Task #6109
closedПоля helpDirections, missionParticipationConfirmed, personalDataConsent + nullable даты
100%
Description
Сопутствующая задача к ТЗ на доработку АИС ГМ от 24.08.2026. Фронтенд реализован полностью (проект hummission-front, задачи #6093–#6107) и уже отправляет/читает перечисленные поля. Задача самодостаточна: всё, что нужно бэкенду, описано здесь.
Перенесена из hummission-front #6108.
1. Новые поля волонтера¶
/api/volunteers (GET списком, POST, PUT) и волонтер внутри /api/volunteer-applications:
| Поле | Тип | Смысл |
|---|---|---|
helpDirections |
string[] |
направления волонтерской помощи, 16 значений справочника (см. ниже) |
missionParticipationConfirmed |
boolean | null |
подтверждение участия; null = статус не поставлен, это отдельное состояние, не false
|
volunteerMissionId |
string | null |
миссия, к которой привязан волонтер |
volunteerMissionShiftId |
string | null |
смена |
Справочник helpDirections (ключи; подписи используются в Excel-шаблонах):
NO_SPECIALIZATION, CONSTRUCTION_REPAIR, ROOFING, WELDING, ELECTRICAL, PLUMBING, DRIVER_CAR_B, DRIVER_TRUCK_C, COOKING, MEDICAL_HELP, PSYCHOLOGICAL_HELP, LEGAL_HELP, LOADING_UNLOADING, LOGISTICS, CHILDREN_ELDERLY, MEDIA_VOLUNTEER.
Правило целостности: NO_SPECIALIZATION не может встречаться вместе с любым другим значением. На фронте это гарантировано UI, на бэкенде желательна валидация — данные приходят ещё и через импорт Excel.
2. Заявка из внешнего контура¶
POST /api/volunteer-applications/outer_perimeter (multipart/form-data) дополнительно получает:
-
helpDirections— повторяющееся поле, по одному значению на запись (не строка через запятую) -
personalDataConsent—"true"/"false", согласие на обработку персональных данных. Без отметки фронт не даёт отправить заявку; значение стоит сохранять как юридический факт с датой и версией текста согласия (https://er.ru/upages/soglasie-pd4).
3. Проставление подтверждения участия из таблицы¶
PATCH /api/volunteers/{id}/participation-confirmation
Тело: { "missionParticipationConfirmed": true | false | null }
Решение на согласование: эндпоинт придуман фронтендом. Если удобнее — можно обойтись существующим PUT /api/volunteers/{id}, тогда правится один вызов во фронте (VolunteersIndex.tsx, handleParticipationChange). Отдельный PATCH выбран потому, что оператор меняет статус построчно и слать целого волонтера ради одного поля не хочется.
Фронт применяет изменение оптимистично и откатывает значение в UI при любой ошибке, так что до реализации эндпоинта колонка визуально работает, но не сохраняет.
4. Импорт волонтеров¶
POST /api/volunteer-missions/{id}/import-volunteers — в объектах массива volunteers теперь приходят helpDirections и missionParticipationConfirmed (см. п.1). Тот же эндпоинт используется импортом со страницы «Волонтеры».
5. Nullable даты¶
-
VolunteerMission.missionStartDate/missionEndDate— сделать nullable -
VolunteerMissionShift.departureDate/arrivalDate— сделать nullable
Прямое требование ТЗ (раздел «Волонтерские миссии», пп.1–2). Фронт отправляет null при пустом значении и корректно отображает отсутствующие даты.
6. Желательно (не блокирует)¶
GET /api/volunteers — отдавать связанные mission (id, name, missionStartDate, missionEndDate) и shift (id, shiftNumber). Сейчас карточка волонтера при отсутствии этих данных догружает последнюю заявку волонтера отдельным запросом (/api/volunteer-applications?volunteerId=...&size=1&sort=createdAt,desc), а фильтр по миссии на странице «Волонтеры» работает только по тем волонтерам, у кого связь пришла в списке.
Совместимость¶
Все новые поля читаются фронтендом защитно (отсутствующее значение = пусто), поэтому фронт можно выкатывать до бэкенда — ничего не сломается, новые поля просто не будут сохраняться.
Updated by Redmine Admin about 13 hours ago
- Status changed from New to Resolved
- % Done changed from 0 to 100
Реализовано на бэкенде и подтверждено фактическим ответом API /api/volunteer-applications/{id} от 26.08.2026: приходят helpDirections, missionParticipationConfirmed (в т.ч. null как отдельное состояние), volunteerMissionId / volunteerMissionShiftId, а также связанные mission (с cyrillicId, topic, location, plannedVolunteersCount, registeredVolunteersCount, ответственным и source) и shift (с departureLocation / arrivalLocation).
Согласие на ПД сделано богаче, чем было в спецификации, и это правильно: помимо personalDataConsent отдаются personalDataConsentAt и personalDataConsentVersion — фронтенд показывает все три в карточке заявки.
Фронтенд карточки заявки доработан под полный ответ (коммит 36f0724).
Осталось проверить отдельно (не блокирует закрытие):
- даты приходят в формате
2026-09-02T21:00— без таймзоны и безZ. Похоже на московскую полночь, сохранённую как UTC. JS разбирает такую строку как локальное время, поэтому возможен сдвиг на сутки при отображении. Нужно сверить с тем, что оператор вводил в форме миссии. -
PATCH /api/volunteers/{id}/participation-confirmation— отдельно не проверялся.