Files
smart-city-digital-twin-mar…/smart-app-city/backend/app/models/models.py

121 lines
4.5 KiB
Python

"""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)