devices.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. """
  2. Superadmin endpoints for device management.
  3. """
  4. from typing import Annotated
  5. from fastapi import APIRouter, Depends, HTTPException, Query, status
  6. from sqlalchemy.ext.asyncio import AsyncSession
  7. from app.api.deps import get_current_superadmin
  8. from app.core.database import get_db
  9. from app.models.user import User
  10. from app.schemas.device import (
  11. DeviceCreate,
  12. DeviceListResponse,
  13. DeviceResponse,
  14. DeviceUpdate,
  15. )
  16. from app.services import device_service
  17. router = APIRouter()
  18. @router.get("", response_model=DeviceListResponse)
  19. async def list_devices(
  20. db: Annotated[AsyncSession, Depends(get_db)],
  21. current_user: Annotated[User, Depends(get_current_superadmin)],
  22. skip: int = Query(0, ge=0, description="Number of records to skip"),
  23. limit: int = Query(100, ge=1, le=1000, description="Max records to return"),
  24. organization_id: int | None = Query(
  25. None, description="Filter by organization"
  26. ),
  27. status: str | None = Query(None, description="Filter by status"),
  28. ):
  29. """
  30. List all devices (superadmin only).
  31. Returns paginated list of devices with optional filters.
  32. """
  33. devices, total = await device_service.list_devices(
  34. db,
  35. skip=skip,
  36. limit=limit,
  37. organization_id=organization_id,
  38. status=status,
  39. )
  40. return DeviceListResponse(
  41. devices=devices,
  42. total=total,
  43. )
  44. @router.get("/{device_id}", response_model=DeviceResponse)
  45. async def get_device(
  46. device_id: int,
  47. db: Annotated[AsyncSession, Depends(get_db)],
  48. current_user: Annotated[User, Depends(get_current_superadmin)],
  49. ):
  50. """
  51. Get device by ID (superadmin only).
  52. """
  53. device = await device_service.get_device(db, device_id)
  54. if not device:
  55. raise HTTPException(
  56. status_code=status.HTTP_404_NOT_FOUND,
  57. detail="Device not found",
  58. )
  59. return device
  60. @router.post(
  61. "", response_model=DeviceResponse, status_code=status.HTTP_201_CREATED
  62. )
  63. async def create_device(
  64. data: DeviceCreate,
  65. db: Annotated[AsyncSession, Depends(get_db)],
  66. current_user: Annotated[User, Depends(get_current_superadmin)],
  67. ):
  68. """
  69. Register a new device (superadmin only).
  70. Devices are assigned a unique simple_id (Receiver #1, #2, etc).
  71. """
  72. try:
  73. device = await device_service.create_device(db, data)
  74. except ValueError as e:
  75. raise HTTPException(
  76. status_code=status.HTTP_400_BAD_REQUEST,
  77. detail=str(e),
  78. )
  79. return device
  80. @router.patch("/{device_id}", response_model=DeviceResponse)
  81. async def update_device(
  82. device_id: int,
  83. data: DeviceUpdate,
  84. db: Annotated[AsyncSession, Depends(get_db)],
  85. current_user: Annotated[User, Depends(get_current_superadmin)],
  86. ):
  87. """
  88. Update device (superadmin only).
  89. Can update device organization assignment, status, and configuration.
  90. """
  91. device = await device_service.update_device(db, device_id, data)
  92. if not device:
  93. raise HTTPException(
  94. status_code=status.HTTP_404_NOT_FOUND,
  95. detail="Device not found",
  96. )
  97. return device
  98. @router.delete("/{device_id}", status_code=status.HTTP_204_NO_CONTENT)
  99. async def delete_device(
  100. device_id: int,
  101. db: Annotated[AsyncSession, Depends(get_db)],
  102. current_user: Annotated[User, Depends(get_current_superadmin)],
  103. ):
  104. """
  105. Delete device (superadmin only).
  106. Warning: This permanently deletes the device.
  107. """
  108. deleted = await device_service.delete_device(db, device_id)
  109. if not deleted:
  110. raise HTTPException(
  111. status_code=status.HTTP_404_NOT_FOUND,
  112. detail="Device not found",
  113. )