from datetime import timezone, timedelta from pathlib import Path from typing import Literal from pydantic import Field from pydantic_settings import BaseSettings # Beijing time (UTC+8) BEIJING_TZ = timezone(timedelta(hours=8)) # Project root directory (where config.py lives → parent = app/ → parent = project root) _PROJECT_ROOT = Path(__file__).resolve().parent.parent _DEFAULT_DB_PATH = _PROJECT_ROOT / "badge_admin.db" class Settings(BaseSettings): APP_NAME: str = "KKS Badge Management System" DATABASE_URL: str = Field( default=f"sqlite+aiosqlite:///{_DEFAULT_DB_PATH}", description="Database connection URL (absolute path for SQLite)", ) TCP_HOST: str = "0.0.0.0" TCP_PORT: int = Field(default=5000, ge=1, le=65535) API_HOST: str = "0.0.0.0" API_PORT: int = Field(default=8088, ge=1, le=65535) DEBUG: bool = Field(default=False, description="Enable debug mode (SQL echo, verbose errors)") # API authentication API_KEY: str | None = Field(default=None, description="API key for authentication (None=disabled)") CORS_ORIGINS: str = Field(default="*", description="Comma-separated allowed CORS origins") # Rate limiting RATE_LIMIT_DEFAULT: str = Field(default="60/minute", description="Default rate limit") RATE_LIMIT_WRITE: str = Field(default="30/minute", description="Rate limit for write operations") # 高德地图 API (geocoding) AMAP_KEY: str | None = Field(default=None, description="高德地图 Web API key") AMAP_SECRET: str | None = Field(default=None, description="高德地图安全密钥") # Geocoding GEOCODING_DEFAULT_IMEI: str = Field(default="868120334031363", description="Default IMEI for AMAP geocoding API") GEOCODING_CACHE_SIZE: int = Field(default=10000, description="Max geocoding cache entries") # Track query limit TRACK_MAX_POINTS: int = Field(default=10000, description="Maximum points returned by track endpoint") # Data retention DATA_RETENTION_DAYS: int = Field(default=90, description="Days to keep location/heartbeat/alarm/attendance/bluetooth records") DATA_CLEANUP_INTERVAL_HOURS: int = Field(default=24, description="Hours between automatic cleanup runs") model_config = {"env_file": ".env", "env_file_encoding": "utf-8", "extra": "ignore"} settings = Settings()