Архитектура «Дневника самонаблюдений»
Документ описывает архитектуру функционала «Дневник самонаблюдений» и является техническим основанием для разработки. Функционал встраивается в существующий стек: Laravel CRM, Яндекс.Формы, чат-бот MAX.
Источник актуализации: /Users/masaltsev/Documents/dev/crm/docs/diary-architecture.md.
1. Контекст и цели
Дневник самонаблюдений — инструмент рефлексии для волонтёров. После каждого визита к подопечному волонтёр отвечает на 4–5 вопросов:
- Как прошла встреча? (факты, ключевые моменты)
- За что я благодарен подопечному?
- С какими трудностями столкнулся?
- За что могу себя похвалить?
- (Опционально, только для студентов) Какая психологическая теория помогла бы объяснить поведение подопечного?
Ключевое отличие от обычного отчёта: дневник — личный, рефлексивный, не обязательный для всех. Координатор видит записи только если волонтёр сам открыл доступ или поднял «красный флаг».
2. Архитектурные решения
2.1 Место дневника в системе
| Вопрос | Решение | Обоснование |
|---|---|---|
| Где хранить? | Отдельная таблица diary_entries в БД CRM |
Структурированные данные, связь с парой, поиск по записям координатором |
| Как вводить? | Яндекс.Форма, открываемая из бота MAX | Готовый инструмент, привычный UX, поддержка скрытых полей для prefill |
| Когда предлагать? | Сразу после отправки обычного отчёта — как отдельный опциональный шаг | Контекст ещё свежий; не навязываем, предлагаем |
| Кто видит в CRM? | Координатор: только количество записей + «красные флаги»; куратор-психолог: полные записи с разрешения волонтёра | Конфиденциальность — ключевое условие доверия |
| Как отображать в CRM? | Отдельный раздел на странице пары, а не как тип PairEvent | Дневник — не событие пары, а событие волонтёра; смешивать нельзя |
2.2 Связь «волонтёр → дневник → пара»
Идентификация происходит через уже реализованный механизм: volunteer_profiles.max_user_id → Contact с type=volunteer → активные Pair.
Пара выбирается на этапе обычного отчёта (в боте). pair_id и volunteer_contact_id передаются в форму через GET-параметры в URL Яндекс.Формы (скрытые предзаполненные поля).
2.3 Механизм предзаполнения Яндекс.Форм
Яндекс.Формы поддерживают передачу значений через GET-параметры URL. Для скрытых полей нужно:
- Добавить вопрос типа «Короткий текст»
- Включить опцию Скрытый вопрос
- Задать Идентификатор вопроса (например,
volunteer_id,pair_id) - Формировать ссылку с параметрами:
?volunteer_id=42&pair_id=17
3. Поток данных (общая схема)
Волонтёр в боте MAX
↓ (выбирает пару, отправляет обычный отчёт)
↓ PairEvent сохраняется в CRM
↓
Бот: «Хотите заполнить дневник самонаблюдений? Это займёт 5 минут.»
[📓 Открыть дневник] [Пропустить]
↓ (нажатие кнопки «Открыть дневник»)
↓
CRM генерирует URL Яндекс.Формы с prefill-параметрами:
https://forms.yandex.ru/u/{FORM_ID}/?volunteer_id=42&pair_id=17
↓
Волонтёр заполняет форму в браузере (или WebView)
↓
Яндекс.Форма → POST Webhook → CRM endpoint /api/diary/yandex-webhook
↓
CRM: создаёт DiaryEntry, связывает с Pair и Contact
↓
Бот: «Запись сохранена»
4. Модель данных (концептуально)
Ключевые поля записи дневника:
volunteer_contact_id(связь с волонтёром)pair_id(связь с парой)visit_date- ответы
q1–q5 has_red_flag(автоматически по ключевым словам)yandex_form_id(для идемпотентности)
Подробная SQL‑схема и чеклист реализации (миграции/контроллеры/политики/тесты) — в исходном документе из репозитория CRM.
5. Доступы и отображение в CRM
- Координатор: видит сводку (кол-во записей, наличие/кол-во red‑flag) по своим парам.
- Куратор‑психолог: видит полный текст записей (новая роль, отдельная политика доступа).
- Волонтёр: видит только свои записи через MAX‑бот (последняя запись / экспорт).