feat(bot): veteran daily check-in, medication reminders and rule reactions

Daily check-in (mood → dose → sleep/nightmares → alcohol → free text with
extract_checkin, buttons win over the LLM, progressive upsert of
daily_checkins), medication reminder flow (taken / skip with reason /
side effects → doses + daily_checkins), medication question menu via
med_qa, med_info rule reactions from the drug instruction excerpt,
«записаться раньше» request recorded for lane B, friendly intros for
scheduled scales. actions.py: additive med_info handler hook.

Refs #37

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-03 18:45:53 +03:00
co-authored by Claude Opus 5.5
parent 4c6e150162
commit 2b13d54ed7
5 changed files with 1061 additions and 4 deletions
+98
View File
@@ -0,0 +1,98 @@
# Тексты приёма препарата (issue #37): напоминание, пропуск, побочные эффекты, вопрос о лекарстве, ответы
# на действия правил med_info (отсроченный эффект, алкоголь, побочные эффекты).
# СТАТУС: черновик, утверждает психиатр (#8).
#
# Правила текстов: без диагнозов и названий расстройств; без советов по дозам и схеме приёма (решает врач);
# не использовать слова, которые звучат как постановка на учёт или слежка (проверяется тестом). Ответы о
# препарате берутся только из выдержки инструкции ГРЛС (app/llm/med_qa.py); тексты ниже — обрамление и
# запасные варианты, если выдержки нет.
status: "черновик, утверждает психиатр (#8)"
reminder:
# {drug}, {dose} — из назначения врача (МНН и дозировка как в назначении, без изменений).
text: "Время принять {drug} {dose}. Отметьте, пожалуйста, как получилось."
text_no_drug: "Время принять препарат, назначенный врачом. Отметьте, пожалуйста, как получилось."
taken: "Принял(а)"
skip: "Пропущу"
side_effects: "Есть побочные эффекты"
taken_ack: "Отлично, отметил приём. Спасибо!"
# Кнопка от напоминания, которое уже неактуально (например, вчерашнего).
stale: "Это напоминание уже неактуально. Если хотите отметить самочувствие — нажмите «Как я сегодня»."
skip:
question: "Понял, отметил. Подскажите, что помешало? Это поможет вашему врачу."
reasons:
forgot: "Забыл(а)"
side_effects: "Из-за побочных эффектов"
quit: "Решил(а) бросить"
other: "Другое"
ack:
forgot: "Понял, бывает. Завтра напомню в обычное время."
quit: "Спасибо, что честно сказали — это важно, и решать это лучше вместе с врачом."
other: "Понял, отметил. Если захотите рассказать подробнее — просто напишите."
side_effects:
question: "Что беспокоит? Выберите вариант или «Другое», чтобы описать своими словами."
options:
nausea: "Тошнота"
insomnia: "Бессонница"
headache: "Головная боль"
dizziness: "Головокружение"
agitation: "Беспокойство"
other: "Другое"
# Короткий вопрос к инструкции препарата (med_qa, раздел «побочные эффекты») для выбранного эффекта.
questions:
nausea: "тошнота после приёма, когда пройдёт"
insomnia: "бессонница, нарушения сна"
headache: "головная боль"
dizziness: "головокружение"
agitation: "беспокойство, тревога"
describe: "Опишите, пожалуйста, коротко, что вы заметили."
ack: "Спасибо, отметил. Ваш врач увидит это в вашей карточке."
# Тот же эффект был и вчера: инструкцию второй раз не повторяем.
repeat: "Понимаю, это неприятно. Я отмечаю это каждый день, и ваш врач увидит, если не проходит."
ask_dose: "А препарат сегодня приняли?"
dose_yes: "Да, принял(а)"
dose_no: "Нет"
# Ежедневный чек-ин: если сегодня ещё нет отметки о приёме.
checkin:
question: "Сегодня приняли {drug}?"
question_no_drug: "Сегодня приняли назначенный препарат?"
"yes": "Да"
"no": "Нет"
later: "Ещё нет"
question:
prompt: "Напишите ваш вопрос о препарате. Я отвечаю только по официальной инструкции, а если ответа в ней нет — подскажу обратиться к врачу."
no_prescription: "Я не нашёл в карточке назначенного препарата. Пожалуйста, уточните вопрос у вашего врача."
# Ответы на действие правила med_info. Ответ = lead + выдержка из инструкции (med_qa по разделу section,
# вопрос question) + notice. Если выдержки нет — lead + fallback + notice.
med_info:
delayed_effect:
section: onset
question: "когда начнёт действовать препарат, нет эффекта, только хуже"
lead: "Понимаю, что сейчас тяжело."
fallback: "Эффект таких препаратов обычно наступает не сразу, а через 2–4 недели регулярного приёма. Пожалуйста, не прекращайте приём самостоятельно."
notice: "Я сообщил вашему врачу — он свяжется с вами, чтобы обсудить, как вы себя чувствуете."
alcohol_interaction:
section: alcohol
question: "можно ли алкоголь вместе с препаратом, сон"
lead: "Спасибо, что честно рассказали."
fallback: "В инструкции к препарату есть предупреждение о совместном приёме с алкоголем, а алкоголь сам по себе ухудшает сон."
notice: "Я передал это вашему врачу."
nausea:
section: side_effects
question: "тошнота после приёма, когда пройдёт"
lead: ""
fallback: "Тошнота часто встречается в первые дни приёма и обычно проходит сама."
notice: "Если станет хуже — напишите мне, я передам врачу."
side_effects:
section: side_effects
question: "побочные эффекты в начале приёма"
lead: ""
fallback: "Спасибо, что сообщили о самочувствии. Я отмечу это для вашего врача."
notice: "Если станет хуже — напишите мне, я передам врачу."
+62
View File
@@ -0,0 +1,62 @@
# Тексты ежедневного чек-ина и плановых шкал (issue #37, ADR-002, CLINICAL_MODULES §1–2).
# Ядро (настроение + приём) задаётся всем; вопрос про сон и кошмары — модулю veteran; алкоголь — см. settings.
# СТАТУС: черновик, утверждает психиатр (#8).
#
# Правила текстов: без диагнозов и названий расстройств; без советов по дозам; пациент не видит баллов шкал;
# не использовать слова, которые звучат как постановка на учёт или слежка (проверяется тестом).
status: "черновик, утверждает психиатр (#8)"
settings:
# Модули, которым задаётся вопрос про сон и кошмары (modules.yaml: daily_question = sleep_nightmares).
sleep_modules: [veteran]
# Ежедневный вопрос об алкоголе: модули, где он задаётся всегда (у ветеранов алкоголь — частый способ
# «заглушить» бессонницу и фактор риска, CLINICAL_MODULES §1); остальным — при положительном AUDIT-C
# (порог берётся из правила auditc_positive в config/rules.yaml, ADR-002).
alcohol_daily_modules: [veteran]
# Плановые шкалы, перед которыми показывается дружелюбное вступление (см. scale_intros).
intro_scales: [pcl5, phq9, dar5, auditc]
checkin:
start: "Добрый день! Короткая отметка о самочувствии — это займёт меньше минуты."
mood:
question: "Как ваше настроение сегодня по шкале от 0 до 10? 0 — очень плохо, 10 — отлично."
sleep:
question: "Сколько часов удалось поспать прошлой ночью?"
options:
"<4": "Меньше 4 ч"
"4-6": "4–6 ч"
"6-8": "6–8 ч"
">8": "Больше 8 ч"
nightmares:
question: "Снились ли кошмары или тяжёлые сны?"
"yes": "Да"
"no": "Нет"
alcohol:
question: "Выпивали ли вы алкоголь за последние сутки?"
clarify: "Вы упомянули алкоголь. Сколько примерно выпили за последние сутки?"
options:
none: "Не пил(а)"
"1-2": "1–2 порции"
more: "Больше"
text:
question: "Как вы? Можно пару слов — что было за день, что беспокоит."
skip: "Пропустить"
buttons_hint: "Выберите, пожалуйста, вариант кнопкой."
done: "Спасибо, записал. Если что-то изменится — пишите в любое время."
already_done: "Сегодня вы уже отмечались, спасибо! Если хотите что-то добавить — просто напишите."
visit:
# Нажата кнопка «Записаться к врачу раньше» (действие правила suggest_visit). Онлайн-записи пока нет —
# просьба передаётся врачу как факт в карточке.
requested: "Передал врачу просьбу о более раннем визите. С вами свяжутся, чтобы договориться о времени. Если станет хуже до визита — пишите мне или звоните 112."
# Дружелюбное вступление перед шкалой (параметр intro у start_scale). Пациент не видит баллов.
scale_intros:
scheduled:
pcl5: "Раз в две недели я прошу ответить на вопросы о том, как беспокоят тяжёлые воспоминания и их последствия. Это займёт 3–4 минуты. Так ваш врач увидит, что меняется со временем."
phq9: "Пора для короткого опроса о настроении и силах за последние две недели — 9 вопросов. Отвечайте так, как есть, правильных ответов нет."
dar5: "Несколько вопросов о раздражительности и вспышках гнева. После службы это бывает у многих, и врачу важно видеть, как это меняется."
auditc: "Три коротких вопроса об алкоголе. Отвечайте как есть: это нужно врачу, чтобы лечение было безопасным."
unscheduled:
phq9: "Последние дни настроение ниже обычного. Давайте я задам несколько вопросов — так ваш врач лучше поймёт, как вы сейчас."