feat: Initialize frontend and backend structure with essential configurations
Some checks failed
Backend CI / lint-and-test (push) Failing after 2m15s
Frontend CI / lint-and-build (push) Successful in 1m1s

- Added TypeScript build info for frontend.
- Created Vite configuration for React application.
- Implemented pre-commit hook to run checks before commits.
- Set up PostgreSQL Dockerfile with PostGIS support and initialization scripts.
- Added database creation script for PostgreSQL with necessary extensions.
- Established Python project configuration with dependencies and development tools.
- Developed pre-commit script to enforce code quality checks for backend and frontend.
- Created PowerShell script to set up Git hooks path.
This commit is contained in:
2025-10-11 15:25:32 +02:00
commit fc1e874309
74 changed files with 9477 additions and 0 deletions

View File

@@ -0,0 +1,35 @@
from .auth import (
AuthResponse,
LoginRequest,
RegisterRequest,
TokenPayload,
TokenResponse,
UserInDB,
UserPublic,
)
from .base import (
StationCreate,
StationModel,
TrackCreate,
TrackModel,
TrainCreate,
TrainModel,
to_camel,
)
__all__ = [
"LoginRequest",
"RegisterRequest",
"AuthResponse",
"TokenPayload",
"TokenResponse",
"UserInDB",
"UserPublic",
"StationCreate",
"StationModel",
"TrackCreate",
"TrackModel",
"TrainCreate",
"TrainModel",
"to_camel",
]

View File

@@ -0,0 +1,45 @@
from __future__ import annotations
from pydantic import BaseModel, ConfigDict
from backend.app.models.base import to_camel
class LoginRequest(BaseModel):
username: str
password: str
class RegisterRequest(BaseModel):
username: str
password: str
full_name: str | None = None
class TokenResponse(BaseModel):
access_token: str
token_type: str = "bearer"
model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True)
class TokenPayload(BaseModel):
sub: str
exp: int
class UserPublic(BaseModel):
username: str
full_name: str | None = None
model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True)
class UserInDB(UserPublic):
hashed_password: str
class AuthResponse(TokenResponse):
user: UserPublic
model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True)

View File

@@ -0,0 +1,87 @@
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