docs: G1/SP3c дизайн — полные платёжные реквизиты (фронт)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Дмитрий
2026-06-19 07:54:57 +03:00
parent 44b93679c4
commit 0a044fc06b
@@ -0,0 +1,136 @@
# G1/SP3c — полные платёжные реквизиты (фронт) — дизайн
**Дата:** 19.06.2026
**Статус:** дизайн утверждён владельцем (брейншторм)
**Спринт:** G1/SP3c. Предшественники: SP1 (самозапись), SP2 (бэкенд реквизитов+гейт), SP3a (фронт входа), SP3b (лёгкая форма реквизитов + гейт).
**Граница:** только фронт. Бэкенд (поля + валидация) готов в SP2, не меняется.
---
## 1. Цель
Дать клиенту возможность дозаполнить **полные платёжные реквизиты** (КПП / ОГРН /
юр.адрес / банковские реквизиты) — для будущего этапа оплаты (счёт/договор).
Расширяет ту же вкладку «Реквизиты» из SP3b, добавляя блок ниже лёгких полей.
`requisites_completed_at` бэкенд ставит при заполнении расчётного счёта
(`RequisitesService::upsert`). Пока этот флаг **не потребляется** никаким
гейтом оплаты (этап оплаты — будущее); в SP3c он используется только для
информативного чипа-статуса.
---
## 2. Готовый бэкенд (контракт, не меняем)
Все поля уже есть в таблице `tenant_requisites` (миграция SP2) и в
`RequisitesResource`. Эндпоинты — те же `GET/PUT /api/tenant/requisites`
(SP3b api-обёртка `getRequisites`/`updateRequisites` уже их покрывает; новых
api-функций не нужно).
**Поля (nullable) и форматы валидации** (`UpdateRequisitesRequest`):
- `kpp``regex:/^\d{9}$/`
- `ogrn``regex:/^(\d{13}|\d{15})$/`
- `legal_address``string` (nullable)
- `bank_name``string` max:255
- `bank_bik``regex:/^\d{9}$/`
- `bank_account``regex:/^\d{20}$/`
- `corr_account``regex:/^\d{20}$/`
**`requisites_completed_at`**: ставится в `now()` если `bank_account` заполнен,
иначе `null` (`RequisitesService::upsert`). Возвращается в `RequisitesResource`.
`Requisites`-интерфейс (`api/requisites.ts`, SP3b) **уже включает** все эти поля —
менять api-слой не нужно.
---
## 3. Что добавляем во фронте
Только расширение `app/resources/js/views/settings/RequisitesTab.vue`. Новых
файлов, роутов, api-функций, правок бэкенда — нет.
### 3.1. Блок «Реквизиты для оплаты»
Ниже лёгких полей (после строки контакт/ИНН) — отдельный блок:
- Заголовок «Реквизиты для оплаты (для счёта и договора)».
- **Чип-статус** рядом с заголовком:
- 🟢 `color="success"` «Готово к оплате» — если `form.requisites_completed_at` заполнен;
-`color="default"`/grey «Не заполнено» — иначе.
- Поясняющая подпись: «Нужны для выставления счёта и договора. Можно заполнить позже.»
### 3.2. Поля по типу лица
Видимость завязана на `form.subject_type` (computed-флаги):
- **legal_entity (Юрлицо):** КПП · ОГРН · Юр.адрес · Наименование банка · БИК · Р/с · К/с
- **sole_proprietor (ИП):** ОГРНИП *(поле `ogrn`)* · Юр.адрес · Наименование банка · БИК · Р/с · К/с — **без КПП**
- **individual (Физлицо):** Наименование банка · БИК · Р/с · К/с — **без КПП/ОГРН/юр.адреса**
Лейбл поля `ogrn`: «ОГРН» для ЮЛ, «ОГРНИП» для ИП.
### 3.3. Валидация (клиент зеркалит бэкенд)
Все платёжные поля **необязательные**. Проверка только если поле заполнено:
- `kpp` — ровно 9 цифр;
- `ogrn` — для ЮЛ ровно 13 цифр, для ИП ровно 15 цифр (UI-уточнение; бэкенд
принимает 13 или 15);
- `bank_bik` — ровно 9 цифр;
- `bank_account`, `corr_account` — ровно 20 цифр.
Клиентская проверка добавляется в существующий `validateClient()` (SP3b) — он
по-прежнему сначала проверяет обязательные лёгкие поля, затем (если заполнены)
платёжные форматы. Серверные `422` раскладываются по полям (механизм SP3b).
### 3.4. Данные / поведение
- `GET` (onMounted, SP3b) уже предзаполняет все поля, включая платёжные.
- `PUT` (`save()`, SP3b) уже отправляет всю форму целиком — платёжные поля
уедут вместе с лёгкими.
- После сохранения `Object.assign(form, updated)` (SP3b) обновит
`requisites_completed_at` → чип перерисуется.
---
## 4. Обработка ошибок
- `422` с полевыми `errors` → раскладка по полям (готово в SP3b `save()`).
- Прочие → общий `saveError` через `extractErrorMessage` (готово в SP3b).
- Отдельной обработки SP3c не требует.
---
## 5. Верификация
vitest сломан (G8). Проверяем:
- `npm --prefix app run type-check` (`vue-tsc`) = exit 0.
- eslint по `RequisitesTab.vue` = 0 ошибок.
- `npm --prefix app run build` = успех (перед Playwright обязательна пересборка).
- **Живой Playwright (обязательно):**
1. Клиент из SP3b (лёгкие реквизиты есть) → вкладка реквизитов; чип «Не заполнено».
2. Тип «ИП» → видны ОГРНИП + юр.адрес + банк, КПП скрыт; заполнить валидно
(ОГРНИП 15 цифр, БИК 9, р/с 20, к/с 20) → Сохранить → чип «Готово к оплате».
3. Тип «Юрлицо» → появляется КПП (9 цифр); тип «Физлицо» → КПП/ОГРН/юр.адрес
скрыты, остаётся только банк (проверка видимости по типу).
4. Негатив: БИК `8 цифр` → видимая ошибка под полем.
---
## 6. YAGNI / границы
- НЕ трогаем бэкенд (поля и валидация готовы в SP2).
- НЕ добавляем api-функции (SP3b обёртка уже шлёт всю форму).
- НЕ делаем кросс-полевую обязательность банковского набора (бэкенд этого не
требует; `requisites_completed_at` ставится по `bank_account`). Чип честно
отражает бэкенд-правило.
- НЕ делаем гейт оплаты (этап оплаты — будущий эпик).
- НЕ чиним сторонние находки (register-500, стейл-тест, NBSP-lint).
---
## 7. Затрагиваемые файлы
| Файл | Действие |
|---|---|
| `app/resources/js/views/settings/RequisitesTab.vue` | правка — +блок платёжных реквизитов, +чип-статус, +валидация платёжных полей |