"""Configuration for the inventory backend. DATA_DIR selects which dataset the API serves: - local dev / tests: small real-schema samples (default) or a fixture dir - container image: the full scunpacked dataset downloaded at build time The catalog is read-only. Everything mutable (accounts, sessions, per-user inventories) lives in the database configured by DATABASE_URL. """ import os _APP_DIR = os.path.dirname(os.path.abspath(__file__)) _BACKEND_DIR = os.path.dirname(_APP_DIR) DATA_DIR = os.environ.get("DATA_DIR", os.path.join(_BACKEND_DIR, "data", "samples")) def _env_bool(name: str, default: bool) -> bool: raw = os.environ.get(name) if raw is None: return default return raw.strip().lower() in {"1", "true", "yes", "on"} # --- Persistence ---------------------------------------------------------- DATABASE_URL = os.environ.get( "DATABASE_URL", "postgresql+psycopg://sc_inventory:sc_inventory_dev@db:5432/sc_inventory" ) # Create missing tables on startup. Disabled by the test suite, which builds # its own schema against an in-memory SQLite database. AUTO_INIT_DB = _env_bool("AUTO_INIT_DB", True) # How long startup waits for PostgreSQL to accept connections (container boot). DB_WAIT_SECONDS = int(os.environ.get("DB_WAIT_SECONDS", "60")) # --- Session cookies ------------------------------------------------------ # Enable COOKIE_SECURE once the site is served over TLS. Defaults to false so # plain http://localhost:8080 keeps working out of the box. COOKIE_SECURE = _env_bool("COOKIE_SECURE", False) COOKIE_NAME = os.environ.get("COOKIE_NAME", "sc_session") SESSION_TTL_DAYS = int(os.environ.get("SESSION_TTL_DAYS", "30")) # --- CORS ----------------------------------------------------------------- # Empty by default: the frontend is served same-origin through nginx, so no # cross-origin access is needed. Comma-separated origins opt in explicitly. CORS_ORIGINS = [ origin.strip() for origin in os.environ.get("CORS_ORIGINS", "").split(",") if origin.strip() ] # --- Login hardening ------------------------------------------------------ LOGIN_MAX_ATTEMPTS = int(os.environ.get("LOGIN_MAX_ATTEMPTS", "5")) LOGIN_WINDOW_SECONDS = int(os.environ.get("LOGIN_WINDOW_SECONDS", "900")) # --- Input limits --------------------------------------------------------- MAX_NOTES_LENGTH = 1000 MAX_QUANTITY = 1_000_000