feat(web): приложение пациента — двухэтапные опросы, результат скрининга, дневник по результату #79

Merged
Arxip222 merged 10 commits from feat/rag-clinical-guidelines into dev 2026-10-04 15:25:17 +03:00
Owner

Что меняется

Веб-приложение пациента (web/) и движок опросов по документам «Опросники для MVP» (этап 1) и «Этап 2». Этап 1 общий для всех в порядке документа → предварительный результат пациенту (не диагноз) → модули дневника → утренний/вечерний дневник, плановые шкалы и журнал всех опросов. Решение — ADR-012.

Closes #77

Зона

A (web) + B (patient_web API, questionnaire flow) + clinical config. Контракты #34 не менялись.

Слияние с dev: /demo/personas оставлен в версии dev (демо-консоль); приложению пациента отдельный /patient/demo-personas. Анонимный вход теперь всегда создаёт псевдонимный профиль без врача (диалоговый API из #12 обслуживает только известные профили).

Отдельно: .gitattributes с *.sh eol=lf — на Windows infra/postgres/init.sh уходил в CRLF, Postgres не создавал базы и API отвечал 500.

Как проверить

  1. .env: INTAKE_DEMO=true; docker compose up -d --build; cd web && npm run dev.
  2. Анонимный вход → «ПТСР» → согласие → первичный опрос (без названий шкал) → экран результата.
  3. Главная → «Дневник — утро» / «Дневник — вечер»; Профиль → «Мои результаты».
  4. make lint && make test.

Чек-лист

  • слито с origin/dev
  • ruff + pytest зелёные (959 passed)
  • лог в issue (### 2026-10-04)
  • нет ПДн в логах, нет реальных данных, нет секретов
  • общие файлы: .gitattributes новый, CLAUDE.md/docker-compose/pyproject не тронуты

🤖 Generated with Claude Code

## Что меняется Веб-приложение пациента (`web/`) и движок опросов по документам «Опросники для MVP» (этап 1) и «Этап 2». Этап 1 общий для всех в порядке документа → предварительный результат пациенту (не диагноз) → модули дневника → утренний/вечерний дневник, плановые шкалы и журнал всех опросов. Решение — ADR-012. Closes #77 ## Зона A (web) + B (patient_web API, questionnaire flow) + clinical config. Контракты #34 не менялись. Слияние с dev: `/demo/personas` оставлен в версии dev (демо-консоль); приложению пациента отдельный `/patient/demo-personas`. Анонимный вход теперь всегда создаёт псевдонимный профиль без врача (диалоговый API из #12 обслуживает только известные профили). Отдельно: `.gitattributes` с `*.sh eol=lf` — на Windows `infra/postgres/init.sh` уходил в CRLF, Postgres не создавал базы и API отвечал 500. ## Как проверить 1. `.env`: `INTAKE_DEMO=true`; `docker compose up -d --build`; `cd web && npm run dev`. 2. Анонимный вход → «ПТСР» → согласие → первичный опрос (без названий шкал) → экран результата. 3. Главная → «Дневник — утро» / «Дневник — вечер»; Профиль → «Мои результаты». 4. `make lint && make test`. ## Чек-лист - [x] слито с origin/dev - [x] ruff + pytest зелёные (959 passed) - [x] лог в issue (### 2026-10-04) - [x] нет ПДн в логах, нет реальных данных, нет секретов - [ ] общие файлы: `.gitattributes` новый, CLAUDE.md/docker-compose/pyproject не тронуты 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Arxip222 added 10 commits 2026-10-04 15:22:45 +03:00
Structure-aware units with audience/evidence metadata, manual review,
hybrid BM25 search, citation-checked answers and an eval set.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A second channel to the same dialog engine as the Telegram bot: consent,
onboarding, scales and check-ins come from app/dialog; the bot is unchanged.

- API: /auth/emias (doctor's one-time connect code via EmiasMock),
  /auth/emias/demo (synthetic personas), /auth/anonymous (random token,
  nothing stored in the identity DB), /crisis/resources from crisis.yaml
- web/: React + TS + Vite, mobile-first, safe areas, hash routing,
  tokens and texts isolated for a Capacitor mobile build

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- /flow renders the dialog engine's current step as a mock screen (consent,
  age, onboarding and scales with progress, mood 0–10, free text, dose
  reminder, crisis with hotlines and breathing, safety plan), so every
  engine scenario gets the design without duplicating its logic
- today / meds / doctor / profile / messages tabs; navy sidebar and
  emergency rail on desktop, emergency block and tab bar on phones
- API: GET /me/{token}/today (today's doses, week marks, next visit, demo
  clock time); demo ЕМИАС sign-in seeds the persona's synthetic profile and
  prescription from the dashboard fixtures

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- focus screens: question and context on the left, answers on the right in
  one wide card; consent text and the 0–10 scale in one wide column
- today: dashboard with tasks, this week's doses and quick actions side by
  side; meds / doctor / profile in two-column grids; welcome gets «Как это
  работает» steps
- fix: 0–10 scale no longer overflows narrow containers

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Focus screen renders versioned questionnaire items (iq: buttons): section chip, position
  (adaptive forms without "of N"), recall date, pause / help-now actions, optional skip,
  sleep-hours input, 0-10 scale anchors, RUS-AUDIT item 2 standard-drink table.
- Paused / held-for-review questionnaires get their own screen.
- Today: intake and diary tasks, review notice, therapy-day card on days 1/7/14.
- Drug card /meds/:ref from data/meds/meds_reference.json (draft built from the Minzdrav
  guidelines: depression 2024, PTSD 2023) — expected effect, course, side effects, red flags;
  no doses shown. "Report a side effect" always available (med:side_effects:<ref>).
- API: /instruments/catalog, /meds/reference; today gains questionnaire state, reference id,
  indication and therapy day; demo persona seeds the dashboard dose history.
- INTAKE_DEMO=1 (demo clock only) opens the questionnaires on synthetic data without touching
  the clinical release gate in config/intake_runtime.yaml.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On Windows git converted infra/postgres/init.sh to CRLF; Postgres then failed to run it
(/bin/bash^M: bad interpreter), so the identity/clinical databases and roles were never
created and every API call returned 500.

Refs #77

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Sign-in: centred ЕМИАС card without the sidebar; anonymous entry asks «Депрессия / ПТСР».
- Stage 1 is the same for everyone and follows the fixed order of the MVP questionnaire:
  PHQ-2 → trauma filter/TSQ → RUS-AUDIT-S → C-SSRS → context; stage 2 only where stage 1
  is positive. Starts without a profile.
- After stage 1 the patient sees a preliminary result (screening, not a diagnosis), stored
  with the record; it switches on the diary modules (depression / PTSD).
- Stage 2 diary: morning (sleep, sleep quality, alcohol) and evening (mood, medication,
  3 PHQ-9 items in rotation, short PCL-5); C-SSRS since last contact only under risk;
  flags on weekly means against the personal norm; scheduled full scales with change
  (remission, response, worsening).
- Questionnaire log: GET /me/{token}/results and the «Мои результаты» screen.
- Questionnaires centred without the sidebar and without scale names; «Продолжить позже»
  goes home; confirmations are toasts; free-text comments are optional.
- Demo policy config/questionnaire_demo.yaml (INTAKE_DEMO only, not a clinical approval).

ADR-012.

Refs #77

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merge origin/dev into feat/rag-clinical-guidelines
CI / ruff · pytest (pull_request) Successful in 2m9s
0106aefc33
Conflict in app/api/routes.py: /demo/personas keeps the dev version (demo console, DB patients
with scenarios); the patient app gets its own /patient/demo-personas (synthetic ЕМИАС accounts).
Anonymous sign-in now always creates a doctor-less pseudonymous profile, since the dialog API
of #12 serves known profiles only.

Refs #77

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Arxip222 merged commit b94291e541 into dev 2026-10-04 15:25:17 +03:00
Sign in to join this conversation.