32 KiB
ТЗ: мессенджер в стиле Икар
Назначение документа
Этот документ является техническим заданием для нейросети или команды разработки, которой нужно создать полноценный мессенджер, функционально и визуально близкий к проекту Икар.
Цель: получить современный мобильный мессенджер с серверной частью, 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.
Подсказка для нейросети-разработчика
Если ты создаешь проект по этому ТЗ, сначала сгенерируй архитектуру и каркас:
- Backend API + database entities.
- Android app shell + auth/session.
- Chat list + chat screen.
- Realtime messages.
- Attachments upload/download.
- Correct image rendering and cache safety.
- Push notifications.
- Groups/channels/stories/calls/bots.
- Admin panel.
- Release/update flow.
Не начинай с лендинга. Первый экран приложения после входа - список чатов. Если пользователь не авторизован - экран входа.
Главный UX-ориентир: это должен быть рабочий мессенджер, а не демонстрационная страница.