This commit is contained in:
lendry
2026-06-25 08:31:36 +03:00
parent 71b270fcb3
commit 933f7fb9e1
22 changed files with 1871 additions and 620 deletions

View File

@@ -838,8 +838,8 @@ curl -X POST http://localhost:3000/auth/otp/verify \\
},
{
slug: 'sessions',
title: 'Сессии и PIN',
description: 'Управление устройствами, PIN-блокировка и отзыв сессий.',
title: 'Сессии, PIN и удаление аккаунта',
description: 'Управление устройствами, PIN-блокировка, отзыв сессий и отложенное удаление профиля.',
sections: [
{
id: 'totp',
@@ -866,6 +866,46 @@ curl -X POST http://localhost:3000/auth/otp/verify \\
{
type: 'paragraph',
text: 'PIN хранится как bcrypt hash. Таймаут блокировки читается из SystemSetting PIN_LOCK_TIMEOUT_MINUTES — значение не захардкожено во frontend.'
},
{
type: 'list',
items: [
'PIN_DELETE_GRACE_MINUTES — задержка перед окончательным удалением PIN после запроса',
'PIN_REQUIRE_ON_DELETE — требовать текущий PIN при запросе удаления защиты'
]
}
]
},
{
id: 'account-deletion',
title: 'Удаление аккаунта',
blocks: [
{
type: 'paragraph',
text: 'Пользователь может запланировать удаление профиля в личном кабинете: раздел «Данные» (/data) → «Удалить профиль». Аккаунт не удаляется мгновенно — начинается период ожидания, настраиваемый администратором.'
},
{
type: 'table',
headers: ['Ключ SystemSetting', 'Описание', 'По умолчанию'],
rows: [
['ACCOUNT_DELETE_GRACE_DAYS', 'Через сколько дней после запроса окончательно удалить аккаунт', '30']
]
},
{
type: 'list',
items: [
'POST /profile/users/{userId}/self-delete — запланировать удаление (только свой профиль)',
'GET /profile/users/{userId}/self-delete/status — дата окончательного удаления и статус pending',
'POST /profile/users/{userId}/self-delete/cancel — отменить запрос до истечения срока',
'До истечения срока пользователь может входить и пользоваться сервисом как обычно',
'На странице /data отображается предупреждение с датой удаления и кнопкой отмены'
]
},
{
type: 'callout',
variant: 'warning',
title: 'Что происходит при финализации',
text: 'Фоновый планировщик sso-core (каждые 5 минут) находит аккаунты с истёкшим сроком ожидания и выполняет soft-delete: анонимизация email/телефона/username, отзыв сессий, снятие ролей. Семьи, где пользователь — создатель, удаляются полностью (участники, чаты, медиа). Из остальных семей пользователь исключается.'
}
]
},
@@ -888,7 +928,7 @@ curl -X POST http://localhost:3000/auth/otp/verify \\
{
slug: 'family-chat',
title: 'Семья и чат',
description: 'Семейные группы, приглашения, чат и realtime через WebSocket.',
description: 'Семейные группы, приглашения, чат, удаление семьи и realtime через WebSocket.',
sections: [
{
id: 'family',
@@ -896,7 +936,61 @@ curl -X POST http://localhost:3000/auth/otp/verify \\
blocks: [
{
type: 'paragraph',
text: 'Пользователь создаёт семью, приглашает участников по email/телефону/логину. Лимиты (max family members) берутся из SystemSetting.'
text: 'Пользователь создаёт семью, приглашает участников по email/телефону/логину или через поиск в интерфейсе. Лимит участников задаётся в SystemSetting MAX_FAMILY_MEMBERS (по умолчанию 6). При создании семьи автоматически создаётся общий чат «Общий чат».'
},
{
type: 'list',
items: [
'POST /family/groups — создать семью',
'GET /family/users/{userId}/groups — список семей пользователя',
'PATCH /family/groups/{groupId} — переименовать (только участники, название — создатель)',
'POST /family/groups/{groupId}/invites — отправить приглашение',
'GET /family/groups/{groupId}/invite-search?q=... — поиск пользователей для приглашения'
]
}
]
},
{
id: 'family-leave',
title: 'Выход и исключение участников',
blocks: [
{
type: 'paragraph',
text: 'Участник может выйти из семьи самостоятельно; создатель семьи может исключить любого участника, кроме себя. При выходе или исключении пользователь удаляется из всех чатов этой семьи.'
},
{
type: 'list',
items: [
'DELETE /family/members/{memberId} — выход (если memberId свой) или исключение (если запрос от создателя семьи)',
'Создателя семьи (role: owner) удалить через этот endpoint нельзя — только удалить всю семью целиком'
]
}
]
},
{
id: 'family-delete',
title: 'Удаление семьи',
blocks: [
{
type: 'paragraph',
text: 'Только создатель семьи может полностью удалить группу. В интерфейсе: страница семьи → «Участники семьи» → «Удалить семью». Действие необратимо.'
},
{
type: 'list',
items: [
'DELETE /family/groups/{groupId} — удалить семью (только ownerId === текущий пользователь)',
'Все участники исключаются из семьи',
'Все приглашения (FamilyInvite) удаляются',
'Все чаты семьи (ChatRoom), сообщения, опросы и голоса удаляются каскадом',
'Медиа в MinIO (аватар семьи, аватары чатов, вложения сообщений) удаляются best-effort',
'Остальным участникам отправляется уведомление family_group_deleted и событие WebSocket'
]
},
{
type: 'callout',
variant: 'warning',
title: 'Без передачи владения',
text: 'Перед удалением семьи нельзя «передать» роль создателя другому участнику — только полное удаление группы или выход участников по отдельности.'
}
]
},
@@ -909,7 +1003,8 @@ curl -X POST http://localhost:3000/auth/otp/verify \\
items: [
'REST: /chat/groups/{groupId}/rooms, /chat/rooms/{roomId}/messages',
'WebSocket: ws://localhost:8085/ws с JWT в query или заголовке',
'Медиа чата: presigned upload + защищённый stream с Authorization'
'Медиа чата: presigned upload + защищённый stream с Authorization',
'События realtime: chat_message, chat_message_updated, chat_message_deleted, family_group_deleted'
]
}
]