Functional Requirements
Функциональные требования к платформе AqStream.
Обзор модулей
flowchart TB
subgraph External["Внешние сервисы"]
TG["📱 Telegram"]
PAY["💳 Платёжные провайдеры"]
end
subgraph Core["Core"]
Auth["🔐 Аутентификация"]
Users["👤 Пользователи"]
Orgs["🏢 Организации"]
end
subgraph Events["События"]
EventMgmt["📅 Управление событиями"]
Tickets["🎫 Билеты"]
Reg["📝 Регистрации"]
CheckIn["✅ Check-in"]
Waitlist["⏳ Лист ожидания"]
end
subgraph Support["Поддержка"]
Payments["💰 Платежи"]
Notif["🔔 Уведомления"]
Media["🖼️ Медиа"]
Analytics["📊 Аналитика"]
end
Auth --> TG
Users --> Orgs
Orgs --> EventMgmt
EventMgmt --> Tickets
Tickets --> Reg
Reg --> Waitlist
Reg --> CheckIn
Reg --> Payments
Payments --> PAY
Reg --> Notif
Notif --> TG
EventMgmt --> Media
Reg --> Analytics
FR-1: Аутентификация и авторизация
FR-1.1: Регистрация пользователя
| ID |
Требование |
| FR-1.1.1 |
Система должна позволять регистрацию через Telegram (основной способ) |
| FR-1.1.2 |
Система должна позволять регистрацию по email и паролю (альтернативный способ) |
| FR-1.1.3 |
При регистрации через Telegram аккаунт активируется автоматически |
| FR-1.1.4 |
При регистрации по email требуется подтверждение |
| FR-1.1.5 |
Пароль должен содержать минимум 8 символов, включая буквы и цифры |
| FR-1.1.6 |
Система должна проверять уникальность Telegram ID и email |
FR-1.2: Вход в систему
| ID |
Требование |
| FR-1.2.1 |
Система должна аутентифицировать пользователя через Telegram (основной способ) |
| FR-1.2.2 |
Система должна аутентифицировать пользователя по email и паролю (альтернативный способ) |
| FR-1.2.3 |
При успешном входе выдаётся JWT access token и refresh token |
| FR-1.2.4 |
Access token действителен 15 минут |
| FR-1.2.5 |
Refresh token действителен 7 дней |
| FR-1.2.6 |
Система должна блокировать аккаунт после 5 неудачных попыток входа по email |
FR-1.3: Восстановление пароля
| ID |
Требование |
| FR-1.3.1 |
Пользователь может запросить сброс пароля по email |
| FR-1.3.2 |
Ссылка для сброса действительна 1 час |
| FR-1.3.3 |
После сброса все активные сессии завершаются |
FR-2: Управление пользователями
FR-2.1: Профиль пользователя
| ID |
Требование |
| FR-2.1.1 |
Пользователь может редактировать имя, фамилию, аватар |
| FR-2.1.2 |
Пользователь может изменить email (требует подтверждения) |
| FR-2.1.3 |
Пользователь может изменить пароль |
| FR-2.1.4 |
Пользователь может удалить свой аккаунт |
FR-2.2: Настройки уведомлений
| ID |
Требование |
| FR-2.2.1 |
Уведомления отправляются через Telegram (основной канал) |
| FR-2.2.2 |
Пользователь может настроить типы уведомлений |
| FR-2.2.3 |
Настройки применяются ко всем организациям пользователя |
FR-2.3: Админ платформы
| ID |
Требование |
| FR-2.3.1 |
Админ рассматривает и одобряет/отклоняет запросы на создание организаций |
| FR-2.3.2 |
Админ может управлять пользователями (блокировка, удаление) |
| FR-2.3.3 |
Админ может управлять организациями (редактирование, удаление) |
| FR-2.3.4 |
Админ может модерировать события (скрытие, удаление) |
| FR-2.3.5 |
Админ имеет доступ к системным настройкам |
| FR-2.3.6 |
Админ имеет доступ к логам и метрикам платформы |
| FR-2.3.7 |
Админ видит данные всех организаций (без ограничений RLS) |
FR-3: Организации
FR-3.1: Создание организации
| ID |
Требование |
| FR-3.1.1 |
Пользователь может отправить запрос на создание организации |
| FR-3.1.2 |
Админ платформы рассматривает и одобряет/отклоняет запрос |
| FR-3.1.3 |
После одобрения пользователь создаёт организацию |
| FR-3.1.4 |
Название организации обязательно |
| FR-3.1.5 |
URL (slug) организации должен быть уникальным |
| FR-3.1.6 |
Создатель становится владельцем организации |
FR-3.2: Управление членами
| ID |
Требование |
| FR-3.2.1 |
Владелец и модератор могут приглашать членов через Telegram |
| FR-3.2.2 |
Доступные роли: Владелец (Owner), Модератор |
| FR-3.2.3 |
Только владелец может назначать/снимать роли |
| FR-3.2.4 |
Модератор может приглашать и удалять членов (кроме владельца) |
| FR-3.2.5 |
Приглашение действительно 7 дней |
FR-3.3: Роли и права
| Право |
Владелец |
Модератор |
| Удаление организации |
✓ |
— |
| Передача владения |
✓ |
— |
| Управление организацией |
✓ |
✓ |
| Управление членами |
✓ |
✓* |
| Назначение ролей |
✓ |
— |
| Создание/удаление групп |
✓ |
✓/— |
| Приглашение в группы |
✓ |
✓ |
| Создание событий |
✓ |
✓ |
| Редактирование событий |
✓ |
✓ |
| Отмена событий |
✓ |
✓ |
| Просмотр регистраций |
✓ |
✓ |
| Просмотр аналитики |
✓ |
✓ |
| Check-in |
✓ |
✓ |
| Экспорт данных |
✓ |
✓ |
*Модератор не может удалить владельца
FR-3.4: Группы
| ID |
Требование |
| FR-3.4.1 |
Владелец и модератор могут создавать группы внутри организации |
| FR-3.4.2 |
Только владелец может удалять группы |
| FR-3.4.3 |
Для приглашения в группу генерируется уникальный инвайт-код |
| FR-3.4.4 |
Пользователь может состоять в нескольких группах |
| FR-3.4.5 |
Событие может быть привязано к одной или нескольким группам |
| FR-3.4.6 |
Групповое событие видно только участникам группы и членам организации |
FR-4: События
FR-4.1: Создание события
| ID |
Требование |
| FR-4.1.1 |
Организатор может создать событие от имени организации |
| FR-4.1.2 |
Обязательные поля: название, дата начала |
| FR-4.1.3 |
Опциональные поля: описание, место, обложка, дата окончания |
| FR-4.1.4 |
Описание поддерживает Markdown |
| FR-4.1.5 |
Событие создаётся в статусе Draft |
| FR-4.1.6 |
Организатор может настроить видимость списка участников (закрытая/открытая) |
| FR-4.1.7 |
При открытой видимости участники видят список зарегистрированных с распределением по типам билетов |
FR-4.2: Жизненный цикл события
stateDiagram-v2
[*] --> Draft
Draft --> Published: Публикация
Published --> Draft: Снятие
Published --> Cancelled: Отмена
Published --> Completed: Завершение
Draft --> Cancelled: Отмена
Cancelled --> [*]
Completed --> [*]
| ID |
Требование |
| FR-4.2.1 |
Draft: событие не видно публично, можно редактировать |
| FR-4.2.2 |
Published: событие доступно для регистрации |
| FR-4.2.3 |
Cancelled: регистрация закрыта, участники уведомлены |
| FR-4.2.4 |
Completed: событие завершено, только просмотр |
FR-4.3: Редактирование события
| ID |
Требование |
| FR-4.3.1 |
В статусе Draft можно редактировать всё |
| FR-4.3.2 |
В статусе Published нельзя изменять типы билетов с регистрациями |
| FR-4.3.3 |
При изменении даты/места участники получают уведомление |
FR-5: Билеты
FR-5.1: Типы билетов
| ID |
Требование |
| FR-5.1.1 |
Событие может иметь несколько типов билетов |
| FR-5.1.2 |
Каждый тип имеет: название, количество |
| FR-5.1.3 |
Можно задать период продаж (начало, окончание) |
| FR-5.1.4 |
Билет может быть бесплатным или платным |
| FR-5.1.5 |
Для платного билета можно задать время брони (опционально) |
| FR-5.1.6 |
Для платного билета можно задать предоплату (опционально) |
| FR-5.1.7 |
При истечении времени брони — бронь аннулируется, место возвращается |
FR-5.2: Доступность билетов
| ID |
Требование |
| FR-5.2.1 |
Система отображает количество доступных билетов |
| FR-5.2.2 |
При продаже последнего билета тип помечается как «Распродан» |
| FR-5.2.3 |
Система предотвращает overselling (конкурентные покупки) |
FR-6: Регистрации
FR-6.1: Процесс регистрации
| ID |
Требование |
| FR-6.1.1 |
Пользователь выбирает тип билета |
| FR-6.1.2 |
Заполняет регистрационную форму |
| FR-6.1.3 |
Для платных билетов — переход к оплате |
| FR-6.1.4 |
После успешной регистрации генерируется уникальный код |
| FR-6.1.5 |
Билет отправляется в Telegram с QR-кодом |
FR-6.2: Статусы регистрации
stateDiagram-v2
[*] --> Reserved: Бронирование (с таймером)
[*] --> Pending: Регистрация (без таймера)
[*] --> Confirmed: Бесплатный билет
Reserved --> Confirmed: Оплата
Reserved --> Expired: Истечение времени
Reserved --> Cancelled: Отмена
Pending --> Confirmed: Оплата
Pending --> Cancelled: Отмена
Confirmed --> CheckedIn: Check-in
Confirmed --> Cancelled: Отмена (возврат)
Expired --> [*]
Cancelled --> [*]
CheckedIn --> [*]
| Статус |
Описание |
| Reserved |
Забронировано, ожидает оплаты (с ограничением по времени) |
| Pending |
Ожидает оплаты (без ограничения) |
| Confirmed |
Подтверждена (оплачена или бесплатный билет) |
| Cancelled |
Отменена |
| CheckedIn |
Участник пришёл |
| Expired |
Бронь истекла |
FR-6.3: Отмена регистрации
| ID |
Требование |
| FR-6.3.1 |
Участник может отменить регистрацию |
| FR-6.3.2 |
Организатор может отменить регистрацию участника |
| FR-6.3.3 |
При отмене платной регистрации инициируется возврат |
| FR-6.3.4 |
Место возвращается в пул доступных |
FR-7: Лист ожидания
| ID |
Требование |
| FR-7.1 |
При отсутствии билетов можно встать в лист ожидания |
| FR-7.2 |
При появлении места первый в очереди получает уведомление |
| FR-7.3 |
На бронирование даётся 24 часа |
| FR-7.4 |
Если не использовано — переходит к следующему |
FR-8: Check-in
| ID |
Требование |
| FR-8.1 |
Организатор может сканировать QR-код билета |
| FR-8.2 |
Система проверяет валидность билета |
| FR-8.3 |
Система предотвращает повторный check-in |
| FR-8.4 |
Возможен ручной поиск по имени/email |
| FR-8.5 |
Статистика check-in доступна в реальном времени |
FR-9: Платежи
FR-9.1: Провайдеры
| ID |
Требование |
| FR-9.1.1 |
Интеграция с платёжными провайдерами |
| FR-9.1.2 |
Организация выбирает провайдера в настройках |
FR-9.2: Процесс оплаты
| ID |
Требование |
| FR-9.2.1 |
Создание платёжной сессии при регистрации |
| FR-9.2.2 |
Редирект на страницу провайдера |
| FR-9.2.3 |
Обработка webhook от провайдера |
| FR-9.2.4 |
Подтверждение регистрации при успешной оплате |
| FR-9.2.5 |
Поддержка предоплаты (частичная оплата при регистрации) |
| FR-9.2.6 |
Доплата остатка в личном кабинете до начала события |
FR-9.3: Возвраты
| ID |
Требование |
| FR-9.3.1 |
Полный возврат при отмене регистрации |
| FR-9.3.2 |
Полный возврат при отмене события |
| FR-9.3.3 |
Частичный возврат по решению организатора |
FR-10: Уведомления
FR-10.1: Telegram (основной канал)
| Тип |
Триггер |
| Подтверждение регистрации |
Успешная регистрация |
| Напоминание |
За 24 часа до события |
| Изменение события |
Изменение даты/места |
| Отмена события |
Отмена организатором |
| Билет из листа ожидания |
Освобождение места |
| Чек об оплате |
Успешный платёж |
FR-10.2: Требования к Telegram-боту
| ID |
Требование |
| FR-10.2.1 |
Бот автоматически связывается с аккаунтом при регистрации через Telegram |
| FR-10.2.2 |
Пользователь может отключить определённые типы уведомлений |
| FR-10.2.3 |
Бот поддерживает inline-кнопки для быстрых действий |
| FR-10.2.4 |
Билет отправляется как изображение с QR-кодом |
FR-11: Медиа
| ID |
Требование |
| FR-11.1 |
Загрузка изображений для событий |
| FR-11.2 |
Поддерживаемые форматы: JPEG, PNG, WebP, GIF |
| FR-11.3 |
Максимальный размер: 5 MB |
| FR-11.4 |
Автоматический resize для превью |
FR-12: Аналитика
FR-12.1: Дашборд события
| Метрика |
Описание |
| Просмотры |
Количество просмотров страницы события |
| Регистрации |
Общее количество регистраций |
| Конверсия |
Просмотры → Регистрации |
| Check-in rate |
Регистрации → Пришедшие |
| По типам билетов |
Распределение по типам |
FR-12.2: Экспорт
| ID |
Требование |
| FR-12.2.1 |
Экспорт списка участников в CSV |
| FR-12.2.2 |
Экспорт отчёта в PDF |
Нефункциональные требования
Производительность
| Метрика |
Требование |
| Response time (P95) |
< 500ms |
| Throughput |
1000 req/sec |
| Concurrent users |
10,000 |
| Database queries |
< 100ms (P95) |
Надёжность
| Метрика |
Требование |
| Uptime |
99.9% |
| Data durability |
99.999% |
| RPO |
1 час |
| RTO |
4 часа |
Безопасность
| Аспект |
Требование |
| Транспорт |
HTTPS (TLS 1.3) |
| Пароли |
bcrypt с cost factor 12 |
| Аутентификация |
JWT (HS256) |
| Multi-tenancy |
Row Level Security в PostgreSQL |
| Secrets |
Environment variables, не в коде |
| Валидация |
На всех уровнях (API, Service, DB) |
Масштабируемость
| Аспект |
Требование |
| Архитектура |
Stateless сервисы |
| Горизонтальное масштабирование |
Поддержка нескольких инстансов |
| База данных |
Read replicas для отчётов |
| Кэширование |
Redis для часто запрашиваемых данных |
Мониторинг
| Аспект |
Требование |
| Метрики |
Prometheus-совместимый формат |
| Логирование |
Structured logs (JSON) |
| Трассировка |
Correlation ID во всех запросах |
| Health checks |
/actuator/health для каждого сервиса |
Совместимость
| Аспект |
Требование |
| API версионирование |
/api/v1/, backward compatible |
| Браузеры |
Chrome, Firefox, Safari (последние 2 версии) |
| Мобильные |
Responsive design, PWA-ready |
| Telegram |
Bot API 6.0+ |
Локализация
| Аспект |
Требование |
| Язык интерфейса |
Русский (основной) |
| Часовые пояса |
Поддержка разных timezone |
| Форматы дат |
DD.MM.YYYY HH:mm |
Дальнейшее чтение