feat: backend FastAPI Smart App City — auth JWT, IoT, GIS, notifications, reporting
This commit is contained in:
120
smart-app-city/backend/app/models/models.py
Normal file
120
smart-app-city/backend/app/models/models.py
Normal file
@@ -0,0 +1,120 @@
|
||||
"""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)
|
||||
Reference in New Issue
Block a user