Files
the-other-dude/backend/app/schemas/sector.py
Jason Staack ea5afe3408 feat(14-01): add sector CRUD backend with migration, model, service, and router
- Create sectors table migration (034) with RLS and devices.sector_id FK
- Add Sector ORM model with site_id and tenant_id foreign keys
- Add SectorCreate/Update/Response/ListResponse Pydantic schemas
- Implement sector_service with CRUD and device assignment functions
- Add sectors router with GET/POST/PUT/DELETE and device sector assignment
- Register sectors router in main.py
- Add sector_id and sector_name to Device model and DeviceResponse

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 06:40:44 -05:00

64 lines
1.5 KiB
Python

"""Pydantic schemas for Sector endpoints."""
import uuid
from datetime import datetime
from typing import Optional
from pydantic import BaseModel, ConfigDict, field_validator
class SectorCreate(BaseModel):
"""Schema for creating a new sector."""
name: str
azimuth: Optional[float] = None
description: Optional[str] = None
@field_validator("name")
@classmethod
def validate_name(cls, v: str) -> str:
v = v.strip()
if len(v) < 1 or len(v) > 255:
raise ValueError("Sector name must be 1-255 characters")
return v
class SectorUpdate(BaseModel):
"""Schema for updating an existing sector. All fields optional."""
name: Optional[str] = None
azimuth: Optional[float] = None
description: Optional[str] = None
@field_validator("name")
@classmethod
def validate_name(cls, v: Optional[str]) -> Optional[str]:
if v is None:
return v
v = v.strip()
if len(v) < 1 or len(v) > 255:
raise ValueError("Sector name must be 1-255 characters")
return v
class SectorResponse(BaseModel):
"""Sector response schema with device count."""
id: uuid.UUID
site_id: uuid.UUID
name: str
azimuth: Optional[float] = None
description: Optional[str] = None
device_count: int = 0
created_at: datetime
updated_at: datetime
model_config = ConfigDict(from_attributes=True)
class SectorListResponse(BaseModel):
"""List of sectors with total count."""
items: list[SectorResponse]
total: int