feat(questionnaire): integrate revised intake and follow-up monitoring
CI / ruff · pytest (pull_request) Successful in 55s
CI / ruff · pytest (pull_request) Successful in 55s
Add gated TSQ, Russian C-SSRS Recent, durable responses and notifications, diaries, schedules and audited clinical review. Preserve manual assessment when the Russian follow-up source is unavailable. Refs #52
This commit is contained in:
@@ -42,6 +42,20 @@ def menu_reply(ctx: Ctx, text: str | None = None) -> Reply:
|
||||
[Button(label=b.contact_doctor, data="menu:contact_doctor")],
|
||||
[Button(label=b.revoke, data="consent:revoke")],
|
||||
]
|
||||
from app.core.intake_questions import texts
|
||||
from app.core.intake_runtime import intake_enabled
|
||||
|
||||
if intake_enabled():
|
||||
buttons.insert(0, [Button(label=texts()["help"], data="intake:help")])
|
||||
buttons.insert(
|
||||
0,
|
||||
[
|
||||
Button(
|
||||
label=texts()["resume"] if ctx.data.get("questionnaire_record") else texts()["start"],
|
||||
data="intake:resume" if ctx.data.get("questionnaire_record") else "intake:start",
|
||||
)
|
||||
],
|
||||
)
|
||||
return Reply(text=text or ctx.texts.idle.menu_prompt, buttons=buttons)
|
||||
|
||||
|
||||
@@ -53,6 +67,10 @@ async def onboarding_entry(ctx: Ctx, after: str | None = None) -> str:
|
||||
profile (after `after`, if given) that has such a state registered; `"idle"` when none is left."""
|
||||
profile = await ctx.profile()
|
||||
modules = list(profile.modules) if profile is not None and profile.modules else []
|
||||
from app.core.intake_runtime import intake_enabled
|
||||
|
||||
if after is None and intake_enabled() and any(m in modules for m in ("veteran", "depression")):
|
||||
return "intake.start"
|
||||
if after in modules:
|
||||
modules = modules[modules.index(after) + 1 :]
|
||||
for module in modules:
|
||||
@@ -275,6 +293,8 @@ async def _reach_out(ctx: Ctx, event: Event) -> Step:
|
||||
|
||||
def close_crisis(ctx: Ctx) -> Step:
|
||||
"""Doctor acknowledged the crisis: clear the flag; a C-SSRS still running returns to idle afterwards."""
|
||||
if not (ctx.data.get("crisis") or {}).get("open") and ctx.state != "crisis":
|
||||
return Step()
|
||||
crisis = {**(ctx.data.get("crisis") or {}), "open": False, "closed_at": ctx.now.isoformat()}
|
||||
scales = {
|
||||
sid: {**s, "return_state": "idle"} if s.get("return_state") == "crisis" else s
|
||||
@@ -311,7 +331,11 @@ async def revoke(ctx: Ctx) -> Step:
|
||||
"""
|
||||
async with get_identity_session() as s:
|
||||
await identity_repo.revoke_consent(s, token=ctx.token, now=ctx.now)
|
||||
from app.services.questionnaire import cancel_pending
|
||||
|
||||
await cancel_pending(ctx.session, ctx.token)
|
||||
data = {
|
||||
"questionnaire_record": None,
|
||||
"consent": False,
|
||||
"revoked_at": ctx.now.isoformat(),
|
||||
"delete_requested": True,
|
||||
|
||||
Reference in New Issue
Block a user