143 Commits
Author SHA1 Message Date
Eleboba 47e0af78fc Merge pull request 'release: dev → main (финальная сдача)' (#114) from dev into main
CI / ruff · pytest (push) Successful in 2m35s
2026-10-05 13:43:37 +03:00
Eleboba 4b166cf488 Merge pull request 'chore(devops): веб-приложение пациента в docker compose' (#113) from chore/web-in-compose into dev
CI / ruff · pytest (push) Successful in 2m40s
CD / ruff · pytest (push) Successful in 2m42s
CI / ruff · pytest (pull_request) Successful in 2m35s
CD / deploy dev (push) Successful in 31s
2026-10-05 13:43:19 +03:00
ElebobaandClaude Opus 5.5 1eb0f47823 chore(devops): patient web app in docker compose — the jury needs only Docker
CI / ruff · pytest (pull_request) Successful in 2m34s
Requirement: no extra software beyond the regulated set. The web app is built in a Node stage and served by
nginx (:8080, /api → app, SSE unbuffered); the server override keeps it off (host nginx serves the bundle).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 13:40:24 +03:00
Eleboba 499cf6cdfc Merge pull request 'docs: README для жюри' (#112) from docs/readme-submission into dev
CD / ruff · pytest (push) Successful in 2m35s
CI / ruff · pytest (push) Successful in 2m43s
CD / deploy dev (push) Successful in 55s
2026-10-05 13:33:16 +03:00
ElebobaandClaude Opus 5.5 65ae3506f7 docs: README for the jury — goals, what is built, run, API, medical limitations
CI / ruff · pytest (pull_request) Successful in 2m32s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 13:30:37 +03:00
Eleboba b945c839b8 Merge pull request 'feat: живой ответ агента (стриминг) + вкладка «Чат» на телефоне' (#111) from feat/chat-streaming into dev
CI / ruff · pytest (push) Successful in 2m53s
CD / ruff · pytest (push) Successful in 2m55s
CD / deploy dev (push) Successful in 1m19s
2026-10-05 12:55:14 +03:00
ElebobaandClaude Opus 5.5 d1f92407f9 feat: live agent answers (SSE streaming) + «Чат» tab on phones
CI / ruff · pytest (pull_request) Successful in 2m43s
- POST /dialog/{token}/events/stream: Server-Sent Events with the agent's steps («Смотрю вашу карту ЕМИАС…»,
  «Ищу в клинических рекомендациях…»), the answer as the model writes it (OpenRouter stream=true), then the
  final replies (same as /events, incl. the forbidden-output filter and sources). X-Accel-Buffering: no.
- Web: free-text messages use the stream — a live bubble with steps, typing dots and a cursor; falls back to
  the plain request if the stream breaks.
- Phones: the bottom tab bar gets «Чат» (it had no way back to the chat).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 12:52:19 +03:00
Eleboba d662a69c7e Merge pull request 'feat(bot): /start без кода на демо-стенде — личная копия Андрея' (#110) from fix/tg-demo-start into dev
CD / ruff · pytest (push) Failing after 7s
CD / deploy dev (push) Skipped
CI / ruff · pytest (push) Successful in 2m43s
2026-10-05 12:33:50 +03:00
ElebobaandClaude Opus 5.5 bfb0c9e7bb feat(bot): /start without a code on the demo stand opens a private copy of veteran Andrey
CI / ruff · pytest (pull_request) Successful in 2m45s
Refs #108

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 12:28:03 +03:00
Eleboba fa23e1f3c6 Merge pull request 'fix(bot): Telegram через прокси на сервере' (#109) from fix/tg-proxy into dev
CD / ruff · pytest (push) Successful in 3m25s
CI / ruff · pytest (push) Successful in 3m29s
CD / deploy dev (push) Successful in 2m42s
2026-10-05 12:23:03 +03:00
ElebobaandClaude Opus 5.5 9087e2ac8d fix(bot): Telegram through TG_PROXY_URL — docker on the RF server has no IPv4 route to Telegram
CI / ruff · pytest (pull_request) Successful in 2m28s
Closes #108

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 23:40:53 +03:00
Eleboba cb680ff5b1 Merge pull request 'feat: кризис в конце теста и без блокировки, оружие без триггера, Никита' (#107) from feat/crisis-deferred into dev
CD / ruff · pytest (push) Successful in 2m39s
CI / ruff · pytest (push) Successful in 3m0s
CD / deploy dev (push) Successful in 1m50s
2026-10-04 23:33:01 +03:00
ElebobaandClaude Opus 5.5 531bef1e73 feat: crisis message after the test and non-blocking; weapon answer triggers nothing; ЕМИАС demo = Никита
CI / ruff · pytest (pull_request) Successful in 2m33s
- CRISIS_BLOCKING (default off for the demo): a crisis no longer locks the dialog; the message and the
  doctor's acute alert still happen. The clinical protocol (blocking, immediate stop) stays behind the flag and
  keeps its tests.
- Crisis signals inside a questionnaire (intake red flags, high C-SSRS, PHQ-9 item 9) no longer stop it: the
  test is finished and the crisis message comes at the end; the doctor's alert is raised at once/at the end.
- Weapon access: asked and stored, triggers nothing (rule disabled, no red flag, no safety block).
- ЕМИАС demo persona is «Никита В.»; the one-click demo stays «Андрей С.».

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 23:30:05 +03:00
Eleboba b58d91fdce Merge pull request 'release: dev → main (сдача хакатона)' (#106) from dev into main
CI / ruff · pytest (push) Successful in 2m43s
2026-10-04 23:00:55 +03:00
Eleboba 967ae2d5b6 Merge pull request 'fix(bot): полировка чат-агента' (#105) from fix/agent-polish into dev
CI / ruff · pytest (push) Successful in 2m45s
CD / ruff · pytest (push) Successful in 2m51s
CI / ruff · pytest (pull_request) Successful in 2m41s
CD / deploy dev (push) Successful in 3m27s
2026-10-04 22:46:14 +03:00
ElebobaandClaude Opus 5.5 e72378f178 fix(bot): agent polish — instant small talk, capped tool calls, analogues, plain text, definitions allowed
CI / ruff · pytest (pull_request) Successful in 2m43s
- Greetings / chit-chat answered without the LLM (instant, free, no medical findings dumped into «привет»).
- At most 4 tool calls per turn (one «как дела?» turn fired 23 parallel searches).
- «My drug» is never asked back; analogues → the drug's group, replacement only by the doctor.
- Markdown stripped to plain text with «•»; no sources footer under short replies.
- Diagnosis filter no longer blocks definitions («ПТСР — это расстройство…»); diagnosis-like statements about
  the patient are still blocked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 22:43:18 +03:00
Eleboba f0be84d020 Merge pull request 'feat(bot): агент отвечает на любое сообщение + личная копия на любой демо-вход' (#104) from feat/chat-all-text into dev
CD / deploy dev (push) Successful in 3m30s
CD / ruff · pytest (push) Successful in 2m46s
CI / ruff · pytest (push) Successful in 2m57s
2026-10-04 22:30:25 +03:00
ElebobaandClaude Opus 5.5 31585c7f35 feat(bot): every free-text message gets the agent's answer; every demo entry is a private copy
CI / ruff · pytest (pull_request) Successful in 2m41s
- Idle chat: all messages go to the agent (greetings, side-effect and substitute questions included); check-in
  signals are still recorded silently, quit intent keeps its rule reaction. Seen live: «какие будут побочки»
  was logged as a complaint («Спасибо, отметил»), «привет» got a canned phrase.
- Agent prompt: warm short replies to small talk; substitutes → only the doctor changes the drug.
- ЕМИАС demo persona button creates a private copy too (starting from consent + questionnaires, subject to
  the screening switch); the web app drops a stored session of the old shared demo account.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 22:27:26 +03:00
Eleboba 535838e941 Merge pull request 'fix(bot): вопросы о составе без «?»' (#103) from fix/question-words into dev
CD / ruff · pytest (push) Successful in 3m12s
CI / ruff · pytest (push) Successful in 3m45s
CD / deploy dev (push) Successful in 2m32s
2026-10-04 21:44:37 +03:00
ElebobaandClaude Opus 5.5 4b64086ad7 fix(bot): composition questions without «?» are questions
CI / ruff · pytest (pull_request) Successful in 2m44s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 21:41:43 +03:00
Eleboba 0e4dd0d5a2 Merge pull request 'feat: демо-режим для презентации — вход в один клик, тумблер начального теста' (#102) from feat/demo-mode into dev
CI / ruff · pytest (push) Successful in 4m20s
CD / ruff · pytest (push) Successful in 4m34s
CD / deploy dev (push) Successful in 3m20s
2026-10-04 21:13:38 +03:00
ElebobaandClaude Opus 5.5 c8887dc4b3 test: demo_settings is a clinical table
CI / ruff · pytest (pull_request) Successful in 2m52s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 21:07:41 +03:00
ElebobaandClaude Opus 5.5 cdd5ad9cde feat: presentation demo mode — one-click private demo patient, screening on/off switch
CI / ruff · pytest (pull_request) Failing after 2m33s
- POST /auth/demo/fresh + «Демо: войти как Андрей» on the welcome screen: every sign-in gets a fresh private
  copy of veteran Andrey (consent, prescription, ЕМИАС record) and lands in the chat — no codes, nobody's
  crisis or half-done questionnaire leaks into another viewer.
- Initial screening switch: SCREENING_ENABLED env default + /demo/settings + a toggle in the demo console;
  off → after consent straight to the chat.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 21:01:05 +03:00
Eleboba 99e7b8e55d Merge pull request 'fix: чат отвечает в любой ситуации — без ложного повторного кризиса' (#101) from fix/crisis-refire into dev
CD / deploy dev (push) Successful in 2m42s
CI / ruff · pytest (push) Successful in 3m0s
CD / ruff · pytest (push) Successful in 3m1s
2026-10-04 18:28:41 +03:00
ElebobaandClaude Opus 5.5 dd67905626 fix: chat replies in any situation — no false crisis re-fire, answers in crisis, medicine questions anywhere
CI / ruff · pytest (pull_request) Successful in 2m22s
- An acked crisis is not raised again for the same signal: re-raised only if a newer triggering scale exists
  (seen live: AUDIT-C 0/0/0 re-fired the acked PHQ-9 item 9 crisis).
- In an open crisis every non-acute message gets a reply (agent for questions, support otherwise) plus
  emergency contacts; acute messages still get the fixed script.
- Questions and medicine mentions without «?» are answered mid-questionnaire; free-text steps (check-in,
  side effects, question states) keep parsing their input.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 18:23:03 +03:00
Eleboba a026a8cd48 Merge pull request 'fix: карта ЕМИАС для веб-демо Андрея + REVISION после успешного деплоя' (#100) from fix/emias-demo-token into dev
CD / ruff · pytest (push) Successful in 2m25s
CI / ruff · pytest (push) Successful in 2m38s
CD / deploy dev (push) Successful in 1m50s
2026-10-04 17:55:28 +03:00
ElebobaandClaude Opus 5.5 0bbe1e0932 fix: web demo token tok-andrey shares Andrey's ЕМИАС record; REVISION written only after a healthy deploy
CI / ruff · pytest (pull_request) Successful in 2m44s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 17:52:23 +03:00
Eleboba 475800436e Merge pull request 'feat(bot): чат отвечает в любом состоянии + OpenRouter через прокси' (#99) from feat/chat-anywhere into dev
CD / ruff · pytest (push) Successful in 2m47s
CI / ruff · pytest (push) Successful in 2m49s
CD / deploy dev (push) Successful in 1m58s
2026-10-04 17:46:38 +03:00
ElebobaandClaude Opus 5.5 c489ddbdc4 feat(bot): chat answers questions in any state; OpenRouter via proxy from the RF server
CI / ruff · pytest (pull_request) Successful in 2m53s
A question asked mid-questionnaire, mid-check-in or during a crisis is answered right away (agent →
guidelines/instruction); the pending question is re-shown with its buttons (engine remembers the last
prompt), in a crisis the answer carries the emergency contacts and the crisis stays open until the doctor's
ack. Acute messages still get the fixed crisis script. OpenRouter blocks RF IPs: OPENROUTER_PROXY_URL routes
the agent through an HTTP proxy, as vobot does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 17:42:03 +03:00
Eleboba 683a74b004 Merge pull request 'chore(devops): CD — автодеплой dev на сервер' (#98) from chore/cd-deploy into dev
CD / ruff · pytest (push) Successful in 2m21s
CI / ruff · pytest (push) Successful in 2m30s
CD / deploy dev (push) Successful in 1m27s
2026-10-04 16:56:12 +03:00
ElebobaandClaude Opus 5.5 285c95ac6b chore(devops): CD — every merge into dev deploys dev.meditron.tenvex.ru
CI / ruff · pytest (pull_request) Successful in 2m24s
Gitea Actions: lint + tests, then infra/deploy/deploy.sh over ssh as the dedicated ptsr-deploy user
(secrets DEPLOY_SSH_KEY, DEPLOY_HOST), then an HTTPS smoke check. deploy.sh now ships a tar.gz via scp and
retries every remote step (the host drops some ssh connections); the web build runs as the deploy user so the
next release can clean up.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 16:53:35 +03:00
Eleboba 24e8ba4e72 Merge pull request 'fix: анонимная помощь с первичным опросом и доступом к врачу' (#97) from feat/95-anonymous-care into dev
CI / ruff · pytest (push) Successful in 2m34s
Reviewed-on: #97
2026-10-04 16:51:23 +03:00
Pavel Eliseev f5987c72f0 fix(web): offer anonymous screening and doctor contact without identity
CI / ruff · pytest (pull_request) Successful in 2m30s
Refs #95, #96
2026-10-04 16:48:03 +03:00
Pavel Eliseev 0743184f3d fix(api): provide pseudonymous patients access to doctor care 2026-10-04 16:47:06 +03:00
Arxip222 079c3003aa Merge pull request 'fix(clinical): красные флаги, одно правило кризиса, звонок после кризиса, одна таблица номеров' (#94) from fix/clinical-review-safety into dev
CI / ruff · pytest (push) Successful in 2m26s
2026-10-04 16:28:28 +03:00
Eleboba dff8f316bb Merge pull request 'chore(devops): HTTPS для meditron.tenvex.ru' (#93) from chore/nginx-https-prod into dev
CI / ruff · pytest (push) Successful in 2m14s
2026-10-04 16:25:26 +03:00
ElebobaandClaude Opus 5.5 f14efac7ac chore(devops): HTTPS for meditron.tenvex.ru too
CI / ruff · pytest (pull_request) Successful in 2m20s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 16:22:49 +03:00
Eleboba 766c2a2e4b Merge pull request 'chore(devops): HTTPS для dev.meditron.tenvex.ru' (#91) from chore/nginx-https into dev
CI / ruff · pytest (push) Successful in 2m16s
2026-10-04 16:21:49 +03:00
Arxip222 37b612b8c4 Merge remote-tracking branch 'origin/dev' into fix/clinical-review-safety
CI / ruff · pytest (pull_request) Successful in 2m22s
2026-10-04 16:21:24 +03:00
Arxip222andClaude Opus 5.5 44814b7293 fix(clinical): red flags, one crisis rule, callback after a crisis, one table of numbers
Clinical review of the questionnaires (ADR-013):
- Red-flag block first in stage 1 (config/instruments/red_flags.yaml); any «Да» stops the
  questionnaire with an acute alert and the help screen of its category.
- One crisis rule: the crisis screen opens at a HIGH C-SSRS risk only; moderate stops and goes
  to a psychiatrist (24 h as a guide), low is a flag with the safety plan. PHQ-9 item 9 with a
  negative screener is a discrepancy flag; without a completed screener it asks the C-SSRS at once.
  config/questionnaire.yaml: cssrs_positive_policy graded (C01).
- Every crisis leaves a callback task for the doctor on duty (post_crisis_call, one per patient)
  and the app asks how the person is the next day, the safety plan one tap away.
- Routing: risk and flags first, scales second; PCL-5 >= 50 no longer means a priority
  appointment (pcl5_severe is moderate on the dashboard too).
- Crisis numbers live only in config/texts/crisis.yaml; texts and the agent prompt refer to them
  via {phone:<key>}. Fixes the children's helpline offered to adults by the chat agent.

Refs #92

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 16:21:16 +03:00
Eleboba c09620e6d3 Merge pull request 'feat(ui): единый дизайн всех страниц по образцу кабинета врача' (#88) from feat/85-unified-design into dev
CI / ruff · pytest (push) Successful in 2m26s
Reviewed-on: #88
2026-10-04 16:20:10 +03:00
ElebobaandClaude Opus 5.5 a3180ad232 chore(devops): HTTPS for dev.meditron.tenvex.ru, meditron.tenvex.ru on HTTP until its DNS record
CI / ruff · pytest (pull_request) Successful in 2m20s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 16:19:19 +03:00
Soyavo 07652d044c Merge pull request 'feat(bot): prepare MAX notification adapter and setup handoff' (#89) from feat/83-max-bot into dev
CI / ruff · pytest (push) Successful in 2m21s
2026-10-04 16:17:18 +03:00
Soyavo ae4c76aa62 Merge pull request '[contract] Redact input values in settings validation errors' (#90) from fix/87-settings-privacy into dev
CI / ruff · pytest (push) Successful in 2m19s
2026-10-04 16:17:03 +03:00
Pavel Eliseev a4ee3d25f0 fix(web): allow returning home from questionnaires
CI / ruff · pytest (pull_request) Successful in 2m28s
Keep the shared dialog and submitted answers while leaving the focus screen. Remove the history trap and wire the text-step home action.

Refs #85
2026-10-04 16:14:37 +03:00
Pavel Eliseev 7780b484f3 feat(bot): add MAX notifications adapter and operator handoff
CI / ruff · pytest (pull_request) Successful in 2m27s
Refs #83
2026-10-04 16:10:30 +03:00
Pavel Eliseev 28967c7c37 fix(contract): redact input values in settings errors
CI / ruff · pytest (pull_request) Successful in 2m22s
Refs #87
2026-10-04 16:10:30 +03:00
Pavel Eliseev 2a2fdb171e feat(ui): extend minimal doctor design across all screens
CI / ruff · pytest (pull_request) Successful in 2m16s
Refs #85
2026-10-04 16:09:57 +03:00
Soyavo afbfbad19e Merge pull request 'feat(backend): prepare MAX linking, webhook API and durable notifications' (#86) from feat/82-max-backend into dev
CI / ruff · pytest (push) Successful in 2m16s
2026-10-04 16:09:13 +03:00
Pavel Eliseev 461c3d02ea fix(backend): redact retryable MAX storage failures
CI / ruff · pytest (pull_request) Successful in 2m4s
Refs #82
2026-10-04 16:04:38 +03:00