← всі звіти · med-detective-top5-fixes-plan-2026-05-01.md
Med Detective top-5 fixes — детальний план для апруву
2026-05-01. Узгодження ПЕРЕД роботою. Med Detective = продакшн (вже відданий лікарям на тест), prod-лінк /med-detective/. Жодна зміна не йде у prod без проходження test-інстансу + ОК Сергія. Blue/green: правки робляться у /srv/projects/med-detective-test/ (port 8766, Redis DB 4 — поточно вказує prod), потім swap Caddy.
Поточний mapping (перевірено): /med-detective/ → 127.0.0.1:8766 (нова версія) · /med-detective-test/ → 127.0.0.1:8765 (стара). Перед стартом треба rsync prod→test (або swap назад), щоб правити ізольовано.
Фікс 1. Groq Judge backend
Що змінюється
- Файл:
backend/llm.py
- Що додаємо: новий клас
GroqBackend(LLMBackend) поруч з ReplicateBackend і GeminiBackend. API-ключ з /srv/passepartout/groq/groq.key (створимо). Стандартна модель: llama-3.1-70b-versatile або llama-3.3-70b-versatile.
- Що міняємо: функцію
get_judge_backend() (line 122). Зараз повертає ReplicateBackend(REPLICATE_JUDGE_MODEL). Меняємо логіку: пріоритет Groq → Replicate fallback → Gemini.
- Конфіг через env: додати
MED_JUDGE_BACKEND=groq як default у systemd unit.
Що НЕ змінюється
- Patient backend (
MED_PATIENT_BACKEND) — лишається Replicate Llama-3-8b як зараз.
- Intent backend (
MED_INTENT_BACKEND) — лишається.
extract_json() — універсальна, не торкаємо.
- Rubric judge (45/40/15 розподіл) — не торкаємо, це окремо у
prompts/.
- API endpoints
/api/judge — без змін у контракті, лише latency.
Тестування
- Локально: викликати
judge(session_id) на готовий case_01 → перевірити що JSON приходить, рубрика 100, all 5 keys присутні (diagnosis_score, history_score, plan_score, …).
- Latency: міряти
time 5 викликів, очікую <500ms vs зараз 15s.
- Якщо Groq падає (rate limit/down) → fallback на Replicate автоматично.
Ризики
- Groq має менший контекст (32k vs 128k). Перевірити що наш rubric+history influences не виходить за ліміт. Поточно перевіряти не потрібно — в практиці <8k токенів на сесію.
- Якщо Сергій ще не має Groq API key — він має зареєструвати на console.groq.com і дати, інакше фікс відкладається.
- Кеш
_JUDGE_CACHE — переконатись що при перемиканні в env скиду кеша через systemctl restart.
Оцінка
2-3 год (1 год імплементація + 1 год тестування + 0.5 год promote).
Фікс 2. Lead Capture (email modal → Supabase)
Що змінюється
- Backend (
main.py): новий ендпоінт POST /api/lead приймає {session_id, email, consent}. Записує у Supabase таблицю leads (ID, email, session_id, case_id, score, ts).
- Frontend (
index.html): після showResult() рендерити модальне вікно «Хочете отримати свідоцтво/CME PDF? Введіть email». Поле email + checkbox згоди + кнопки. На submit → POST /api/lead.
- Конфіг: Supabase credentials у
/srv/passepartout/supabase/med-detective.env (новий файл; URL+anon_key+service_key) + .meta.
- Schema Supabase: SQL setup для таблиці
med_detective_leads (uuid PK, created_at default now(), email text, session_id text, case_id text, score int, consent_at timestamptz). RLS: read-only для anon, write — service-key from backend.
Що НЕ змінюється
- Сам опитувальник, judge, кейси.
- localStorage логіка (буде паралельно у фікс 5).
Тестування
- Відкрити кейс, дойти до результату, відкрити модалку, ввести email → перевірити що рядок з'явився у Supabase і email прийшов на серверні логи.
- Невалідний email → frontend-валідація показує помилку, ендпоінт не викликається.
- Без consent → submit заблокований.
- Дубль (той самий email + session_id) → backend has UNIQUE constraint, повертає 409 — UI показує «Вже надіслано».
Ризики
- Якщо Supabase буде down → frontend має graceful failure, не блокувати інший flow.
- GDPR: явна згода (checkbox) обов'язкова.
- ⚠️ Можливі звернення до Supabase з боку юристів — додати у Privacy Policy на лендингу. Сергій підтвердити що privacy текст готовий.
Оцінка
3-4 год (1 год Supabase setup + 1 год backend + 1 год frontend + 0.5 год тестів).
Фікс 3. GA4 + custom events
Що змінюється
- Frontend: у
index.html секція <head> — gtag.js init з GA4 measurement ID (потрібен від Сергія, або беремо з вже існуючого аналогічного проекту biogaia-story/pediatric-news).
- Custom events триггеримо у JS:
case_started (case_id)
question_asked (case_id, question_index)
tests_ordered (case_id, n_tests)
diagnosis_submitted (case_id)
judge_completed (case_id, total_score)
lead_captured (case_id) — через фікс 2
- Подія
page_view — за замовчуванням gtag.
Що НЕ змінюється
Тестування
- GA4 DebugView — побачити events у реальному часі.
- Прогнати один cycle, перевірити що всі 6 events стрельнули.
- Перевірити що cookies (consent) поважаються — GA4 не пише без consent.
Ризики
- Adblock блокує GA4 — це норма, не вирішувати.
- Якщо ID GA4 не сергіїв (а тестовий) — забруднимо реальний моніторинг. Тому беремо саме prod GA4 ID Med Detective.
Оцінка
2 год (0.5 год GA4 setup + 1 год events + 0.5 год тестів).
Фікс 4. Investigation Panel — повна версія
Контекст
MVP вже зроблений 19.04 (синя кнопка «Замовити обстеження» + модал з категоріями + результати як system-bubble). Дизайн повної версії: /srv/projects/med-detective-test/docs/investigation_panel_design.md.
Що в плані повної версії (що додаємо)
- Tab-категорії з фільтром. Зараз 6 категорій × всі тести; додаємо search-bar по назві.
- «Recommended»-теги — judge-side hint про які тести варті при цьому case_id (на основі
key_tests_to_order). Не показуємо ground-truth, лише subtle підказку.
- Ціна/час тесту — meta-фільд у
lab_catalog.py (ціна в грн + час очікування результату). Добавляємо у UI як цифри під назвою.
- Бюджет-лічильник — кожен case має ліміт «бюджет на тести 500 грн / 24 год». Граєш — лічишся. Judge нараховує бонус «cost-effective» якщо вкладся.
- Результат у різних форматах: числа (ЗАК), якісні (КОН-мікроскопія: «грибки виявлені»), графіки (ЕКГ — простий SVG-патерн).
- Reset-кнопка — починати замовлення тестів заново.
Що НЕ змінюється
- Існуючий MVP UI зберігається; нові tab/search/cost — інкрементально.
- Judge-rubric — без змін у формулі (бонус cost-effective можемо додати окремою фічею пізніше).
- API контракт
/api/order_tests — без зміни.
Тестування
- Відкрити Investigation Panel, перевірити tab/search.
- Замовити 5 тестів → лічильник працює.
- Перевірити графік ЕКГ (case_03) рендериться у chat-bubble.
- Reset → стан очищується.
Ризики
- 7-8 год роботи — це мінімум 2 робочі сесії. Можна розбити на 2 deploys (фази a і b).
- SVG графіки — для ЕКГ потрібні базові патерни. Якщо складно — рендеримо фотку placeholder.
- Бюджет може ускладнити рубрику — обережно, не зачепити поточну логіку judge.
Оцінка
MVP-додатки (tab/search + cost meta + UI цифри): 2-3 год.
Повна версія з бюджетом + графіками + Reset: 7-8 год.
Пропоную MVP-додатки спочатку, повна версія другим етапом.
Фікс 5. Gamification MVP
Що змінюється
- Frontend (
index.html):
- Streak counter: localStorage
streak_days + last_played_date. Показуємо badge «🔥 5 днів поспіль» біля логотипу. Якщо пропустив день — reset.
- Daily quest unlock: кожного дня доступний 1 «daily case». Якщо вже сьогодні грав — UI блокує з повідомленням «Завтра відкриється новий кейс». Робимо опціонально (toggle через settings).
- CME PDF на result screen — кнопка «Завантажити сертифікат». Генеруємо HTML-сертифікат → клієнтський html2canvas + jsPDF (CDN), без backend.
- Backend: жодних змін (gamification клієнтсайд, ніяка БД не потрібна).
Що НЕ змінюється
- Backend, judge, кейси, structurа сесій.
Тестування
- Відкрити кейс day 1 → завершити → streak = 1.
- Через 24 год → новий day → streak = 2.
- Пропустити день → reset до 0.
- Daily quest: пройти один кейс, потім спробувати другий — UI блокує.
- CME PDF — згенерувати, відкрити у readers (Chrome PDF viewer + Acrobat) — щоб не зламана була верстка.
Ризики
- localStorage обмежений 5MB — перевищити неможливо.
- CME PDF — назва прізвище лікаря потрібна; беремо з Lead Capture (фікс 2). Якщо ще не залишив email/прізвище — показуємо placeholder «Лікар» або просимо ввести.
- Юридично: чи можна зватись «CME сертифікат» без акредитації? Можливо краще «Свідоцтво про проходження» — узгодити з Сергієм.
Оцінка
1-2 дні (8-12 год).
Бонус (нижчий пріоритет, без апруву поки що)
Health-anxiety trigger уніфікація
Додати field patient_anxiety: bool у case schema (backend/cases/*.json), валідатор перевіряє. Час: 2 год. Чекає Сергія: чи додавати у всі 11 кейсів, чи лише там де реально патерн «сам себе налякав»?
Gender balance +3 case з чоловіками 45+
Створити case_12 (ХБН/протата), case_13 (подагра), case_14 (tinnitus). Через Case Builder Crew. Час: 1 день. Чекає: Сергій підкаже які product-targets.
Real product photos
5 SVG placeholders (Forteza Spray, Menopace Plus, ZEST MgB6, Argett Sport, ProFLEX Osteo) → реальні webp. Час: 1 год. Чекає: Сергій надсилає фото або URLs з brandsite'ів.
Підсумкова оцінка
| Фікс |
Час |
Ризик |
Залежності |
| 1. Groq Judge |
2-3 год |
низький |
Groq API key від Сергія |
| 2. Lead Capture |
3-4 год |
середній |
Supabase credentials, Privacy Policy |
| 3. GA4 events |
2 год |
низький |
GA4 measurement ID |
| 4. Investigation Panel (a-MVP) |
2-3 год |
низький |
— |
| 4. Investigation Panel (b-full) |
5-6 год |
середній |
дизайн графіків ЕКГ |
| 5. Gamification |
8-12 год |
низький |
юридична назва сертифіката |
Загалом: ~25-30 год роботи. Можна розбити на 5 sprint'ів по фіксу.
Що мені потрібно від Сергія перед стартом
- Groq API key — або зареєструвати, або сказати «беремо тільки Replicate, Groq поки відкласти»
- Supabase credentials — використовуємо
lunar-hubble.env (вже у passepartout) як шаблон, чи створюємо окремий project? Створення займе 5 хв.
- GA4 Measurement ID — який саме (новий property, чи об'єднуємо з biogaia-story?)
- Privacy Policy текст для Lead Capture — є готовий, чи треба написати?
- Юридичну назву сертифіката — «CME сертифікат» (потребує акредитації) чи «Свідоцтво про проходження»?
- Порядок: робити всі 5 паралельно чи послідовно? Я б порадив послідовно: 1 → 3 (швидкі) → 4a → 2 → 4b → 5.
- Перед стартом swap test/prod або rsync prod→test — ОК на rsync prod→test зараз (синхронізує test-інстанс зі станом prod), потім правки тільки у test, після ОК — swap у prod.
Що НЕ роблю без подальшого ОК
- Деплоїти у prod (
/med-detective/) — лише після проходження test-інстансу.
- Видаляти будь-які кейси чи API endpoints.
- Змінювати rubric judge-а (це серцевина).
- Чіпати інші med-detective інстанси (
menopace, fables).
Пиши «погнали по N» — і починаю. Або «всі 5 послідовно з пунктом 1».