Initial commit
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
"""Application configuration (pydantic-settings).
|
||||
|
||||
`Settings` loads from environment variables (prefix ``APP_``) and an optional
|
||||
``.env`` file, falling back to the defaults below for local dev. Keep secrets
|
||||
(JWT_SECRET, HMAC_PEPPER, scraper credentials, ...) in the environment / a
|
||||
secret store, never in source.
|
||||
|
||||
The Swedish parental-leave rule values live in the nested, frozen ``LeaveRules``
|
||||
model. They are domain defaults rather than routine deployment config, but are
|
||||
modelled as settings so they're typed, validated, and overridable should a rule
|
||||
year change (e.g. ``APP_RULES__MAX_SAVABLE_DAYS_AT_AGE_4=96``). NOTE: these are
|
||||
the common-case figures — children born before 2014, multiples, and single
|
||||
custody differ and should become explicit config when tackled.
|
||||
"""
|
||||
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||
|
||||
|
||||
class LeaveRules(BaseModel):
|
||||
"""Frozen Swedish föräldrapenning rule defaults (single source of truth)."""
|
||||
|
||||
model_config = ConfigDict(frozen=True)
|
||||
|
||||
total_days_per_child: int = 480
|
||||
sjukpenning_days: int = 390 # income-based tier
|
||||
lagsta_niva_days: int = 90 # flat low-rate tier
|
||||
|
||||
days_per_parent: int = 240 # default joint-custody split
|
||||
reserved_days_per_parent: int = 90 # non-transferable ("reserverade dagar")
|
||||
|
||||
max_dubbeldagar: int = 60 # both parents, same child-day
|
||||
dubbeldagar_months_limit: int = 15 # only within the child's first 15 months
|
||||
|
||||
max_savable_days_at_age_4: int = 96 # age-4 ceiling
|
||||
hard_expiry_age_years: int = 12
|
||||
|
||||
sgi_protected_first_months: int = 12
|
||||
sgi_min_days_per_week_after_age_1: int = 5
|
||||
|
||||
# Default reserve for preschool planning-day ("studiedagar") closures — the
|
||||
# per-child value is user-editable; this is just the seeded default.
|
||||
preschool_planning_days_per_year: int = 6
|
||||
|
||||
@property
|
||||
def transferable_days_per_parent(self) -> int:
|
||||
return self.days_per_parent - self.reserved_days_per_parent
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
model_config = SettingsConfigDict(
|
||||
env_prefix="APP_",
|
||||
env_nested_delimiter="__",
|
||||
env_file=".env",
|
||||
extra="ignore",
|
||||
)
|
||||
|
||||
# 'sqlite' for local dev, 'postgres' for production (swap repository impls).
|
||||
database_type: str = "sqlite"
|
||||
sqlite_path: str = "./foraldraledig.db"
|
||||
|
||||
# Lock CORS down to the frontend origin(s).
|
||||
cors_origins: list[str] = ["http://localhost:5173"]
|
||||
|
||||
# Auth — change jwt_secret in production (min 32 chars).
|
||||
jwt_secret: str = "dev-secret-change-in-production-min-32-chars"
|
||||
jwt_algorithm: str = "HS256"
|
||||
jwt_access_token_expire_minutes: int = 15
|
||||
jwt_refresh_token_expire_days: int = 7
|
||||
|
||||
# FK scraper — disabled until legal/ToS + BankID review (§2.3).
|
||||
scraper_enabled: bool = False
|
||||
|
||||
rules: LeaveRules = LeaveRules()
|
||||
|
||||
|
||||
settings = Settings()
|
||||
Reference in New Issue
Block a user