Чаты и поддержкамобилка вендора
Демо · эпик batele-microservices#481 · issue batele-turbo#18 · мобильная реализация batele_vendor_flutter#6
Поверхность · мобильное приложение вендора · модель v3

Чаты и поддержка в мобилке вендора

Экраны нарисованы «как влитые» в реальный batele_vendor_flutter (ветка development, монохромный ребрендинг): шрифт Inter, палитра из palette.dart (бренд/акцент = чёрный #222222), белый AppBar с заголовком слева, карточки с рамкой 1.5px и радиусом 16. Модель v3: чат не привязан к заказу — это долгоживущий канал одной пары участников (Курьер · КурСлужба · Вендор · Клиент · SuperAdmin · SuperOrg), одна пара = один чат со сквозной историей через все заказы и доставки. Контекст живёт на сообщении (orderId? / deliveryId? / ticketId?) — чип в ленте («#4821», «D-7301», «VS-102»); клик по чипу фильтрует канал. Два вида ленты: полная история пары и фильтр-режим (чип контекста в шапке, композер авто-тегирует). Участник со стороны вендора — организация: пишет любой сотрудник с правом, фиксируется senderMemberId, у исходящих видна подпись автора; ленивое создание пары сохраняется. Право доступа — vendor.chats. Полная модель — в разделе «Модель чатов».

Инбокс · «Чаты» GET /chats/threads · /support/tickets

Корневой экран с сегмент-переключателем Переписки | Поддержка. Вкладка «Переписки» — пары-каналы (не заказы): у каждой пары один долгоживущий чат, последний контекст показан чипом (#4821, D-7301). Служба — один канал на все доставки. Ленивое создание: пара появляется после первого сообщения. Вкладка «Поддержка» — тикеты контура vendor_support со статусом и SLA-таймером. Фильтр по филиалу — иконкой в AppBar. Бейджи — счётчик непрочитанного (unread).

Чаты
Переписки 3 Поддержка 2
А
Айгерим А. · клиент14:32
#4821Вы уже близко?2
Boomerang Go · служба14:14
D-7301Курьер выехал · один канал на все доставки
Бакыт Т. · курьер14:20
#4821Оставил у подъезда, спасибо!
М
Максат О. · клиент13:58
#4820Спасибо, всё получил!
Э
Эльнура С. · клиент13:12
#4817А можно без лука, пожалуйста?
инбокс · таб «Переписки» · пары-каналы + чипы контекста
Чаты
Переписки 3 Поддержка 2
VS-102open14:20
Не начислился кешбек
Айгерим А. · Лояльность06:12
VS-103pending12:05
Вопрос по брони столика
Нурзат Б. · Броньждём клиента
VS-101resolvedВчера
Опоздала доставка
Максат О. · Доставкаждёт подтв.
тикеты создают клиенты — кнопки «+» нет
инбокс · таб «Поддержка» · SLA-таймер
Размещение «Чатов». В демо — отдельная вкладка нижней навигации (Заказы · Доставки · Чаты · Настройки) со счётчиком непрочитанного. Альтернатива — вход из карточки заказа/доставки; обе точки входа ведут в один инбокс.

Тред пары GET /chats/:pairId/messages · WS

Канал пары — сквозной: вся история с собеседником через все заказы и доставки, с разделителями дат. У каждого сообщения — чип контекста (#4700, #4821), клик по нему включает фильтр-режим. Из карточки заказа открывается сегмент собеседников и фильтрованный по заказу тред: чип контекста в шапке + табы «Клиент | Служба | Курьер» с unread-бейджами (тап мгновенно переключает канал собеседника, оставаясь в контексте заказа), авто-тег композера. Входящие — белые слева, исходящие — тёмные справа с подписью автора (senderMemberId → «Айзада»); от службы — «Boomerang Go · Нурлан». Над композером — чип «Отвечаете от имени Тандыр».

А
Айгерим А.онлайн · клиент
Вчера
#4700
Заказ забрала, всё вкусно, спасибо! 🙏
20:14
#4700
Спасибо, что выбрали нас! Ждём снова 🙂
Мээрим
20:15
Сегодня
#4821
Здравствуйте! Когда примерно приедет курьер?
14:05
#4821
Здравствуйте, Айгерим! Курьер уже забрал заказ, будет у вас через 10–15 минут 🙂
Айзада
14:06
Отлично, спасибо!
14:07
Непрочитанные
#4821
Здравствуйте, а курьер уже выехал?
14:31
Вы уже близко?
14:32
Отвечаете от имени Тандыр · Центр
#4821Сообщение…
вход из заказа = вся история (чипы #4700 + #4821) · #4821 авто-тег композера
А
Айгерим А.клиент #4821

Заказ #4821

Статусв доставке
Плов «Тандыр» × 1560 с
Лагман × 1680 с
Итого1 240 с
Обсудить заказ с
Клиент 2 Служба Курьер

Откроется вся история канала (чипы #4700, #4821 в одной ленте) — фильтр не включается; контекст #4821 идёт авто-тегом в композер. Фильтр «Заказ #4821 ✕» — опционально. Ленивое создание: канал с курьером появится после первого сообщения.

контекст заказа · сегмент собеседников → фильтр по #4821
А
Айгерим А.онлайн · клиент
Клиент Служба Курьер
Заказ #4821 табы переключают собеседника в этом заказе
Показаны сообщения с контекстом #4821
Здравствуйте! Когда примерно приедет курьер?
14:05
Курьер уже забрал заказ, будет через 10–15 минут 🙂
Айзада
14:06
Отлично, спасибо!
14:07
Вы уже близко?
14:32
Отвечаете от имени Тандыр · Центр
#4821Сообщение…
фильтр-режим (опционально) · чип «#4821 ✕» фильтрует ленту · табы собеседников · дот-unread
Boomerang Goслужба доставки · один канал
Вчера
Boomerang Go · Нурлан
D-7298
Доставка D-7298 завершена, спасибо за заказ!
21:03
Сегодня
Доставка D-7301 создана
Boomerang Go · Нурлан
D-7301
Взяли вашу доставку D-7301 в работу.
14:10
Курьер назначен · Бакыт Т.
D-7301
Курьер задерживается? Клиент спрашивает, где заказ.
Айзада
14:12
Boomerang Go · Нурлан
Уже в пути, будет минут через 10. Держим на связи.
14:14
Отвечаете от имени Тандыр · Центр
Сообщение…
сквозной канал службы · чипы доставок D-7298 / D-7301

Поддержка · тикет GET /support/tickets/:id · vendor_support

Тикет vendor_support = вендор помогает своему клиенту. Технически это тот же канал Клиент ↔ Вендор, отфильтрованный по ticketId: показаны только сообщения с чипом «VS-102». Сверху — карточка тикета (статус, приоритет, категория, клиент → профиль, связанный заказ, SLA первого ответа), ниже — беседа и композер (авто-тег ticketId). Смена статуса и назначение агента — из меню в AppBar.

VS-102Лояльность · open
open высокий Лояльность
Не начислился кешбек за заказ
Первый ответ · SLAосталось 06:12
Фильтр канала Клиент ↔ Вендор по тикету VS-102
VS-102
После заказа #4821 не пришёл кешбек 33 сома на баланс. Подскажите, пожалуйста?
14:20
VS-102
Здравствуйте! Проверяю начисление по заказу, вернусь с ответом в течение 10 минут.
Айзада · агент
14:24
Отвечаете как Тандыр · поддержка · агент Айзада
VS-102Ответ клиенту…
тикет = фильтр канала по ticketId · чипы VS-102 + карточка + SLA
VS-102Лояльность · open

Статус тикета

Open сейчас
Открыт, ждёт ответа агента.
Pending
Ждём ответа клиента — SLA на паузе.
Resolved
Решено, ждёт подтверждения клиента.
Closed
Закрыт. Клиент может открыть повторно.
Назначить агента
Айзада
bottom-sheet · статус open → pending → resolved → closed

Состояния офлайн · завершённый контекст · нет права

Офлайн — сообщения в очереди (часики) отправятся автоматически при возврате сети; при сбое — ошибка и «Повторить». Завершение заказа/доставки не закрывает канал пары — контекст просто уходит в прошлое и доступен через фильтр, композер остаётся активным. Без права vendor.chats — заглушка вместо инбокса.

А
Айгерим А.был(а) недавно · клиент
Нет соединения — сообщения отправятся автоматически
Вы уже близко?
14:32
Курьер будет через 10 минут 🙂
Айзада
14:33
Уже на вашей улице
Айзада
14:33
Не отправлено · Повторить
Сообщение…
офлайн · очередь (часики) + ошибка + «Повторить»
Н
Нургуль К.клиент · был(а) вчера
Заказ #4736 · завершён канал остаётся открыт
Заказ #4736 завершён · это фильтр по контексту, не архив
#4736
Заказ получила, всё вкусно 🙏
Пн, 19:41
#4736
Спасибо, что выбрали нас! Ждём снова 🙂
Айзада
Пн, 19:42
Отвечаете от имени Тандыр · Центр
Сообщение…
завершённый контекст · фильтр, не архив · канал пары открыт
Чаты

Недоступно для вашей роли

Попросите администратора включить право «Чаты» в вашей роли — тогда здесь появятся каналы с клиентами, службами и курьерами и тикеты поддержки.

право vendor.chats
нет права · заглушка вместо инбокса
Право «Чаты» — новое в каталоге прав. Добавляется как vendor.chats; на существующие роли автоматически не бэкфиллится — админ включает его вручную там, где нужно. До включения экран «Чаты» показывает заглушку выше.

Модель чатов — коротко эпик batele-microservices#481

Ключевые правила. Полная спецификация контуров, событий и прав — в задаче эпика и issue batele-turbo#18.

Канал = пара, не заказ

Чат — долгоживущий канал между парой участников (Курьер · КурСлужба · Вендор · Клиент · SuperAdmin · SuperOrg). Одна пара = один чат со сквозной историей через все заказы и доставки.

Контекст на сообщении

У сообщения — orderId? / orderShortId? / deliveryId? / ticketId? → чип в ленте («#4821», «D-7301», «VS-102»). Клик по чипу фильтрует канал по контексту.

Два вида ленты

Полная история пары (чипы на сообщениях) или фильтр-режим: чип контекста в шапке «Заказ #4821 ✕», только его сообщения, композер авто-тегирует новые сообщения этим контекстом.

Вендор = организация

Со стороны вендора участник — организация: пишет любой сотрудник с правом, фиксируется senderMemberId, у исходящих видна подпись автора. Ленивое создание: пара появляется при первом сообщении.

Тикет = фильтр канала

Контур vendor_support: тикет — тот же канал Клиент ↔ Вендор, отфильтрованный по ticketId. Статусы open / pending / resolved / closed, SLA первого ответа, агенты = сотрудники.

Realtime, право, контексты

По WebSocket: typing, read, presence, unread; офлайн → push. Право vendor.chats (новое, без бэкфилла). Завершение заказа не закрывает канал — контекст доступен через фильтр.

Демо UI/UX. Экраны нарисованы под нативные паттерны batele_vendor_flutter (ветка development). Реализация мобилки — batele_vendor_flutter#6, бэкенд — эпик batele-microservices#481.