Kazeia-central/kazeia_central/features/medical/questionnaires/router.py

83 lines
2.8 KiB
Python

"""Router Questionnaires cliniques (médical) : authoring + assignation + résultats.
Feature **central-only** (store chiffré) : pas d'adb ici. La passation on-device
et sa remontée arriveront via une future spec RPC ; `record_result` sert dès
maintenant de point d'entrée (saisie assistée / import futur).
"""
from __future__ import annotations
from typing import Any
from fastapi import APIRouter
from pydantic import BaseModel
from kazeia_central.core.context import Ctx
from . import service as svc
class _Questionnaire(BaseModel):
title: str
definition: dict[str, Any]
class _Assign(BaseModel):
serial: str
profile_id: str
frequency: dict[str, Any] # {mode: "once"|"recurring", every_days?, count?}
class _Result(BaseModel):
serial: str
profile_id: str
answers: list[int | None] # index du choix retenu par question
def make_router(ctx: Ctx) -> APIRouter:
r = APIRouter(prefix="/api/questionnaires", tags=["questionnaires"])
g, now = ctx.guard, ctx.now_ms
# --- littéraux AVANT /{qid} (FastAPI matche dans l'ordre de déclaration) ---
@r.get("/assignments")
def list_assignments(serial: str | None = None, profile_id: str | None = None):
return g(lambda: svc.assignments(ctx.store, serial=serial, profile_id=profile_id))
@r.post("/assignments/{aid}/deactivate")
def deactivate_assignment(aid: str):
return g(lambda: svc.deactivate(ctx.store, aid, now=now(), actor=ctx.operator))
@r.get("/results/{serial}/{profile_id}")
def patient_results(serial: str, profile_id: str):
return g(lambda: svc.patient_results(ctx.store, serial, profile_id))
# --- catalogue de questionnaires ---
@r.get("")
def list_questionnaires():
return g(lambda: svc.list_questionnaires(ctx.store))
@r.get("/{qid}")
def get_questionnaire(qid: str):
return g(lambda: svc.get_questionnaire(ctx.store, qid))
@r.put("/{qid}")
def save_questionnaire(qid: str, body: _Questionnaire):
return g(lambda: svc.save_questionnaire(ctx.store, qid, body.title, body.definition,
now=now(), actor=ctx.operator))
@r.delete("/{qid}")
def delete_questionnaire(qid: str):
return g(lambda: svc.delete_questionnaire(ctx.store, qid, now=now(), actor=ctx.operator))
# --- assignation + passation ---
@r.post("/{qid}/assign")
def assign(qid: str, body: _Assign):
return g(lambda: svc.assign(ctx.store, qid, body.serial, body.profile_id, body.frequency,
now=now(), actor=ctx.operator))
@r.post("/{qid}/result")
def record_result(qid: str, body: _Result):
return g(lambda: svc.record_result(ctx.store, qid, body.serial, body.profile_id,
body.answers, now=now(), actor=ctx.operator))
return r