9.7 KiB
9.7 KiB
Анонс для исполнителя (кратко)
Ниже описан текущий статус ветки по функциям:
- PWA + FCM уведомления
- личные сообщения (вторая слева вкладка, "Личные сообщения")
- связи / близкие друзья (центральная вкладка)
- server-push события (в том числе закрытие сессии)
Что нужно проверить и довести до рабочего состояния
- PWA/FCM: регистрация service worker, получение FCM token, отправка token на сервер, получение foreground/background уведомлений.
- Личные сообщения: отправка первого сообщения любому пользователю, входящие по WS, ACK, fallback в FCM, дедупликация на клиенте.
- Связи / близкие друзья: поиск пользователя, добавление в близкие, обновление графа связей сразу после добавления.
- SessionRevoked: если сессию закрыли с другого устройства, клиент должен корректно завершить локальную сессию и показать понятное состояние.
Главная цель handoff
Сделать так, чтобы все описанные сценарии стабильно работали end-to-end без ручных "подпинок".
Подробное ТЗ и технические детали
1) Архитектура протокола и общие принципы
1.1 Формат обмена
Используется JSON-over-WebSocket.
- Для запрос-ответ:
op + requestId + payload - Для server-push событий: те же поля, но
event=true,requestIdиспользуется как eventId.
1.2 ID сообщений/событий
ID генерируются в формате:
prefix-yyyyMMdd-HHmmss-SSS-random10
Реализация: NetIdGenerator.
1.3 Роли каналов доставки
- WS — приоритетная доставка в активные сессии.
- FCM — fallback, если ACK по WS не получен или WS-сессия отсутствует.
2) PWA + FCM
2.1 Что уже добавлено
Клиент
shine-UI/manifest.webmanifestshine-UI/firebase-messaging-sw.jsshine-UI/js/services/pwa-push-service.jsshine-UI/index.htmlсодержит placeholders:window.__SHINE_FIREBASE_CONFIG__window.__SHINE_FIREBASE_VAPID_KEY__
Сервер
- API
UpsertPushToken - Таблица
user_push_tokens - Серверный FCM sender (legacy HTTP):
FcmPushSender - Конфиг:
fcm.server.keyвapplication.properties
2.2 Как должно работать (целевое поведение)
- Клиент после авторизации регистрирует SW.
- Просит permission на notifications.
- Получает FCM token.
- Если token новый/изменился — отправляет
UpsertPushToken. - Сервер сохраняет token за конкретной сессией.
2.3 Что проверить/доделать
- Синхронизация Firebase config между
index.htmlиfirebase-messaging-sw.js. - Работа iOS Safari (PWA через Home Screen).
- Поведение при смене token.
- Надёжность
FcmPushSender(таймауты, логирование ошибок ответа).
3) Вторая слева вкладка: Личные сообщения / Чаты
3.1 Продуктовая логика (как должно быть)
- Открытие списка диалогов на вкладке "Личные сообщения".
- Кнопка
+открывает поиск пользователя по префиксу логина (SearchUsers). - Первое сообщение можно отправить любому пользователю, даже если он не контакт.
- Если пользователь не в контактах — в чате показывается действие "Добавить в контакты".
- Входящее сообщение может прийти:
- напрямую по WS (
IncomingDirectMessage) - через FCM (fallback)
- напрямую по WS (
- На клиенте дедупликация должна быть по
messageId.
3.2 Что уже сделано технически
Сервер
SendDirectMessageAckIncomingMessagedirect_messagesтаблица + DAO- доставка по активным WS-сессиям + ожидание ACK + fallback в FCM
Клиент
authService.sendDirectMessage(...)authService.ackIncomingMessage(...)- WS client поддерживает server events (
onEvent) - В
app.jsобработкаIncomingDirectMessage - В
state.jsдобавленыincomingDedup,addIncomingMessage
3.3 Что глючит/что проверить
- Стабильность отображения новых чатов, если сообщение пришло от неизвестного пользователя.
- Согласованность списка диалогов и фактических сообщений.
- Поведение при быстрых дубликатах WS + FCM.
- Поведение при сетевых обрывах/повторном коннекте.
4) Центральная вкладка: Связи / Близкие друзья
4.1 Целевое поведение
- Экран "Связи" загружает граф друзей (
GetUserConnectionsGraph). - Кнопка "Добавить близкого друга" открывает модалку:
- поле логина/префикса
- кнопка "Поиск"
- кнопка "Назад"
- Поиск идёт через
SearchUsers. - По клику на найденного — подтверждение "Добавить? Да/Нет".
- При "Да" вызывается
AddCloseFriend, после успеха:- закрыть модалку
- вернуться на экран связей
- обновить граф.
4.2 Что уже сделано
- UI-flow модалки реализован на
network-view.js. - API
AddCloseFriendдобавлен на сервере. ConnectionsStateDAO.upsertRelation(...)добавлен для upsert связи FRIEND.
4.3 Что проверить/доделать
- Валидация edge-cases (добавление самого себя, несуществующий логин).
- Корректность отрисовки графа после добавления.
- Согласованность данных с будущей "настоящей" записью в blockchain (сейчас MVP upsert в
connections_state).
5) SessionRevoked и мультисессии
5.1 Целевое поведение
Если с другой сессии закрыли текущую сессию:
- сервер шлёт событие
SessionRevoked - клиент чистит локальную авторизацию
- клиент возвращается в состояние неавторизованного входа.
5.2 Что проверить
- Что событие приходит до закрытия socket.
- Что UX не "зависает" на промежуточном экране.
6) API-операции (быстрый список)
Уже используемые/добавленные в ветке
SearchUsersListContactsGetUserConnectionsGraphAddCloseFriendUpsertPushTokenSendDirectMessageAckIncomingMessageCloseActiveSession(с server eventSessionRevoked)
7) Минимальный чек-лист тестирования для нового исполнителя
- Авторизация пользователя A и B в разных браузерах/устройствах.
- A отправляет первое сообщение B (без контактов) — должно уйти.
- B получает по WS, отправляется ACK, fallback FCM не должен дублировать.
- Выключить WS у B и проверить fallback FCM.
- Вкладка "Связи": добавить близкого друга через поиск, проверить обновление графа.
- Закрыть сессию B с другого устройства и проверить
SessionRevokedUX. - Перезапуск клиента: проверка повторной регистрации push-токена только при изменении.
8) Важное ограничение текущей реализации
Некоторые части реализованы как MVP и требуют стабилизации:
- местами UI/состояние могут рассинхронизироваться;
- fallback WS->FCM может требовать донастройки таймингов и ретраев;
AddCloseFriendсейчас пишет прямое состояние связи (upsert), а не полный blockchain-поток создания блоков.
Это ожидаемо для handoff: задача следующего исполнителя — довести до production-стабильности.