SHiNE-server/TASKS/CHAT_PWA_HANDOFF.md
AidarKC 9cbff47194 Добавил массовое тестовое заполнение через API: A1..A10 и дружеские связи
- Переименован тест в Seed_TestDataPopulation (не IT_07_*)\n- Тест создаёт пользователей A1..A10 через AddUser\n- Дружеские связи формируются через AddBlock (CONNECTION_FRIEND)\n- Добавлен контроль количества друзей (A1=5, A2=7, A3=3)\n- Тест включён в обязательный запуск всех IT и в suite\n- Обновлена TASKS-документация по тестовым логинам
2026-04-06 10:28:22 +03:00

204 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Анонс для исполнителя (кратко)
Ниже описан текущий статус ветки по функциям:
- PWA + FCM уведомления
- личные сообщения (вторая слева вкладка, "Личные сообщения")
- связи / близкие друзья (центральная вкладка)
- server-push события (в том числе закрытие сессии)
## Что нужно проверить и довести до рабочего состояния
1. **PWA/FCM**: регистрация service worker, получение FCM token, отправка token на сервер, получение foreground/background уведомлений.
2. **Личные сообщения**: отправка первого сообщения любому пользователю, входящие по WS, ACK, fallback в FCM, дедупликация на клиенте.
3. **Связи / близкие друзья**: поиск пользователя, добавление в близкие, обновление графа связей сразу после добавления.
4. **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.webmanifest`
- `shine-UI/firebase-messaging-sw.js`
- `shine-UI/js/services/pwa-push-service.js`
- `shine-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 Как должно работать (целевое поведение)
1. Клиент после авторизации регистрирует SW.
2. Просит permission на notifications.
3. Получает FCM token.
4. Если token новый/изменился — отправляет `UpsertPushToken`.
5. Сервер сохраняет token за конкретной сессией.
## 2.3 Что проверить/доделать
- Синхронизация Firebase config между `index.html` и `firebase-messaging-sw.js`.
- Работа iOS Safari (PWA через Home Screen).
- Поведение при смене token.
- Надёжность `FcmPushSender` (таймауты, логирование ошибок ответа).
---
## 3) Вторая слева вкладка: Личные сообщения / Чаты
## 3.1 Продуктовая логика (как должно быть)
1. Открытие списка диалогов на вкладке "Личные сообщения".
2. Кнопка `+` открывает поиск пользователя по префиксу логина (`SearchUsers`).
3. **Первое сообщение можно отправить любому пользователю**, даже если он не контакт.
4. Если пользователь не в контактах — в чате показывается действие "Добавить в контакты".
5. Входящее сообщение может прийти:
- напрямую по WS (`IncomingDirectMessage`)
- через FCM (fallback)
6. На клиенте дедупликация должна быть по `messageId`.
## 3.2 Что уже сделано технически
### Сервер
- `SendDirectMessage`
- `AckIncomingMessage`
- `direct_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 Целевое поведение
1. Экран "Связи" загружает граф друзей (`GetUserConnectionsGraph`).
2. Кнопка "Добавить близкого друга" открывает модалку:
- поле логина/префикса
- кнопка "Поиск"
- кнопка "Назад"
3. Поиск идёт через `SearchUsers`.
4. По клику на найденного — подтверждение "Добавить? Да/Нет".
5. При "Да" вызывается `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 Целевое поведение
Если с другой сессии закрыли текущую сессию:
1. сервер шлёт событие `SessionRevoked`
2. клиент чистит локальную авторизацию
3. клиент возвращается в состояние неавторизованного входа.
## 5.2 Что проверить
- Что событие приходит до закрытия socket.
- Что UX не "зависает" на промежуточном экране.
---
## 6) API-операции (быстрый список)
### Уже используемые/добавленные в ветке
- `SearchUsers`
- `ListContacts`
- `GetUserConnectionsGraph`
- `AddCloseFriend`
- `UpsertPushToken`
- `SendDirectMessage`
- `AckIncomingMessage`
- `CloseActiveSession` (с server event `SessionRevoked`)
---
## 7) Минимальный чек-лист тестирования для нового исполнителя
1. Авторизация пользователя A и B в разных браузерах/устройствах.
2. A отправляет первое сообщение B (без контактов) — должно уйти.
3. B получает по WS, отправляется ACK, fallback FCM не должен дублировать.
4. Выключить WS у B и проверить fallback FCM.
5. Вкладка "Связи": добавить близкого друга через поиск, проверить обновление графа.
6. Закрыть сессию B с другого устройства и проверить `SessionRevoked` UX.
7. Перезапуск клиента: проверка повторной регистрации push-токена только при изменении.
---
## 8) Важное ограничение текущей реализации
Некоторые части реализованы как MVP и требуют стабилизации:
- местами UI/состояние могут рассинхронизироваться;
- fallback WS->FCM может требовать донастройки таймингов и ретраев;
- `AddCloseFriend` сейчас пишет прямое состояние связи (upsert), а не полный blockchain-поток создания блоков.
Это ожидаемо для handoff: задача следующего исполнителя — довести до production-стабильности.
---
## 9) Тестовые логины для быстрой проверки
Для проверки работы системы можно использовать специальные тестовые аккаунты
после выполнения теста `Seed_TestDataPopulation` (он создаёт их через API):
- `A1`
- `A2`
- `A3`
- `A4`
- `A5`
- `A6`
- `A7`
- `A8`
- `A9`
- `A10`
Общий пароль для этих аккаунтов:
- `1`