v1.1
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
ТЕХНИЧЕСКОЕ ЗАДАНИЕ (ТЗ) НА ПЛАТФОРМУ EVENTHUB
|
ТЕХНИЧЕСКОЕ ЗАДАНИЕ (ТЗ) НА ПЛАТФОРМУ EVENTHUB
|
||||||
Версия: 1.0 (расширенная)
|
Версия: 1.1 (расширенная с гибридной моделью повторяющихся событий)
|
||||||
|
|
||||||
1. ЦЕЛИ И НАЗНАЧЕНИЕ
|
1. ЦЕЛИ И НАЗНАЧЕНИЕ
|
||||||
EventHub — платформа для управления событиями с поддержкой календарей, записи участников (включая специалистов), гибкого подтверждения, рейтингов, отзывов, модерации, встроенного баг-трекера и платной подписки. Целевая аудитория: владельцы календарей (бизнес), участники (клиенты), администраторы.
|
EventHub — платформа для управления событиями с поддержкой календарей, записи участников (включая специалистов), гибкого подтверждения, рейтингов, отзывов, модерации, встроенного баг-трекера и платной подписки. Целевая аудитория: владельцы календарей (бизнес), участники (клиенты), администраторы.
|
||||||
@@ -14,114 +14,256 @@ EventHub — платформа для управления событиями
|
|||||||
- Гибкое подтверждение заявок: auto (автоматически), manual (вручную), timeout (авто через N секунд)
|
- Гибкое подтверждение заявок: auto (автоматически), manual (вручную), timeout (авто через N секунд)
|
||||||
- Теги календаря, рейтинг (средняя оценка, количество голосов)
|
- Теги календаря, рейтинг (средняя оценка, количество голосов)
|
||||||
|
|
||||||
2.2. События
|
2.2. События (расширенная версия с повторяющимися событиями)
|
||||||
- Создание события (название, дата/время, длительность, тип: офлайн/онлайн)
|
|
||||||
- Для офлайн: геоточка (адрес + координаты)
|
2.2.1. Типы событий и модель хранения
|
||||||
- Для онлайн: ссылка (Zoom, Google Meet)
|
События делятся на два типа:
|
||||||
- Ограничение количества мест
|
- single — одиночное событие, имеет конкретные дату и время начала, длительность.
|
||||||
- Привязка к специалисту (для коммерческих календарей)
|
- recurring — повторяющееся событие (серия), определяется мастер-записью и правилом повторения.
|
||||||
- Теги событий, рейтинг
|
|
||||||
|
Для эффективного хранения и быстрого поиска применяется гибридная модель с отложенной материализацией вхождений:
|
||||||
|
- Каждая повторяющаяся серия представлена одной мастер-записью в таблице events с полем event_type = recurring и полем recurrence_rule, содержащим правило повторения в формате, совместимом с iCalendar RRULE (или упрощённый JSON-представление: freq, interval, byday, until и т.д.).
|
||||||
|
- Конкретные вхождения (экземпляры) серии материализуются в таблице events только при необходимости:
|
||||||
|
* когда на данное вхождение записался хотя бы один участник;
|
||||||
|
* когда администратор вручную редактирует это вхождение (перенос времени, отмена, смена специалиста);
|
||||||
|
* (опционально) при наступлении даты вхождения для архивных целей.
|
||||||
|
- Материализованное вхождение имеет:
|
||||||
|
* event_type = single (или специальный флаг is_instance = true),
|
||||||
|
* ссылку master_id на родительскую мастер-запись,
|
||||||
|
* собственные start_time и duration, которые могут отличаться от вычисленных по правилу (например, при переносе конкретного дня).
|
||||||
|
- Отменённые вхождения из серии (исключения) хранятся в отдельной таблице recurrence_exceptions с указанием master_id, original_start_time и action = cancel | reschedule.
|
||||||
|
|
||||||
|
2.2.2. Правила генерации вхождений при поиске
|
||||||
|
При поиске событий на заданный интервал дат (например, /v1/events?from=...&to=...) система:
|
||||||
|
1. Выбирает все одиночные события (event_type = single), попадающие в интервал.
|
||||||
|
2. Выбирает все активные мастер-записи (event_type = recurring), у которых:
|
||||||
|
- дата первого вхождения ≤ конец интервала,
|
||||||
|
- правило повторения допускает вхождения внутри интервала (учёт until или ограничения по количеству повторений).
|
||||||
|
3. Для каждой мастер-записи генерирует список вхождений в пределах запрошенного интервала (используя встроенную функцию разбора RRULE или собственный алгоритм).
|
||||||
|
4. Из сгенерированного списка исключаются вхождения, присутствующие в таблице recurrence_exceptions с действием cancel.
|
||||||
|
5. Если для какого-либо вхождения уже существует материализованная запись в таблице events (по совпадению master_id и start_time), то используются данные материализованного экземпляра (специалист, длительность, статус) вместо вычисленных по шаблону.
|
||||||
|
6. Итоговый список сортируется по времени начала и возвращается с пагинацией.
|
||||||
|
|
||||||
|
Ограничение: глубина генерации вхождений для одного запроса ограничена 1000 элементов; для длительных серий применяется пагинация по датам.
|
||||||
|
|
||||||
|
2.2.3. Материализация при записи участника
|
||||||
|
При попытке записаться на вхождение повторяющегося события (POST /v1/events/:event_id/join):
|
||||||
|
- Если event_id ссылается на мастер-запись (event_type = recurring), то в теле запроса обязательно передаётся occurrence_start — конкретное время вхождения, на которое производится запись.
|
||||||
|
- Система в одной транзакции Mnesia:
|
||||||
|
* Проверяет, существует ли материализованное вхождение с master_id = EventId и start_time = OccurrenceStart.
|
||||||
|
* Если нет — создаёт новую запись в таблице events (тип single, master_id = EventId), копируя общие атрибуты мастер-записи (название, описание, календарь, специалист).
|
||||||
|
* Создаёт бронирование (booking), привязанное к идентификатору материализованного вхождения.
|
||||||
|
- Дальнейшие действия по подтверждению заявки выполняются уже с материализованным экземпляром.
|
||||||
|
|
||||||
|
2.2.4. Изменение и удаление серий
|
||||||
|
- При редактировании мастер-записи (изменение названия, описания, правила повторения) обновляется только сама мастер-запись. Уже существующие материализованные вхождения остаются неизменными (сохраняют старые значения атрибутов). Это поведение может быть изменено администратором через специальный флаг «применить ко всем будущим вхождениям».
|
||||||
|
- При удалении мастер-записи все связанные материализованные вхождения также помечаются удалёнными (или удаляются каскадно), а бронирования на будущие вхождения аннулируются с уведомлением участников.
|
||||||
|
|
||||||
|
2.2.5. Структура записей (records.hrl)
|
||||||
|
```erlang
|
||||||
|
%% Событие (может быть мастером или экземпляром)
|
||||||
|
-record(event, {
|
||||||
|
id :: binary(),
|
||||||
|
calendar_id :: binary(),
|
||||||
|
title :: binary(),
|
||||||
|
description :: binary(),
|
||||||
|
event_type :: single | recurring,
|
||||||
|
start_time :: calendar:datetime(),
|
||||||
|
duration :: integer(), %% минуты
|
||||||
|
recurrence_rule :: binary() | undefined,
|
||||||
|
master_id :: binary() | undefined,
|
||||||
|
is_instance :: boolean(), %% true для материализованных вхождений
|
||||||
|
specialist_id :: binary() | undefined,
|
||||||
|
location :: #location{} | undefined,
|
||||||
|
tags :: [binary()],
|
||||||
|
status :: active | cancelled | completed,
|
||||||
|
created_at :: calendar:datetime(),
|
||||||
|
updated_at :: calendar:datetime()
|
||||||
|
}).
|
||||||
|
|
||||||
|
%% Исключение из повторений
|
||||||
|
-record(recurrence_exception, {
|
||||||
|
master_id :: binary(),
|
||||||
|
original_start :: calendar:datetime(),
|
||||||
|
action :: cancel | reschedule,
|
||||||
|
new_start :: calendar:datetime() | undefined
|
||||||
|
}).
|
||||||
|
|
||||||
|
2.2.6. Требования к реализации
|
||||||
|
|
||||||
|
Разбор и генерация RRULE должны быть реализованы в отдельном модуле logic_recurrence без внешних зависимостей (чистый Erlang).
|
||||||
|
|
||||||
|
Все операции с материализацией и записью участников должны выполняться в транзакциях Mnesia для обеспечения консистентности.
|
||||||
|
|
||||||
|
Для ускорения поиска материализованных вхождений по мастеру и дате создаётся составной индекс в Mnesia: {master_id, start_time} (через mnesia:add_table_index/2 или хранение в ets с ключом {master_id, start_time}).
|
||||||
|
|
||||||
2.3. Запись участников и подтверждение
|
2.3. Запись участников и подтверждение
|
||||||
- Запись через календарь
|
|
||||||
- Подтверждение согласно политике календаря
|
Запись через календарь
|
||||||
- Уведомления участника и владельца
|
|
||||||
- Привязка события к специалисту (отдельная запись в календаре специалиста)
|
Подтверждение согласно политике календаря
|
||||||
|
|
||||||
|
Уведомления участника и владельца
|
||||||
|
|
||||||
|
Привязка события к специалисту (отдельная запись в календаре специалиста)
|
||||||
|
|
||||||
2.4. Отзывы и рейтинги
|
2.4. Отзывы и рейтинги
|
||||||
- Только участники событий могут оставлять отзывы
|
|
||||||
- Оценка 1-5, текстовый комментарий
|
Только участники событий могут оставлять отзывы
|
||||||
- Отзывы на событие или на календарь
|
|
||||||
- Модерация отзывов (администраторы могут скрывать)
|
Оценка 1-5, текстовый комментарий
|
||||||
|
|
||||||
|
Отзывы на событие или на календарь
|
||||||
|
|
||||||
|
Модерация отзывов (администраторы могут скрывать)
|
||||||
|
|
||||||
2.5. Поиск и фильтрация
|
2.5. Поиск и фильтрация
|
||||||
- По тексту, по тегам, по гео-позиции (радиус), по дате/времени
|
|
||||||
|
По тексту, по тегам, по гео-позиции (радиус), по дате/времени
|
||||||
|
|
||||||
2.6. Расширенные возможности
|
2.6. Расширенные возможности
|
||||||
- Экспорт в Google Calendar (через OAuth2)
|
|
||||||
- Экспорт в Apple Calendar (ICS-файл)
|
Экспорт в Google Calendar (через OAuth2)
|
||||||
- Геокодирование (адрес -> координаты) через внешний API (заглушка / Nominatim)
|
|
||||||
|
Экспорт в Apple Calendar (ICS-файл)
|
||||||
|
|
||||||
|
Геокодирование (адрес -> координаты) через внешний API (заглушка / Nominatim)
|
||||||
|
|
||||||
2.7. Модерация и безопасность
|
2.7. Модерация и безопасность
|
||||||
- Жалобы на календари, события, отзывы
|
|
||||||
- Автоматическая модерация по ключевым словам и по порогу жалоб
|
Жалобы на календари, события, отзывы
|
||||||
- Ручная заморозка / разморозка администратором
|
|
||||||
- Бан-лист слов
|
Автоматическая модерация по ключевым словам и по порогу жалоб
|
||||||
- Аудит действий администраторов
|
|
||||||
|
Ручная заморозка / разморозка администратором
|
||||||
|
|
||||||
|
Бан-лист слов
|
||||||
|
|
||||||
|
Аудит действий администраторов
|
||||||
|
|
||||||
2.8. Баг-трекер (автоматический)
|
2.8. Баг-трекер (автоматический)
|
||||||
- При ошибке создаётся тикет, группировка по хэшу ошибки
|
|
||||||
- Учёт количества повторений
|
При ошибке создаётся тикет, группировка по хэшу ошибки
|
||||||
- Уведомление пользователя при создании и при закрытии тикета
|
|
||||||
- Доступ только у администраторов
|
Учёт количества повторений
|
||||||
|
|
||||||
|
Уведомление пользователя при создании и при закрытии тикета
|
||||||
|
|
||||||
|
Доступ только у администраторов
|
||||||
|
|
||||||
2.9. Платная подписка
|
2.9. Платная подписка
|
||||||
- Личное использование бесплатно (personal)
|
|
||||||
- Коммерческое использование платно (commercial)
|
Личное использование бесплатно (personal)
|
||||||
- Пробный период 30 дней
|
|
||||||
- Планы подписки: 1, 3, 6, 12 месяцев
|
Коммерческое использование платно (commercial)
|
||||||
- Заглушка платежного шлюза (для тестирования)
|
|
||||||
- Автоматическое истечение подписки
|
Пробный период 30 дней
|
||||||
|
|
||||||
|
Планы подписки: 1, 3, 6, 12 месяцев
|
||||||
|
|
||||||
|
Заглушка платежного шлюза (для тестирования)
|
||||||
|
|
||||||
|
Автоматическое истечение подписки
|
||||||
|
|
||||||
2.10. Административная панель
|
2.10. Административная панель
|
||||||
- Отдельный HTTPS-сервер (порт 8445) и отдельный WSS (порт 8446)
|
|
||||||
- Управление календарями, событиями, отзывами, жалобами, тикетами, бан-словами
|
Отдельный HTTPS-сервер (порт 8445) и отдельный WSS (порт 8446)
|
||||||
- Статистика, информация о нодах кластера
|
|
||||||
- WebSocket-уведомления администраторам
|
Управление календарями, событиями, отзывами, жалобами, тикетами, бан-словами
|
||||||
|
|
||||||
|
Статистика, информация о нодах кластера
|
||||||
|
|
||||||
|
WebSocket-уведомления администраторам
|
||||||
|
|
||||||
2.11. Real-time уведомления (WebSocket)
|
2.11. Real-time уведомления (WebSocket)
|
||||||
- Пользователи: подписка на календарь, получение обновлений
|
|
||||||
- Администраторы: подписка на глобальные уведомления (жалобы, авто-заморозки)
|
|
||||||
|
|
||||||
3. НЕФУНКЦИОНАЛЬНЫЕ ТРЕБОВАНИЯ
|
Пользователи: подписка на календарь, получение обновлений
|
||||||
|
|
||||||
|
Администраторы: подписка на глобальные уведомления (жалобы, авто-заморозки)
|
||||||
|
|
||||||
|
НЕФУНКЦИОНАЛЬНЫЕ ТРЕБОВАНИЯ
|
||||||
|
|
||||||
3.1. Производительность и масштабирование
|
3.1. Производительность и масштабирование
|
||||||
- 100 000+ пользователей
|
|
||||||
- Горизонтальное масштабирование (увеличение нод)
|
100 000+ пользователей
|
||||||
- Mnesia с дисковыми копиями на нескольких нодах
|
|
||||||
- Отдельные ноды для исторических данных (disc_only_copies)
|
Горизонтальное масштабирование (увеличение нод)
|
||||||
- Пагинация всех списков
|
|
||||||
|
Mnesia с дисковыми копиями на нескольких нодах
|
||||||
|
|
||||||
|
Отдельные ноды для исторических данных (disc_only_copies)
|
||||||
|
|
||||||
|
Пагинация всех списков
|
||||||
|
|
||||||
3.2. Надёжность
|
3.2. Надёжность
|
||||||
- Супервизорное дерево OTP
|
|
||||||
- Let it crash – быстрый перезапуск процессов
|
Супервизорное дерево OTP
|
||||||
- Автоматическое восстановление после падения ноды (Mnesia)
|
|
||||||
|
Let it crash – быстрый перезапуск процессов
|
||||||
|
|
||||||
|
Автоматическое восстановление после падения ноды (Mnesia)
|
||||||
|
|
||||||
3.3. Безопасность
|
3.3. Безопасность
|
||||||
- JWT с ролью (user / admin)
|
|
||||||
- HTTPS / WSS (самоподписанный сертификат для dev, реальный для prod)
|
JWT с ролью (user / admin)
|
||||||
- Argon2 для хеширования паролей (erlang-argon2)
|
|
||||||
- OAuth2 для Google (опционально)
|
HTTPS / WSS (самоподписанный сертификат для dev, реальный для prod)
|
||||||
- Refresh token (запланирован)
|
|
||||||
|
Argon2 для хеширования паролей (erlang-argon2)
|
||||||
|
|
||||||
|
OAuth2 для Google (опционально)
|
||||||
|
|
||||||
|
Refresh token (запланирован)
|
||||||
|
|
||||||
3.4. Наблюдаемость
|
3.4. Наблюдаемость
|
||||||
- Healthcheck эндпоинт
|
|
||||||
- Логирование (JSON, ротация)
|
Healthcheck эндпоинт
|
||||||
- Prometheus метрики (запланированы)
|
|
||||||
- Аудит действий админов
|
Логирование (JSON, ротация)
|
||||||
|
|
||||||
|
Prometheus метрики (запланированы)
|
||||||
|
|
||||||
|
Аудит действий админов
|
||||||
|
|
||||||
3.5. CI/CD
|
3.5. CI/CD
|
||||||
- Drone CI (или GitLab CI / GitHub Actions)
|
|
||||||
- EUnit + Common Test + Tsung
|
|
||||||
- Сборка релиза
|
|
||||||
- Docker-образ
|
|
||||||
- Горячее обновление (rolling upgrade) кластера (3+ нод)
|
|
||||||
- Миграции Mnesia
|
|
||||||
|
|
||||||
4. СТЕК ТЕХНОЛОГИЙ (С ВЕРСИЯМИ)
|
Drone CI (или GitLab CI / GitHub Actions)
|
||||||
- Бэкенд: Erlang/OTP 28.2
|
|
||||||
- Сборка: rebar3 3.27.0
|
|
||||||
- HTTP/WebSocket: Cowboy 2.10.0
|
|
||||||
- JSON: jsx 3.1.0
|
|
||||||
- JWT: jwerl 1.1.0
|
|
||||||
- Хеширование паролей: erlang-argon2 1.0.0
|
|
||||||
- Тестирование: meck 0.9.2, gun 2.0.0
|
|
||||||
- Нагрузочное тестирование: Tsung 1.8.0
|
|
||||||
- CI/CD: Drone 2.0+
|
|
||||||
- Контейнеризация: Docker 20.10+
|
|
||||||
- База данных: Mnesia (встроенная, распределённая)
|
|
||||||
|
|
||||||
5. ИЕРАРХИЧЕСКАЯ СТРУКТУРА КОДА
|
EUnit + Common Test + Tsung
|
||||||
|
|
||||||
|
Сборка релиза
|
||||||
|
|
||||||
|
Docker-образ
|
||||||
|
|
||||||
|
Горячее обновление (rolling upgrade) кластера (3+ нод)
|
||||||
|
|
||||||
|
Миграции Mnesia
|
||||||
|
|
||||||
|
СТЕК ТЕХНОЛОГИЙ (С ВЕРСИЯМИ)
|
||||||
|
|
||||||
|
Бэкенд: Erlang/OTP 28.2
|
||||||
|
|
||||||
|
Сборка: rebar3 3.27.0
|
||||||
|
|
||||||
|
HTTP/WebSocket: Cowboy 2.10.0
|
||||||
|
|
||||||
|
JSON: jsx 3.1.0
|
||||||
|
|
||||||
|
JWT: jwerl 1.1.0
|
||||||
|
|
||||||
|
Хеширование паролей: erlang-argon2 1.0.0
|
||||||
|
|
||||||
|
Тестирование: meck 0.9.2, gun 2.0.0
|
||||||
|
|
||||||
|
Нагрузочное тестирование: Tsung 1.8.0
|
||||||
|
|
||||||
|
CI/CD: Drone 2.0+
|
||||||
|
|
||||||
|
Контейнеризация: Docker 20.10+
|
||||||
|
|
||||||
|
База данных: Mnesia (встроенная, распределённая)
|
||||||
|
|
||||||
|
ИЕРАРХИЧЕСКАЯ СТРУКТУРА КОДА
|
||||||
|
|
||||||
src/
|
src/
|
||||||
├── infra/ # инфраструктура (приложение, супервизоры, аутентификация, подписки)
|
├── infra/ # инфраструктура (приложение, супервизоры, аутентификация, подписки)
|
||||||
@@ -131,54 +273,88 @@ src/
|
|||||||
└── handlers/ # обработчики HTTP/WebSocket
|
└── handlers/ # обработчики HTTP/WebSocket
|
||||||
|
|
||||||
Правила:
|
Правила:
|
||||||
- Модули handlers/ не содержат бизнес-логики.
|
|
||||||
- Модули logic/ не знают о HTTP/WS.
|
|
||||||
- Модули core/ (DAO) работают только с Mnesia.
|
|
||||||
- Модули services/ могут быть заменены на реальные реализации без изменения остального кода.
|
|
||||||
- Заголовочный файл include/records.hrl содержит все записи таблиц Mnesia.
|
|
||||||
|
|
||||||
6. ОСНОВНЫЕ API (КРАТКО)
|
Модули handlers/ не содержат бизнес-логики.
|
||||||
|
|
||||||
|
Модули logic/ не знают о HTTP/WS.
|
||||||
|
|
||||||
|
Модули core/ (DAO) работают только с Mnesia.
|
||||||
|
|
||||||
|
Модули services/ могут быть заменены на реальные реализации без изменения остального кода.
|
||||||
|
|
||||||
|
Заголовочный файл include/records.hrl содержит все записи таблиц Mnesia.
|
||||||
|
|
||||||
|
ОСНОВНЫЕ API (КРАТКО)
|
||||||
|
|
||||||
Пользовательские (порт 8080):
|
Пользовательские (порт 8080):
|
||||||
- POST /v1/register
|
|
||||||
- POST /v1/login
|
POST /v1/register
|
||||||
- GET /v1/user/me
|
|
||||||
- POST /v1/calendars + CRUD
|
POST /v1/login
|
||||||
- POST /v1/calendars/:id/events + CRUD
|
|
||||||
- POST /v1/events/:id/join
|
GET /v1/user/me
|
||||||
- POST /v1/events/:id/confirm/:user_id
|
|
||||||
- POST /v1/reviews
|
POST /v1/calendars + CRUD
|
||||||
- POST /v1/reports
|
|
||||||
- POST /v1/subscription/activate
|
POST /v1/calendars/:id/events + CRUD
|
||||||
- POST /v1/events/:id/export (Google)
|
|
||||||
- GET /v1/events/:id/ical (Apple)
|
POST /v1/events/:id/join
|
||||||
- GET /health
|
|
||||||
|
POST /v1/events/:id/confirm/:user_id
|
||||||
|
|
||||||
|
POST /v1/reviews
|
||||||
|
|
||||||
|
POST /v1/reports
|
||||||
|
|
||||||
|
POST /v1/subscription/activate
|
||||||
|
|
||||||
|
POST /v1/events/:id/export (Google)
|
||||||
|
|
||||||
|
GET /v1/events/:id/ical (Apple)
|
||||||
|
|
||||||
|
GET /health
|
||||||
|
|
||||||
WebSocket (порт 8081): ws://localhost:8081/ws?token=...
|
WebSocket (порт 8081): ws://localhost:8081/ws?token=...
|
||||||
|
|
||||||
Административные (порт 8445):
|
Административные (порт 8445):
|
||||||
- GET /admin/stats/overview
|
|
||||||
- GET /admin/nodes
|
GET /admin/stats/overview
|
||||||
- GET /admin/calendars, PUT /admin/calendars/:id/freeze, /unfreeze
|
|
||||||
- GET /admin/events, PUT /admin/events/:id/freeze
|
GET /admin/nodes
|
||||||
- GET /admin/reviews, PUT /admin/reviews/:id/hide
|
|
||||||
- GET /admin/reports, PUT /admin/reports/:id/status
|
GET /admin/calendars, PUT /admin/calendars/:id/freeze, /unfreeze
|
||||||
- GET /admin/tickets, PUT /admin/tickets/:id/status
|
|
||||||
- GET /admin/banned_words, POST, DELETE
|
GET /admin/events, PUT /admin/events/:id/freeze
|
||||||
|
|
||||||
|
GET /admin/reviews, PUT /admin/reviews/:id/hide
|
||||||
|
|
||||||
|
GET /admin/reports, PUT /admin/reports/:id/status
|
||||||
|
|
||||||
|
GET /admin/tickets, PUT /admin/tickets/:id/status
|
||||||
|
|
||||||
|
GET /admin/banned_words, POST, DELETE
|
||||||
|
|
||||||
Административный WebSocket (порт 8446): wss://localhost:8446/admin/ws?token=...
|
Административный WebSocket (порт 8446): wss://localhost:8446/admin/ws?token=...
|
||||||
|
|
||||||
7. ВЕРСИОНИРОВАНИЕ И СТАТУС
|
ВЕРСИОНИРОВАНИЕ И СТАТУС
|
||||||
Текущая версия: 0.0.1 (MVP, альфа)
|
Текущая версия: 1.1 (MVP, альфа, включает гибридную модель повторяющихся событий)
|
||||||
|
|
||||||
8. ОГРАНИЧЕНИЯ И ДОПУЩЕНИЯ
|
ОГРАНИЧЕНИЯ И ДОПУЩЕНИЯ
|
||||||
- В разработке используются самоподписанные SSL-сертификаты.
|
|
||||||
- Для production требуется реальный сертификат и настройка OAuth2 для Google.
|
|
||||||
- Заглушки внешних сервисов должны быть заменены перед запуском.
|
|
||||||
|
|
||||||
9. ТРЕБОВАНИЯ К ОКРУЖЕНИЮ
|
В разработке используются самоподписанные SSL-сертификаты.
|
||||||
- Erlang/OTP 28.2
|
|
||||||
- rebar3 3.27.0
|
Для production требуется реальный сертификат и настройка OAuth2 для Google.
|
||||||
- openssl
|
|
||||||
- Docker (опционально)
|
Заглушки внешних сервисов должны быть заменены перед запуском.
|
||||||
- Drone (опционально, для CI/CD)
|
|
||||||
|
ТРЕБОВАНИЯ К ОКРУЖЕНИЮ
|
||||||
|
|
||||||
|
Erlang/OTP 28.2
|
||||||
|
|
||||||
|
rebar3 3.27.0
|
||||||
|
|
||||||
|
openssl
|
||||||
|
|
||||||
|
Docker (опционально)
|
||||||
|
|
||||||
|
Drone (опционально, для CI/CD)
|
||||||
Reference in New Issue
Block a user