ci / module boundaries / boundaries (push) Successful in 7s
ci / api / api (push) Successful in 1m9s
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 1m8s
ci / contract / contract (сгенерированный код совпадает с openapi.yaml) (push) Successful in 1m23s
ci / db / db (push) Successful in 2m29s
ci / ts / ts (packages + web) (push) Successful in 2m55s
59 lines
5.8 KiB
Markdown
59 lines
5.8 KiB
Markdown
# Друзья, сообщения и уведомления
|
|
|
|
Социальные функции работают между пользователями одного сервера. В web и desktop
|
|
открывается раздел «Друзья и общение», на Android — вкладка «Друзья».
|
|
|
|
## Поведение
|
|
|
|
- Поиск по логину и отображаемому имени начинается с двух символов, возвращает до 30 человек.
|
|
Пароли, роли, настройки и другие приватные поля в результат не попадают.
|
|
- Заявка требует явного принятия получателем. Встречная заявка не принимает дружбу автоматически.
|
|
Можно отменить свою заявку, отклонить входящую или удалить друга.
|
|
- Личные сообщения и отправка музыки доступны только текущим друзьям. Блокировка прекращает
|
|
дружбу и закрывает общение в обоих направлениях. Разблокировка дружбу не восстанавливает.
|
|
- История сохраняется после удаления друга, но доступна снова только после новой взаимной дружбы.
|
|
В первой странице чата — последние 50 сообщений; ранние подгружаются отдельно.
|
|
- В сообщении до 4000 символов. Музыкальное вложение — ID трека либо действующая ссылка
|
|
общего доступа к плейлисту. Отзыв ссылки делает вложенный плейлист недоступным.
|
|
- «Поделиться» открывает выбор: скопировать ссылку, вызвать системную отправку (когда она
|
|
поддерживается клиентом) или отправить конкретному другу одним нажатием. Отправка другу
|
|
создаёт сообщение с музыкальным вложением. Повтор после сетевого сбоя использует тот же UUID.
|
|
|
|
## Спокойные уведомления
|
|
|
|
Четыре типа: входящая заявка, принятие заявки, личное сообщение, музыка.
|
|
Центр событий и счётчики сохраняются на сервере, отметки прочтения общие для устройств.
|
|
Нет звуков, автоматических всплывающих окон и запроса разрешений ОС.
|
|
|
|
Список уведомлений возвращает до 100 событий, сначала непрочитанные. По мере подтверждения
|
|
новых становятся доступны более старые непрочитанные события. Открытый видимый чат подтверждает
|
|
сообщения только до последнего полученного номера; более поздние сообщения не теряются.
|
|
В скрытой вкладке и в фоне Android автоматического подтверждения нет.
|
|
|
|
Сейчас это уведомления **внутри работающего приложения**, с обновлением центра каждые 15 секунд
|
|
и открытого чата каждые 8 секунд. Web использует стандартную приостановку фонового polling
|
|
React Query; Android останавливает polling при уходе приложения в фон. Уведомления ОС при
|
|
закрытом клиенте (Web Push/FCM/нативный desktop) в эту реализацию не входят.
|
|
|
|
## Реализация и проверки
|
|
|
|
Контракт: `api/openapi.yaml`, операции `getSocial`, `searchPeople`, `socialAction`,
|
|
`getDirectMessages`, `sendDirectMessage`. Модуль API: `internal/social`.
|
|
Миграция `00019_social.sql` создаёт дружбу, блокировки, сообщения и уведомления.
|
|
Миграции применяются штатным запуском API.
|
|
|
|
Мутации пары сериализованы транзакционной advisory-блокировкой PostgreSQL. Отправка сообщения
|
|
и создание уведомления атомарны. UUID сообщения глобально уникален; повтор с другим содержимым
|
|
возвращает конфликт. Чужое уведомление нельзя отметить прочитанным. Поиск скрывает заблокированные
|
|
аккаунты и личные блокировки, включая обратное направление.
|
|
|
|
Ограничения: до 50 исходящих ожидающих заявок, до 10 новых заявок за минуту,
|
|
до 30 сообщений одному человеку за минуту; тело социального POST ограничено 32 KiB.
|
|
Тексты выводятся обычным текстом, вложения формируют только внутренние маршруты каталога.
|
|
|
|
Проверки: `go test ./internal/social`,
|
|
`TEST_DATABASE_URL=… go test -tags integration ./internal/social`,
|
|
`pnpm --filter @pipu/web test src/App.test.tsx -t 'social|playlist sharing'`,
|
|
`pnpm --filter @pipu/web test:e2e e2e/social.spec.ts e2e/playlists.spec.ts`.
|
|
Интеграционный сценарий включён в `ci-db`.
|