feat(core): add verified Russian C-SSRS Recent source content
CI / ruff · pytest (pull_request) Successful in 31s

This commit is contained in:
Pavel Eliseev
2026-10-03 17:24:48 +03:00
parent da089d67cb
commit 57b5ad1eb2
7 changed files with 242 additions and 21 deletions
+59
View File
@@ -0,0 +1,59 @@
"""Russian Recent source transcription, separate from the legacy sequential scale.
This content does not authorize administering or continuing the questionnaire.
Use questionnaire.score_cssrs_recent for required/missing items and risk, and
evaluate_intake for the clinical policy gate before presenting another question.
Never render interviewer guidance as if it were another patient question.
"""
from pathlib import Path
from typing import Literal
import yaml
from pydantic import BaseModel, ConfigDict, Field, model_validator
from app.config import get_settings
ItemId = Literal["q1", "q2", "q3", "q4", "q5", "q6_lifetime", "q6_recent"]
class SourceModel(BaseModel):
model_config = ConfigDict(extra="forbid", frozen=True)
class CssrsOption(SourceModel):
value: int = Field(strict=True, ge=0, le=1)
label: str
class CssrsItem(SourceModel):
id: ItemId
text: str = Field(min_length=1)
interviewer_guidance: str | None
recall_period: Literal["past_month", "lifetime", "past_3_months"]
yes_risk: Literal["low", "moderate", "high"]
class CssrsRussianForm(SourceModel):
id: Literal["cssrs_recent_ru"]
version: str = Field(min_length=1)
title: str
subtitle: Literal["Screen Version - Recent"]
period_label_original: str
initial_instruction: str
branch_instruction: str
options: tuple[CssrsOption, CssrsOption]
items: tuple[CssrsItem, ...]
@model_validator(mode="after")
def _structure(self) -> "CssrsRussianForm":
if tuple(item.id for item in self.items) != ("q1", "q2", "q3", "q4", "q5", "q6_lifetime", "q6_recent"):
raise ValueError("Recent form requires seven ordered answer fields")
if tuple(option.value for option in self.options) != (1, 0):
raise ValueError("source answer columns are Yes, No")
return self
def load_cssrs_russian(path: Path | None = None) -> CssrsRussianForm:
path = path or get_settings().config_dir / "instruments" / "cssrs_recent_ru.yaml"
return CssrsRussianForm.model_validate(yaml.safe_load(path.read_text(encoding="utf-8")))