Закрыты задачи бэклога по неочевидному поведению UI при ошибках отправки сообщений и блокировках со стороны Message-safety + добалено ограничение на размер сообщения
This commit is contained in:
@@ -243,6 +243,7 @@ Pydantic `422` преобразуется в `400 validation_error`, чтобы
|
||||
{
|
||||
"auth": {"phone_enabled": true, "password_enabled": false},
|
||||
"operator": {"call_phone": "+74999591007"},
|
||||
"messages": {"max_text_length": 4000},
|
||||
"consents": {
|
||||
"personal_data": {
|
||||
"required": true,
|
||||
@@ -429,7 +430,7 @@ Success `201` возвращает финальный `MessageResponse`:
|
||||
}
|
||||
```
|
||||
|
||||
На safety deny — `422 message_blocked`; blocked message допустимо сохранять для аудита, но его текст должен храниться по политике минимизации данных (см. решение M8). На dependency failure — `503/504`; если Message уже создан, его `delivery_status=failed`.
|
||||
На safety deny — `422 message_blocked`; blocked message допустимо сохранять для аудита, но его текст должен храниться по политике минимизации данных (см. решение M8). В той же транзакции backend создаёт отдельную локальную `company`-реплику с безопасным бизнес-текстом для сообщения или документа; эта реплика публикуется в realtime, но не отправляется в Open Lines. На dependency failure — `503/504`; если Message уже создан, его `delivery_status=failed`.
|
||||
|
||||
### 6.7. Attachments
|
||||
|
||||
|
||||
@@ -55,7 +55,8 @@ frontend-test-site/
|
||||
| PKCE verifier/state/nonce | session storage, короткий TTL | одноразовые, проверяются callback |
|
||||
| `ux_session_id`, `last_activity_at` | только память | не localStorage |
|
||||
| `guest_session_id` | локально, опционально | не auth, не посылается как право доступа |
|
||||
| pending message/file intent | память | восстанавливает отправку после OTP |
|
||||
| pending text intent | session storage, до терминального send outcome | восстанавливает отправку после OIDC redirect |
|
||||
| pending file intent | память | переносит выбранный `File` с главной в чат без сериализации |
|
||||
| REST cursors | память по dialog | opaque, не парсить |
|
||||
|
||||
Auth state machine: `guest → authorizing → bootstrapping → authenticated`; при refresh failure — обратно `guest`. UX-сессия независима от Keycloak-сессии.
|
||||
@@ -106,7 +107,7 @@ Readonly блок «Личные данные» из `GET /me`; блок «До
|
||||
3. При успехе определить новую UX-сессию (`cold_start` при новом page lifecycle), вызвать `session-start`, затем загрузить profile/dialogs.
|
||||
4. При отсутствии/истечении refresh token оставаться guest до protected action.
|
||||
5. После OTP callback проверить `state`/`nonce`, обменять code с PKCE, вызвать `POST /auth/bootstrap` с согласиями и device metadata.
|
||||
6. Создать UX-сессию, если её нет; затем продолжить pending intent.
|
||||
6. Создать UX-сессию, если её нет, завершить auth-экран и перейти в чат; pending intent отправляется уже экраном чата. Ошибка Message Safety/Bitrix не превращается в ошибку bootstrap.
|
||||
|
||||
Bootstrap повторяем безопасно после неопределённого сетевого результата. Телефон в body никогда не передаётся.
|
||||
|
||||
@@ -142,10 +143,11 @@ Bootstrap повторяем безопасно после неопределё
|
||||
|
||||
1. Валидировать непустой нормализованный текст и клиентский max length из контракта.
|
||||
2. Если guest — сохранить intent, consent → OTP → bootstrap → session-start.
|
||||
3. `POST /dialogs` с idempotency key, сохранить `dialog_id`.
|
||||
4. `POST /dialogs/{id}/messages` с отдельным key.
|
||||
3. `POST /dialogs` с idempotency key, сохранить `dialog_id` и перейти на экран чата до отправки.
|
||||
4. Экран чата выполняет `POST /dialogs/{id}/messages` с отдельным стабильным key.
|
||||
5. Блокировать повторный click только для того же intent; другие действия не замораживать.
|
||||
6. На `201` merge `MessageResponse`; на `422 message_blocked` показать безопасный текст без повтора; на `503/504` предложить retry с тем же key.
|
||||
6. На `201` merge `MessageResponse`; на `422 message_blocked` не показывать красную техническую ошибку, а обновить историю с сохранённой backend `company`-репликой; на `503/504` предложить retry с тем же key.
|
||||
7. Composer показывает счётчик `n/max`, где `max` приходит как `messages.max_text_length` из public app-config; сверх лимита отправка блокируется без обрезки ввода.
|
||||
|
||||
## 11. Файловый flow
|
||||
|
||||
|
||||
Reference in New Issue
Block a user