55 lines
1.5 KiB
Python
55 lines
1.5 KiB
Python
from functools import lru_cache
|
|
from pathlib import Path
|
|
|
|
from pydantic import Field
|
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
|
|
BASE_DIR = Path(__file__).resolve().parent.parent
|
|
|
|
|
|
class Settings(BaseSettings):
|
|
# Core
|
|
data_dir: Path = Field(default=BASE_DIR / "data")
|
|
db_path: Path | None = None # defaults to <data_dir>/bike_admin.db when None
|
|
secret_key: str = Field(default="change-me", min_length=8) # CSRF/session HMAC
|
|
username: str = Field(default="admin", min_length=1)
|
|
password: str | None = None # REQUIRED on first run (see ensure_user)
|
|
|
|
# Hosting posture
|
|
is_production: bool = False # True => Secure cookies + stricter headers
|
|
bind_host: str = "127.0.0.1"
|
|
bind_port: int = 8000
|
|
trust_proxy: bool = True # honor X-Forwarded-For/Proto behind a reverse proxy
|
|
|
|
# Sessions
|
|
session_ttl_seconds: int = 7 * 24 * 3600
|
|
|
|
# Login throttling
|
|
login_max_attempts: int = 8
|
|
login_window_seconds: int = 300
|
|
|
|
# Service hint: flag a bike as "book soon" when it is this close to due.
|
|
service_due_soon_miles: int = 200
|
|
|
|
# Event types (preset)
|
|
event_types: list[str] = [
|
|
"service",
|
|
"fuel",
|
|
"tyre",
|
|
"chain",
|
|
"brake",
|
|
"repair",
|
|
"other",
|
|
]
|
|
|
|
model_config = SettingsConfigDict(env_prefix="BIKE_ADMIN_", env_file=".env", extra="ignore")
|
|
|
|
@property
|
|
def resolved_db_path(self) -> Path:
|
|
return self.db_path or (self.data_dir / "bike_admin.db")
|
|
|
|
|
|
@lru_cache
|
|
def get_settings() -> Settings:
|
|
return Settings()
|