BUG-017: Legal details — поля не маппятся + GET 404 вместо пустого объекта
Описание
Два связанных бага в юридических деталях сотрудника:
- GET возвращает 404 если у сотрудника ещё нет юр. деталей — фронтенд видит ошибку вместо пустой формы
- PUT возвращает 500 — фронтенд отправляет поля с другими именами чем ожидает бэкенд
Запрос 1: GET
GET https://erp-test.nirbi.ru/api/v1/admin/employees/84737600-38e1-45fb-874f-46755dc31a21/legal-details
Status: 404 Not Found
{
"error": {
"code": "LEGAL_DETAILS_NOT_FOUND",
"message": "Legal details not found for employee 84737600-38e1-45fb-874f-46755dc31a21"
}
}Запрос 2: PUT
PUT https://erp-test.nirbi.ru/api/v1/admin/employees/84737600-38e1-45fb-874f-46755dc31a21/legal-details
Status: 500 Internal Server Error
{
"inn": "1234432123",
"passport": "1234 234521",
"driver_license": "1234 34322",
"snils": "123-872-872 89"
}{
"error": {
"code": "INTERNAL_ERROR",
"message": "Internal server error"
}
}Анализ
Баг 1: GET 404
LegalDetailsService.get() бросает LEGAL_DETAILS_NOT_FOUND (404) если запись не существует. Но по UX юр. детали — необязательная секция. При первом открытии вкладки запись ещё не создана.
Решение: GET должен возвращать 200 с пустым/null объектом, а не 404. Или фронтенд должен обрабатывать 404 как “нет данных, покажи пустую форму”.
Баг 2: PUT 500 — несовпадение полей фронтенда и бэкенда
| Фронтенд отправляет | Бэкенд ожидает (DTO) | Проблема |
|---|---|---|
inn | inn | ✅ Маппится, но 10 цифр → validation fail (нужно 12) |
passport | passport_series + passport_number | ❌ Фронт шлёт одно поле, бэкенд ждёт два |
driver_license | driver_license_number | ❌ Другое имя поля |
snils | snils | ✅ Маппится, но формат “123-872-872 89” vs regex ^\d{3}-\d{3}-\d{3} \d{2}$ — OK |
Фронтенд (ViewPage.tsx вкладка “Юридические детали”) использует:
passport(одно поле “серия + номер”) → бэкенд ожидаетpassport_series(4 цифры) +passport_number(6 цифр) раздельноdriver_license→ бэкенд ожидаетdriver_license_number
Jackson игнорирует неизвестные поля → все null → сервис создаёт пустую запись или падает.
Причина 500: скорее всего inn = “1234432123” (10 цифр) проходит через @Valid → MethodArgumentNotValidException → должен вернуть 400. Если 500 — значит ошибка в другом месте (возможно entity save с null в NOT NULL field, или exception при сериализации).
Затронутые сервисы
| Сервис | Проблема |
|---|---|
| User Service | GET возвращает 404 вместо пустого объекта |
| Admin Web | ViewPage: неправильные имена полей (passport, driver_license), паспорт не разделён на серию/номер |
| Shared Types | UpsertLegalDetailsRequest использует правильные поля, но фронт не следует им |