"""SQLModels for Smart City Digital Twin — Martinique.""" import uuid from datetime import datetime from typing import Optional from uuid import UUID from sqlmodel import Field, Relationship, SQLModel class User(SQLModel, table=True): id: UUID = Field(default_factory=uuid.uuid4, primary_key=True) email: str = Field(unique=True, index=True) username: str = Field(unique=True, index=True) hashed_password: str first_name: str last_name: str phone: Optional[str] = Field(default=None) role: str = Field(default="user") avatar_url: Optional[str] = Field(default=None) is_active: bool = Field(default=True) created_at: datetime = Field(default_factory=datetime.utcnow) updated_at: datetime = Field(default_factory=datetime.utcnow) alerts: list["Alert"] = Relationship(back_populates="owner") notification_devices: list["NotificationDevice"] = Relationship( back_populates="user" ) class Zone(SQLModel, table=True): id: UUID = Field(default_factory=uuid.uuid4, primary_key=True) name: str = Field(index=True) description: Optional[str] = Field(default=None) color: str = Field(default="#3949AB") geojson: Optional[str] = Field(default=None) created_at: datetime = Field(default_factory=datetime.utcnow) sensors: list["Sensor"] = Relationship(back_populates="zone") class Sensor(SQLModel, table=True): id: UUID = Field(default_factory=uuid.uuid4, primary_key=True) name: str = Field(index=True) type: str status: str = Field(default="active") latitude: float longitude: float zone_id: Optional[UUID] = Field(default=None, foreign_key="zone.id") last_value: Optional[float] = Field(default=None) last_reading_at: Optional[datetime] = Field(default=None) battery_level: Optional[int] = Field(default=None) created_at: datetime = Field(default_factory=datetime.utcnow) zone: Optional[Zone] = Relationship(back_populates="sensors") readings: list["SensorReading"] = Relationship(back_populates="sensor") alerts: list["Alert"] = Relationship(back_populates="sensor") class SensorReading(SQLModel, table=True): id: UUID = Field(default_factory=uuid.uuid4, primary_key=True) sensor_id: UUID = Field(foreign_key="sensor.id") value: float unit: str quality: float = Field(default=1.0) recorded_at: datetime created_at: datetime = Field(default_factory=datetime.utcnow) sensor: Sensor = Relationship(back_populates="readings") class Alert(SQLModel, table=True): id: UUID = Field(default_factory=uuid.uuid4, primary_key=True) sensor_id: UUID = Field(foreign_key="sensor.id") type: str severity: str = Field(default="medium") message: str value: Optional[float] = Field(default=None) threshold: Optional[float] = Field(default=None) status: str = Field(default="active") created_at: datetime = Field(default_factory=datetime.utcnow) resolved_at: Optional[datetime] = Field(default=None) sensor: Sensor = Relationship(back_populates="alerts") class NotificationDevice(SQLModel, table=True): id: UUID = Field(default_factory=uuid.uuid4, primary_key=True) user_id: UUID = Field(foreign_key="user.id") platform: str push_token: str = Field(unique=True) is_active: bool = Field(default=True) created_at: datetime = Field(default_factory=datetime.utcnow) user: User = Relationship(back_populates="notification_devices") class Notification(SQLModel, table=True): id: UUID = Field(default_factory=uuid.uuid4, primary_key=True) user_id: UUID = Field(foreign_key="user.id") title: str body: str category: str = Field(default="general") # general, alert, maintenance, event is_read: bool = Field(default=False) data: Optional[str] = Field(default=None) # JSON payload as string created_at: datetime = Field(default_factory=datetime.utcnow) read_at: Optional[datetime] = Field(default=None) class NotificationPreference(SQLModel, table=True): id: UUID = Field(default_factory=uuid.uuid4, primary_key=True) user_id: UUID = Field(foreign_key="user.id", unique=True) push_enabled: bool = Field(default=True) email_enabled: bool = Field(default=False) alert_notifications: bool = Field(default=True) maintenance_notifications: bool = Field(default=True) event_notifications: bool = Field(default=True) general_notifications: bool = Field(default=True) created_at: datetime = Field(default_factory=datetime.utcnow) updated_at: datetime = Field(default_factory=datetime.utcnow)