feat(social): друзья, личные беседы, присутствие, аватары и часовой пояс
По запросу пользователя (вне очереди AGENT.md §13): - главного сервера как точки входа больше нет: новичок начинает с пустым списком серверов, вход — только по приглашению или созданием своего; - друзья: поиск по логину с экранированием LIKE, заявки (POST /users/@me/relationships), принятие, удаление/отклонение, списки friends/ incoming/outgoing/blocked; - личные беседы: POST /users/@me/channels (идемпотентно), GET /users/@me/channels со собеседником, статусом и последним сообщением; сообщения в DM работают через общие ручки комнат, доступ — только участникам (посторонний получает 404, события в Gateway тоже фильтруются); - присутствие: last_seen_at обновляется при активности, «невидимка» и простой дольше двух минут выглядят как офлайн, смена статуса рассылает PRESENCE_UPDATE друзьям; - READY отдаёт dm_channels (собеседник, аватар, статус, последнее сообщение); - профиль: timezone (по умолчанию Europe/Moscow) в PATCH /users/@me, загрузка аватара POST /users/@me/avatar (проверка, что это изображение, в том числе по содержимому) и удаление DELETE /users/@me/avatar; старый файл удаляется с диска; - тесты: заявки в друзья, личные беседы и их изоляция, «невидимка», часовой пояс и аватар, PRESENCE_UPDATE другу, отсутствие событий DM у постороннего.
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
-- +goose Up
|
||||
-- Фаза 4 (по запросу): друзья, личные беседы, присутствие и часовой пояс.
|
||||
|
||||
CREATE TABLE relationships (
|
||||
user_id INTEGER NOT NULL REFERENCES users (id) ON DELETE CASCADE,
|
||||
target_id INTEGER NOT NULL REFERENCES users (id) ON DELETE CASCADE,
|
||||
-- friend | outgoing (заявка отправлена) | incoming (заявка получена) | blocked
|
||||
type TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
||||
updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
||||
PRIMARY KEY (user_id, target_id)
|
||||
);
|
||||
CREATE INDEX relationships_type_idx ON relationships (user_id, type);
|
||||
CREATE INDEX relationships_target_idx ON relationships (target_id, type);
|
||||
|
||||
-- Участники личной беседы: канал типа dm без сервера (AGENT.md 7.8).
|
||||
CREATE TABLE dm_participants (
|
||||
channel_id INTEGER NOT NULL REFERENCES channels (id) ON DELETE CASCADE,
|
||||
user_id INTEGER NOT NULL REFERENCES users (id) ON DELETE CASCADE,
|
||||
joined_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
||||
PRIMARY KEY (channel_id, user_id)
|
||||
);
|
||||
CREATE INDEX dm_participants_user_idx ON dm_participants (user_id);
|
||||
|
||||
-- Присутствие: когда пользователя видели в последний раз и его часовой пояс
|
||||
-- для показа времени друзьям.
|
||||
ALTER TABLE users ADD COLUMN last_seen_at TEXT;
|
||||
ALTER TABLE users ADD COLUMN timezone TEXT NOT NULL DEFAULT 'Europe/Moscow';
|
||||
|
||||
-- +goose Down
|
||||
ALTER TABLE users DROP COLUMN timezone;
|
||||
ALTER TABLE users DROP COLUMN last_seen_at;
|
||||
DROP TABLE dm_participants;
|
||||
DROP TABLE relationships;
|
||||
Reference in New Issue
Block a user