chore(devops): project skeleton — uv, docker compose, Makefile, CI
CI / ruff · pytest (pull_request) Successful in 1m50s
CI / ruff · pytest (pull_request) Successful in 1m50s
One Postgres with isolated identity/clinical databases and roles (ADR-003), FastAPI /health, Streamlit placeholder, typed settings with offline defaults. Refs #1 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
"""Typed application settings. The only place that reads environment variables."""
|
||||
|
||||
from functools import lru_cache
|
||||
from pathlib import Path
|
||||
from typing import Literal
|
||||
|
||||
from pydantic import Field
|
||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||
|
||||
ROOT_DIR = Path(__file__).resolve().parent.parent
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
# Empty values in .env (e.g. `TG_BOT_TOKEN=`) fall back to defaults instead of failing validation.
|
||||
model_config = SettingsConfigDict(env_file=".env", extra="ignore", env_ignore_empty=True)
|
||||
|
||||
# Two separate databases (ADR-003): identity holds direct identifiers, clinical holds pseudonymised data.
|
||||
identity_db_url: str = "postgresql+asyncpg://identity_app:identity_app@localhost:5432/identity"
|
||||
clinical_db_url: str = "postgresql+asyncpg://clinical_app:clinical_app@localhost:5432/clinical"
|
||||
|
||||
# HMAC key linking identity and clinical records (hex, 32+ bytes).
|
||||
pseudo_key: str = Field(default="dev-only-insecure-key-change-me-0000000000000000", min_length=32)
|
||||
|
||||
# LLM: GigaChat only (152-FZ: no foreign APIs). `mock` is the offline default (ADR-004).
|
||||
llm_provider: Literal["mock", "gigachat"] = "mock"
|
||||
gigachat_credentials: str = ""
|
||||
gigachat_scope: str = "GIGACHAT_API_PERS"
|
||||
gigachat_model: str = "GigaChat"
|
||||
gigachat_verify_ssl: bool = False
|
||||
|
||||
# Telegram is used only for the prototype on synthetic data; prod channel is MAX / Gosuslugi.
|
||||
tg_bot_token: str = ""
|
||||
doctor_notify_chat_id: int | None = None
|
||||
|
||||
# Virtual clock for the demo (ADR-005).
|
||||
demo_clock: bool = True
|
||||
tz: str = "Europe/Moscow"
|
||||
|
||||
api_base_url: str = "http://localhost:8000"
|
||||
config_dir: Path = ROOT_DIR / "config"
|
||||
data_dir: Path = ROOT_DIR / "data"
|
||||
|
||||
|
||||
@lru_cache
|
||||
def get_settings() -> Settings:
|
||||
return Settings()
|
||||
Reference in New Issue
Block a user