Files
rail-game/backend/app/models/base.py

107 lines
2.3 KiB
Python

from __future__ import annotations
from datetime import datetime
from typing import Generic, Sequence, TypeVar
from pydantic import BaseModel, ConfigDict
def to_camel(string: str) -> str:
head, *tail = string.split("_")
return head + "".join(part.capitalize() for part in tail)
IdT = TypeVar("IdT", bound=str)
class CamelModel(BaseModel):
model_config = ConfigDict(
from_attributes=True,
populate_by_name=True,
alias_generator=to_camel,
)
class TimestampedModel(CamelModel):
created_at: datetime
updated_at: datetime
model_config = ConfigDict(
frozen=True,
from_attributes=True,
populate_by_name=True,
alias_generator=to_camel,
)
class IdentifiedModel(TimestampedModel, Generic[IdT]):
id: IdT
class StationModel(IdentifiedModel[str]):
name: str
latitude: float
longitude: float
class TrackModel(IdentifiedModel[str]):
start_station_id: str
end_station_id: str
length_meters: float
max_speed_kph: float
class TrainModel(IdentifiedModel[str]):
designation: str
capacity: int
max_speed_kph: float
operating_track_ids: list[str]
class StationCreate(CamelModel):
name: str
latitude: float
longitude: float
osm_id: str | None = None
code: str | None = None
elevation_m: float | None = None
is_active: bool = True
class TrackCreate(CamelModel):
start_station_id: str
end_station_id: str
coordinates: Sequence[tuple[float, float]]
name: str | None = None
length_meters: float | None = None
max_speed_kph: int | None = None
is_bidirectional: bool = True
status: str = "planned"
class TrainCreate(CamelModel):
designation: str
capacity: int
max_speed_kph: int
operator_id: str | None = None
home_station_id: str | None = None
consist: str | None = None
class TrainScheduleCreate(CamelModel):
train_id: str
station_id: str
sequence_index: int
scheduled_arrival: datetime | None = None
scheduled_departure: datetime | None = None
dwell_seconds: int | None = None
class UserCreate(CamelModel):
username: str
password_hash: str
email: str | None = None
full_name: str | None = None
role: str = "player"
preferences: str | None = None