BUG-026: Store name PATCH/POST → 500 при длине >255 символов
Описание
POST /api/v1/admin/stores и PATCH /api/v1/admin/stores/{id} падают в 500 INTERNAL_ERROR без понятной ошибки, если поле name длиннее 255 символов (например, 516 символов + emoji).
По REST-конвенции (см. api-design.md) и по контракту API.md невалидные данные обязаны возвращаться как 400 VALIDATION_ERROR с details:[{field, message}]. Сейчас сервер падает в catch-all-handler GlobalExceptionHandler.handleGeneral и отдаёт generic 500, что не даёт UI отобразить ошибку под полем формы.
Симптом найден на проде test-base/findings.md как F91 (session-2026-05-12, Critical).
Шаги воспроизведения
- Под
admin@erp.localзайти в админку https://admin.nirbi.ru/admin/stores - Открыть карточку любой ТТ → «Редактировать»
- В поле «Название» вставить строку 516 символов + emoji (фронт
maxLength={255}обходится через DevTools / programmatic Playwrightevaluate()или прямым API-вызовом) - Нажать «Сохранить»
Ожидаемое поведение
- Сервер возвращает 400 VALIDATION_ERROR с
details: [{"field":"name","message":"name must not exceed 255 characters"}] - UI на фронте получает payload и показывает ошибку рядом с полем «Название» (
errors.nameвEditPage.tsx:199уже умеет рендерить)
Фактическое поведение
- Сервер возвращает 500 INTERNAL_ERROR с body
{"error":{"code":"INTERNAL_ERROR","message":"Internal server error"}} - UI показывает только провал «Сохранение…» без понятного сообщения
Корневая причина
dto/request/UpdateStoreRequest.java:18— полеnameбез@Size(без@NotBlank)dto/request/CreateStoreRequest.java:21—@NotBlankесть,@Sizeнет- БД:
stores.name varchar(255)(миграция001-create-stores.xml:19) - Цепочка отказа: DTO не валидирует длину → JPA пишет в PG → PG:
value too long for type character varying(255)→DataIntegrityViolationException→ нет специального handler’а → catch-allException.class→ 500
Контроллер PublicStoreController:69 уже использует @Valid — достаточно добавить аннотацию на DTO без правок контроллера.
Затронутые сервисы
- Store Service — добавить
@Size(max=255)наnameвUpdateStoreRequestиCreateStoreRequest - Admin Franchise (web) — без изменений.
EditPage.tsx:198иCreatePage.tsx:156уже имеютmaxLength={255}на инпуте, фронт защищён через HTML
Спека требует уточнения
03-Services/Store Service/API.md секции POST /stores и PATCH /stores/{id} не указывают максимальную длину name. Это implicit-знание из БД-схемы. Добавить explicit max length 255 в Request Body описание.
Out of scope (отдельные finding’и)
Тот же класс багов потенциально есть на других строковых полях, но не в скоупе F91/BUG-026:
| Поле | БД | DTO @Size | Фронт maxLength |
|---|---|---|---|
phone | varchar(20) | ❌ | ❌ |
city | varchar(100) | ❌ | 255 (расходится с БД) |
email | varchar(255) | ❌ | — |
timezone | varchar(50) | ❌ | — |
При длинных значениях этих полей backend упадёт в 500 по той же схеме. Заводятся отдельными finding’ами по мере подтверждения.
Ссылки
- test-base/findings.md — F91
- {id}
- api-design.md — HTTP 400 vs 500