Initial QMAX production app

This commit is contained in:
sevenhill
2026-07-03 22:39:48 +03:00
commit 9fcc659438
119 changed files with 17959 additions and 0 deletions
+882
View File
@@ -0,0 +1,882 @@
# ТЗ: мессенджер в стиле Икар
## Назначение документа
Этот документ является техническим заданием для нейросети или команды разработки, которой нужно создать полноценный мессенджер, функционально и визуально близкий к проекту Икар.
Цель: получить современный мобильный мессенджер с серверной частью, 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-ориентир: это должен быть рабочий мессенджер, а не демонстрационная страница.