Files
2026-07-03 22:39:48 +03:00

883 lines
32 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.
# ТЗ: мессенджер в стиле Икар
## Назначение документа
Этот документ является техническим заданием для нейросети или команды разработки, которой нужно создать полноценный мессенджер, функционально и визуально близкий к проекту Икар.
Цель: получить современный мобильный мессенджер с серверной частью, Android-клиентом, real-time сообщениями, медиа-вложениями, звонками, сторис, ботами, каналами, группами, push-уведомлениями, настройками приватности, админкой и механизмом обновления приложения.
Документ нужно читать как product + engineering brief. Если какие-то детали не указаны явно, нужно выбирать решения, близкие к Telegram-подобному пользовательскому опыту: быстрый чат, аккуратные пузырьки, плотная мобильная навигация, удобные вложения, плавная работа с медиа и надежная доставка сообщений.
## Рабочее название
Икар.
## Ключевая идея
Икар - это самостоятельный мессенджер с мобильным Android-клиентом и собственным сервером. Он должен поддерживать личные чаты, группы, каналы, медиа, звонки, сторис, ботов и обновления клиента через собственный каталог релизов.
Пользователь должен воспринимать приложение как быстрый, легкий и приватный мессенджер:
- открыл приложение;
- увидел список чатов;
- вошел в чат;
- написал текст;
- отправил фото, видео, файл или голосовое;
- получил push;
- открыл фото на весь экран;
- позвонил;
- настроил приватность;
- обновил приложение через встроенный механизм.
## Платформы
Минимальный обязательный состав:
- Backend: ASP.NET Core Web API.
- Realtime: SignalR или аналогичный WebSocket transport.
- Android client: Kotlin + Jetpack Compose.
- Storage: локальное файловое хранилище на сервере для вложений и аватаров.
- Database: реляционная БД через ORM, желательно Entity Framework Core или аналог.
- Push: Firebase Cloud Messaging.
- Admin UI: веб-админка, доступная через сервер.
- Distribution: публикация Android APK через каталог обновлений Argus-like.
Дополнительно допустимо:
- Docker-окружение для сервера.
- Отдельный shared-модуль с контрактами API.
- Локальный кэш сообщений и вложений на Android.
## Главные пользовательские сценарии
### Регистрация и вход
Пользователь должен иметь возможность:
- зарегистрироваться по номеру телефона;
- войти по номеру телефона через одноразовый код;
- войти или подтвердить аккаунт через email-код;
- получить JWT/access token;
- восстановить сессию после перезапуска приложения;
- выйти из аккаунта;
- видеть список активных устройств;
- завершать сессии на других устройствах.
В dev/smoke окружении можно использовать тестовые коды, но в production нужно иметь реальную отправку SMS/email или подключаемые провайдеры.
### Профиль пользователя
Пользователь должен иметь:
- display name;
- username или публичный идентификатор, если нужен;
- avatar;
- about/status;
- настройки приватности;
- настройки уведомлений;
- настройки интерфейса чатов.
Нужно поддерживать загрузку аватара с Android-клиента, хранение на сервере и отдачу с авторизацией.
### Список чатов
Главный экран после авторизации - список чатов.
В списке чатов должны отображаться:
- аватар чата или пользователя;
- название;
- последний текст или превью вложения;
- дата/время последнего сообщения;
- бейдж непрочитанных;
- индикатор pinned/muted/archived, если реализовано;
- превью фото для последнего медиа-сообщения;
- статус онлайн для личных чатов.
Список должен обновляться в real-time при новых сообщениях.
### Личные чаты
Пользователь должен иметь возможность:
- создать личный чат с другим пользователем;
- отправлять текст;
- отправлять вложения;
- отвечать на сообщение;
- пересылать сообщение;
- копировать текст;
- удалять сообщение;
- редактировать свое сообщение;
- ставить реакции;
- искать по сообщениям;
- видеть статус доставки.
Статусы доставки:
- sending;
- sent;
- delivered;
- read;
- failed.
### Группы
Групповой чат должен поддерживать:
- создание группы;
- добавление участников;
- удаление участников;
- роли участников;
- права отправки сообщений;
- название и аватар группы;
- список участников;
- уведомления;
- поиск;
- media/materials view.
Минимальные роли:
- owner;
- admin;
- member.
### Каналы
Каналы должны отличаться от групп:
- подписчики читают публикации;
- писать могут только владелец/админы;
- у публикаций могут быть просмотры;
- у публикаций могут быть комментарии через discussion group;
- канал может иметь invite link;
- канал может быть публичным или приватным.
Для каналов нужны:
- создание канала;
- управление участниками/подписчиками;
- публикация постов;
- пересылка постов;
- счетчик просмотров;
- переход в обсуждение.
### Сообщения
Сообщение должно поддерживать:
- id;
- chatId;
- sender;
- text;
- sentAt;
- editedAt;
- deletedAt;
- replyTo;
- forwardedFrom;
- attachments;
- reactions;
- deliveryState;
- hasProtectedContent;
- viewCount для каналов;
- discussionMessageId для каналов;
- mediaAlbumId для альбомов.
Текст должен поддерживать:
- переносы строк;
- ссылки;
- inline preview для ссылок на изображения;
- spoiler-style разметку, если реализуется;
- большие emoji-сообщения, если сообщение состоит только из 1-3 emoji.
### Вложения
Нужно поддерживать вложения:
- изображения: jpg, jpeg, png, webp, gif, bmp, heic, heif;
- видео: mp4, mov, webm, mkv и похожие;
- аудио;
- голосовые сообщения;
- документы/файлы;
- встроенные GIF;
- стикеры.
Ограничение размера по умолчанию: 25 MB на файл, если не задано другое.
У вложения должны быть:
- id;
- fileName;
- contentType;
- fileSizeBytes;
- downloadPath;
- kind;
- sortOrder.
Типы kind:
- File;
- VoiceNote;
- Image;
- Video;
- Sticker;
- Gif.
Если backend не хранит kind явно для всех типов, клиент должен уметь определять тип по contentType и расширению файла.
### Отправка фото
Отправка фото должна работать надежно.
Требования:
- пользователь выбирает фото через системный picker;
- фото копируется во временный локальный файл приложения;
- приложение отображает preview перед отправкой;
- при отправке файл передается на сервер multipart/form-data;
- сервер сохраняет оригинал;
- сервер возвращает сообщение с attachment metadata;
- получатели видят фото в чате без перезапуска;
- при нажатии фото открывается полноэкранный просмотр.
Важное визуальное требование:
- одиночное фото в чате должно отображаться как media-сообщение без обычного белого текстового пузыря;
- не должно быть широких белых полей вокруг фото;
- preview в чате должно сохранять корректное соотношение сторон;
- если изображение очень широкое или очень высокое, нужно ограничивать максимальную высоту, но не показывать белую пустую область как часть сообщения;
- фон загрузки не должен выглядеть как белый прямоугольник;
- если файл еще не докачан, нельзя показывать частично скачанный JPEG как готовое изображение.
Техническое требование для кэша:
- вложения скачивать сначала во временный файл, например `filename.part`;
- после полной загрузки и проверки размера атомарно переносить во финальный cache-файл;
- UI должен считать cache-файл готовым только если он существует, не пустой и, если известен ожидаемый размер, совпадает с `fileSizeBytes`;
- при несовпадении размера старый cache-файл нужно игнорировать или перекачивать;
- image loader не должен кэшировать частично скачанные изображения.
### Фотоальбомы
Если пользователь отправляет несколько изображений/видео одновременно:
- файлы должны отправляться одним album-сообщением, если все вложения являются media;
- у всех вложений должен быть общий mediaAlbumId;
- в чате нужно показывать collage/grid;
- порядок должен соответствовать выбору пользователя;
- при нажатии открывается просмотрщик с навигацией по фото альбома.
### Просмотр фото
Фото-просмотрщик должен:
- открываться на весь экран;
- иметь черный фон;
- показывать фото целиком через ContentScale/Fit;
- поддерживать pinch-to-zoom;
- поддерживать drag при увеличении;
- иметь кнопку закрытия/назад;
- иметь имя отправителя и время;
- поддерживать переход к предыдущему/следующему фото в контексте чата или альбома;
- иметь меню: сохранить, поделиться, открыть внешне, если разрешено.
### Видео
Видео-сообщение должно:
- отображаться карточкой с preview/play;
- открываться в full-screen player;
- проигрываться через Media3/ExoPlayer или аналог;
- поддерживать авторизованные URL;
- иметь play/pause;
- иметь закрытие назад.
### Голосовые сообщения
Нужно поддерживать:
- запись голосового;
- таймер записи;
- отмену записи;
- отправку как attachment kind VoiceNote;
- воспроизведение в чате;
- progress bar;
- stop/play;
- паузу внешней музыки при записи или воспроизведении, если настройка включена.
### Реакции
Сообщения должны поддерживать реакции:
- пользователь может поставить emoji-реакцию;
- повторное нажатие может убрать или сменить реакцию;
- счетчики реакций обновляются real-time;
- реакции отображаются компактно под сообщением.
### Ответы, пересылка, редактирование, удаление
Нужно реализовать:
- reply preview над composer;
- reply preview внутри сообщения;
- переход к исходному сообщению по tap на reply;
- edit mode для своих сообщений;
- delete для себя или для всех, если разрешено;
- forward flow с выбором чата;
- protected content: если сообщение защищено, запретить копирование/пересылку/сохранение.
### Поиск
Нужен глобальный поиск:
- по пользователям;
- по чатам;
- по сообщениям;
- по вложениям;
- по медиа;
- по файлам.
Нужен поиск внутри чата:
- строка поиска в header;
- подсветка результатов;
- навигация вверх/вниз по результатам;
- загрузка старых сообщений при необходимости.
### Уведомления
Push-уведомления должны приходить для:
- новых сообщений;
- входящих звонков;
- важных системных событий.
Требования:
- Firebase token registration;
- настройка звука;
- mute per chat;
- глобальное включение/выключение preview;
- не показывать уведомление, если пользователь уже находится в активном чате;
- действия в уведомлении: открыть чат, принять/отклонить звонок.
### Приватность и безопасность
Нужно реализовать:
- JWT auth;
- авторизацию на всех API;
- проверку членства в чате перед доступом к сообщениям и вложениям;
- запрет скачивания вложений неучастниками;
- privacy settings;
- protected content;
- secure window option на Android;
- rate limiting на API;
- удаление пользователя админом;
- удаление чата и файлов;
- server-side validation для всех upload.
Настройки приватности:
- кто видит номер телефона;
- кто видит avatar;
- кто видит online;
- кто может звонить;
- кто может добавлять в группы;
- показывать или скрывать message preview.
### Настройки приложения
Нужны настройки:
- язык/локаль;
- тема/цвета, если реализуется;
- размер текста сообщений;
- радиус пузырьков;
- обои чата;
- layout списка чатов;
- автоскачивание фото;
- автоскачивание видео по Wi-Fi;
- автоскачивание файлов по Wi-Fi;
- сохранять медиа в галерею;
- защищенный экран;
- push settings;
- настройки звонков.
### Кэш и offline
Android-клиент должен:
- кэшировать последние сообщения;
- показывать кэш при старте;
- хранить scroll position;
- хранить draft text;
- кэшировать скачанные вложения;
- иметь политику очистки кэша;
- поддерживать очередь upload/download через WorkManager;
- показывать прогресс больших передач;
- повторять неудачные передачи.
### Архитектура Android-клиента
Рекомендуемый стек:
- Kotlin;
- Jetpack Compose;
- Material 3;
- Navigation Compose;
- ViewModel;
- StateFlow;
- Room для локального кэша;
- DataStore для настроек;
- OkHttp для API;
- Kotlin serialization;
- SignalR client для realtime;
- Coil для изображений;
- Media3 для видео;
- WorkManager для фоновых upload/download;
- Firebase Messaging.
Структура клиента:
- `app` - dependency container, app bootstrap;
- `core/network` - ApiClient, ServerConfig;
- `core/model` - DTO/model classes;
- `core/realtime` - realtime service;
- `core/local` - Room entities/DAO/cache;
- `core/settings` - DataStore settings;
- `core/push` - Firebase/push;
- `feature/login`;
- `feature/chats`;
- `feature/chat`;
- `feature/profile`;
- `feature/settings`;
- `feature/stories`;
- `feature/call`;
- `feature/bots`;
- `feature/search`;
- `feature/forward`;
- `feature/chatinfo`;
- `feature/transfer`.
### Архитектура backend
Рекомендуемый стек:
- ASP.NET Core;
- Controllers для REST API;
- SignalR Hub для realtime;
- EF Core;
- JWT Bearer auth;
- SQLite/PostgreSQL;
- hosted services для фоновых задач;
- local file storage для uploads;
- Dockerfile.
Структура backend:
- `Controllers/AuthController`;
- `Controllers/UsersController`;
- `Controllers/ChatsController`;
- `Controllers/StoriesController`;
- `Controllers/BotsController`;
- `Controllers/BotApiController`;
- `Controllers/PushController`;
- `Controllers/AppUpdatesController`;
- `Controllers/AdminController`;
- `Infrastructure/Hubs/MessengerHub`;
- `Infrastructure/Storage/AttachmentStorageService`;
- `Infrastructure/Storage/AvatarStorageService`;
- `Infrastructure/Auth/TokenService`;
- `Infrastructure/Push`;
- `Infrastructure/Calls`;
- `Infrastructure/Bots`;
- `Infrastructure/Admin`;
- `Data/IkarDbContext`;
- `Data/Entities`.
### Основные backend entities
Нужно спроектировать сущности:
- User;
- UserSession;
- Chat;
- ChatMember;
- Message;
- MessageAttachment;
- MessageReaction;
- MessageReadReceipt;
- ChatInviteLink;
- ChatTopic;
- Story;
- StoryAttachment;
- Bot;
- BotCommand;
- BotUpdate;
- PushDevice;
- CallSession;
- Admin/moderation logs.
### REST API
Минимальные API группы:
#### Auth
- `POST /api/auth/phone/request-code`;
- `POST /api/auth/phone/verify`;
- `POST /api/auth/email/request-code`;
- `POST /api/auth/email/verify`;
- `POST /api/auth/refresh`;
- `POST /api/auth/logout`;
- `GET /api/auth/sessions`;
- `DELETE /api/auth/sessions/{id}`.
#### Users
- `GET /api/users/me`;
- `PUT /api/users/me`;
- `POST /api/users/me/avatar`;
- `GET /api/users/{id}`;
- `GET /api/users/search?q=...`;
- `GET /api/users/{id}/avatar`.
#### Chats
- `GET /api/chats`;
- `POST /api/chats/direct`;
- `POST /api/chats/groups`;
- `POST /api/chats/channels`;
- `GET /api/chats/{chatId}`;
- `PUT /api/chats/{chatId}`;
- `DELETE /api/chats/{chatId}`;
- `GET /api/chats/{chatId}/messages`;
- `POST /api/chats/{chatId}/messages`;
- `PUT /api/chats/{chatId}/messages/{messageId}`;
- `DELETE /api/chats/{chatId}/messages/{messageId}`;
- `POST /api/chats/{chatId}/messages/{messageId}/reactions`;
- `POST /api/chats/{chatId}/attachments`;
- `POST /api/chats/{chatId}/attachments/album`;
- `GET /api/chats/{chatId}/attachments/{attachmentId}/content`;
- `POST /api/chats/{chatId}/members`;
- `DELETE /api/chats/{chatId}/members/{userId}`;
- `GET /api/chats/{chatId}/search`.
#### Push
- `POST /api/push/devices`;
- `DELETE /api/push/devices/{id}`;
- `PUT /api/push/settings`.
#### Admin
- `GET /admin/api/status`;
- `GET /admin/api/users`;
- `GET /admin/api/chats`;
- `GET /admin/api/messages`;
- `GET /admin/api/attachments`;
- `GET /admin/api/attachments/{id}/content`;
- `DELETE /admin/api/attachments/{id}`;
- `DELETE /admin/api/users/{id}`;
- `DELETE /admin/api/chats/{id}`.
### Realtime hub
Realtime должен поддерживать:
- подключение авторизованного пользователя;
- join/leave chat groups;
- отправку нового сообщения всем участникам;
- обновление сообщения;
- удаление сообщения;
- reaction update;
- typing indicator;
- read receipts;
- online/presence;
- call signaling;
- story changed notification;
- chat list invalidation.
Пример событий:
- `MessageCreated`;
- `MessageUpdated`;
- `MessageDeleted`;
- `ReactionUpdated`;
- `TypingChanged`;
- `ChatUpdated`;
- `UserPresenceChanged`;
- `IncomingCall`;
- `CallAccepted`;
- `CallDeclined`;
- `CallEnded`;
- `WebRtcOffer`;
- `WebRtcAnswer`;
- `IceCandidate`;
- `StoriesChanged`.
### UI/UX стиль
Общее направление:
- Telegram-like;
- чистый светлый интерфейс;
- быстрые списки;
- минимум декоративности;
- акцентный голубой цвет;
- аккуратные rounded shapes;
- сообщения компактные;
- медиа без лишних рамок;
- настройки плотные и понятные;
- нижняя composer-панель всегда удобная.
Цвета можно использовать примерно такие:
- accent blue: `#3390EC`;
- text dark: `#17212B`;
- muted text: `#6C7883`;
- incoming bubble: `#FFFFFF`;
- outgoing bubble: `#E7F7C8`;
- app background: `#F3F7FA`;
- media placeholder: лучше прозрачный или нейтральный, но не белый прямоугольник вокруг фото.
### Экран чата
Экран чата должен включать:
- header с back, avatar, title, subtitle/online, menu;
- список сообщений;
- date separators;
- pinned message banner;
- search mode;
- selection mode;
- reply/edit panel;
- composer;
- attach button;
- emoji/GIF/sticker picker;
- voice record button;
- send button;
- scroll-to-bottom button;
- active transfer cards;
- call banner.
Поведение:
- новые сообщения добавляются снизу;
- автоскролл вниз, если пользователь уже внизу;
- если пользователь выше по истории, показывать кнопку вниз;
- свайп сообщения влево/вправо для reply;
- long press для selection/context actions;
- double tap для reaction, если реализуется.
### Composer
Composer должен поддерживать:
- многострочный ввод;
- attach picker;
- отправку текста;
- отправку вложений;
- preview выбранного файла;
- preview альбома;
- remove attachment;
- reply state;
- edit state;
- emoji/sticker/GIF panel;
- voice recording.
### Встроенный image loader
Для авторизованных картинок:
- использовать access token в Authorization header;
- иметь disk/memory cache key, зависящий от URL и token;
- поддерживать callback успешной загрузки, чтобы UI мог узнать intrinsic size;
- не показывать частично скачанный файл;
- для full-screen использовать fit;
- для chat preview использовать crop только когда aspect ratio контейнера отличается от изображения.
### Admin panel
Admin UI должен быть web-страницей внутри сервера.
Возможности:
- dashboard server status;
- список пользователей;
- список чатов;
- список сообщений;
- список вложений;
- скачивание вложения;
- удаление вложения;
- удаление пользователя;
- удаление чата;
- фильтры и поиск;
- отображение размера файлов и количества записей.
### Обновления приложения
Нужен механизм обновления Android-клиента:
- сервер или отдельный catalog endpoint отдает manifest;
- приложение проверяет latest release;
- сравнивает versionName/versionCode;
- скачивает APK;
- проверяет SHA-256;
- запускает Android package installer;
- записывает установленную версию только после успешной установки.
Manifest должен содержать:
- slug;
- name;
- version;
- androidVersionCode;
- channel;
- platform;
- packageKind;
- downloadPath;
- packageSizeBytes;
- sha256;
- notes;
- publishedAt.
Важно:
- все APK-обновления должны быть подписаны одним и тем же release/upload key;
- нельзя публиковать APK с новым случайным ключом поверх уже установленного приложения.
### Хранение файлов
Сервер должен:
- сохранять вложения в отдельную директорию;
- генерировать безопасные имена файлов;
- хранить оригинальное имя отдельно;
- не доверять client filename;
- определять content type по заголовку и расширению;
- удалять физический файл при удалении attachment/message/chat/user;
- запрещать path traversal;
- отдавать файл только авторизованным участникам чата.
### Docker и deployment
Нужно подготовить:
- `Dockerfile.server`;
- docker-compose для сервера и БД, если нужно;
- appsettings для production/development;
- переменные окружения для JWT, storage path, admin password, SMTP, Firebase;
- scripts для smoke tests;
- scripts для публикации Android APK.
### Тестирование
Обязательные тесты backend:
- auth flow;
- create direct chat;
- send message;
- upload attachment;
- download attachment access control;
- group member permissions;
- channel post permissions;
- reactions;
- stories visibility;
- bot sendMessage/sendPhoto;
- admin delete user/chat/attachment;
- push dispatcher.
Обязательные проверки Android:
- compileDebugKotlin;
- assembleRelease;
- отправка текста;
- отправка фото;
- фото в чате без белого прямоугольника;
- full-screen preview открывает полное фото;
- получатель видит фото без частичного JPEG;
- отправка альбома;
- voice note;
- video preview/player;
- push notification;
- login/session restore.
### Критерии приемки MVP
MVP считается готовым, если:
- пользователь может зарегистрироваться/войти;
- видит список чатов;
- может создать личный чат;
- может отправить и получить текст в real-time;
- может отправить фото;
- фото отображается в чате без белого пузыря и без поломанного partial preview;
- фото открывается на весь экран;
- можно отправить файл;
- можно отправить voice note;
- есть push для новых сообщений;
- есть локальный кэш сообщений;
- backend проверяет права доступа;
- Android APK собирается release-сборкой;
- APK обновляется через manifest/catalog.
### Критерии приемки полной версии
Полная версия считается готовой, если дополнительно есть:
- группы;
- каналы;
- обсуждения каналов;
- сторис;
- аудио/видео звонки;
- боты;
- глобальный поиск;
- админка;
- настройки приватности;
- настройки чатов;
- media gallery/materials;
- transfer queue;
- Argus-like publication flow;
- smoke tests;
- базовая документация для запуска.
## Особые требования к качеству
- Приложение должно ощущаться быстрым.
- Все сетевые ошибки должны иметь понятное сообщение.
- Нельзя блокировать UI во время upload/download.
- Нельзя показывать недокачанный файл как готовый.
- Нельзя терять draft при повороте/перезапуске.
- Нельзя отдавать вложения неучастникам чата.
- Нельзя публиковать Android update с другим signing certificate.
- Нужно очищать временные файлы.
- Нужно избегать больших белых полей вокруг медиа.
- Нужно хранить секреты только в env/local ignored files.
## Подсказка для нейросети-разработчика
Если ты создаешь проект по этому ТЗ, сначала сгенерируй архитектуру и каркас:
1. Backend API + database entities.
2. Android app shell + auth/session.
3. Chat list + chat screen.
4. Realtime messages.
5. Attachments upload/download.
6. Correct image rendering and cache safety.
7. Push notifications.
8. Groups/channels/stories/calls/bots.
9. Admin panel.
10. Release/update flow.
Не начинай с лендинга. Первый экран приложения после входа - список чатов. Если пользователь не авторизован - экран входа.
Главный UX-ориентир: это должен быть рабочий мессенджер, а не демонстрационная страница.