121 lines
4.5 KiB
Python
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)
|