LiveMedCard / livemedcard /refmodels.py
DocUA's picture
Investor UX: full EN localization, story ribbon, signal grouping, provenance drawer
5f6e063
Raw
History Blame Contribute Delete
2.61 kB
"""Типізовані моделі довідкових даних (замість «сирих» dict).
Дає валідацію при завантаженні, автодоповнення й чіткий контракт для L1/L2a/L2b.
Усі моделі **заморожені** (frozen): loader-и в `reference.py` кешують екземпляри,
тож незмінність — гарантія, що жоден викликач не зіпсує спільний довідник.
"""
from __future__ import annotations
from typing import Optional
from pydantic import BaseModel, ConfigDict
from .dto import Severity
class FrozenModel(BaseModel):
"""База довідкових моделей: незмінні після створення (безпечно кешувати)."""
model_config = ConfigDict(frozen=True)
class Interaction(FrozenModel):
a: str # RxNorm
b: str # RxNorm
severity: Severity
detail: str
detail_en: str = "" # англомовний механізм (для /state?lang=en)
def pair(self) -> frozenset[str]:
return frozenset((self.a, self.b))
class DoseLimit(FrozenModel):
rxnorm: str
name: str
max_daily: float
unit: str
class Bounds(FrozenModel):
low: float
high: float
class RangeSpec(FrozenModel):
"""Референсні межі показника з опціональними варіантами за статтю."""
keyword: str
keyword_en: str = "" # англомовна назва показника (для /state?lang=en)
unit: str
default: Bounds
by_sex: dict[str, Bounds] = {}
def resolve(self, sex: Optional[str]) -> "RefRange":
bounds = self.by_sex.get(sex or "", self.default)
return RefRange(
keyword=self.keyword, keyword_en=self.keyword_en, unit=self.unit,
low=bounds.low, high=bounds.high,
sex=sex if (sex and sex in self.by_sex) else None,
)
class RefRange(FrozenModel):
"""Розвʼязані межі для конкретного пацієнта (стать враховано)."""
keyword: str
keyword_en: str = ""
unit: str
low: float
high: float
sex: Optional[str] = None
class LabTerm(FrozenModel):
loinc: str
unit: str
display: str
class MedTerm(FrozenModel):
rxnorm: str
display: str
class CondTerm(FrozenModel):
snomed: str
display: str
class Vocab(FrozenModel):
labs: dict[str, LabTerm] = {}
medications: dict[str, MedTerm] = {}
conditions: dict[str, CondTerm] = {}