# ТЗ: мессенджер в стиле Икар ## Назначение документа Этот документ является техническим заданием для нейросети или команды разработки, которой нужно создать полноценный мессенджер, функционально и визуально близкий к проекту Икар. Цель: получить современный мобильный мессенджер с серверной частью, 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-ориентир: это должен быть рабочий мессенджер, а не демонстрационная страница.