Files
hotel-analysis/NOTIONS.md
2026-01-13 08:23:03 +03:00

20 KiB
Raw Blame History

Проработка:

  • Прототипы интерфейсов
  • Контракты API (swagger)
  • Пользовательские сценарии (use cases)
  • Sequence диаграммы
  • Сервис лицензий, или какой-то способ модульной поставки сервисов? Может с помощью helm чартов?
  • UI спецификация? Обработка ошибок на UI
  • Система логирования бека, фронта, дебагинг, мониторинг, алертнинг
  • Схема деплоя. Ставимся в кластер? А что если нет кластера? Как упаковывать коробку?
  • Аналитика фичей по отдельности, разделить MVP на небольшие кусочки, поставлять фичи этапами
  • Нагрузочное тестирование

Вопросы от Леши:

  • Оценка временных затрат
  • Оценка денежных затрат (человеческий ресурс от минимум до комфорт, дать диапазон с ролями, стоимостью по сотрудникам)

Архитектурные решения

ADR-001: Стратегия работы с данными PMS

Контекст: Система интегрируется с PMS (и другими системами) для получения данных о гостях, номерах и бронированиях. Нужно определить, как работать с этими данными.

Варианты

Вариант 1: Pass-through (запрос по требованию)

Каждый раз запрашиваем данные из PMS когда нужно.

Плюсы Минусы
Данные всегда актуальные Зависимость от доступности PMS
Не нужно хранить и синхронизировать Задержки на каждый запрос
Нет проблем с консистентностью Нет истории (кто был в номере вчера?)

Вариант 2: Полная репликация

Храним копию данных, синхронизируем по событиям или периодически.

Плюсы Минусы
Работаем автономно при падении PMS Сложность синхронизации
Быстрый доступ к данным Возможны расхождения данных
Есть история Дублирование хранилища

Вариант 3: Гибридный

Храним только то, что нужно для задач + кэшируем справочники.

Что храним у себя:

  • Ссылку на номер/гостя (ID из PMS)
  • Снапшот данных на момент создания задачи (имя гостя, номер комнаты)
  • Историю задач с контекстом

Что запрашиваем из PMS:

  • Актуальный статус номера (грязный/чистый/занят)
  • Текущие бронирования
  • Справочник номеров (с кэшированием)

Вопросы для принятия решения

  1. Автономность — должна ли система работать при недоступности PMS?
  2. История — нужно ли знать "для какого гостя делали задачу месяц назад"?
  3. Частота изменений — как часто меняются данные в PMS (заезды/выезды)?
  4. API PMS — поддерживает ли PMS push-уведомления (webhooks) или только pull?
  5. Объём — сколько номеров/гостей в типичном отеле?
  6. Сценарий — горничной нужен актуальный статус номера или достаточно того, что было при создании задачи?

Решение

Ожидает обсуждения


ADR-002: Мультитенантность

Статус: Открыт

Контекст: В NFR-SCALE-003 указано, что система должна поддерживать несколько отелей на одной инсталляции. Нужно определить архитектуру изоляции данных.

Варианты

Вариант 1: Shared Database + tenant_id

Все отели в одной БД, данные разделены по hotel_id.

Плюсы Минусы
Простота развёртывания Риск утечки данных между отелями
Легко делать кросс-отельную аналитику Сложнее масштабировать отдельный отель
Экономия ресурсов Один отель может "положить" всех

Вариант 2: Database per Tenant

Отдельная БД на каждый отель.

Плюсы Минусы
Полная изоляция данных Сложность управления миграциями
Можно масштабировать независимо Больше ресурсов
Проще соответствовать требованиям безопасности Сложнее кросс-отельная аналитика

Вариант 3: Schema per Tenant

Одна БД, но отдельная schema на отель.

Плюсы Минусы
Баланс изоляции и простоты Ограничения PostgreSQL на количество schema
Проще бэкапы отдельных отелей Всё ещё shared resources

Вопросы для принятия решения

  1. Количество отелей — сколько отелей планируется на одной инсталляции?
  2. Требования безопасности — есть ли требования к физической изоляции данных?
  3. Кросс-отельная аналитика — нужны ли отчёты по всем отелям сразу?
  4. Модель продаж — SaaS (много мелких) или Enterprise (мало крупных)?

Решение

Ожидает обсуждения


ADR-003: API Gateway — готовое решение или самописный

Статус: Открыт

Контекст: В архитектуре указан API Gateway Layer, но не определено — это готовое решение или часть кода. От этого зависит где происходит аутентификация, rate limiting, routing.

Варианты

Вариант 1: Готовое решение (Kong / Traefik / AWS API Gateway)

Плюсы Минусы
Готовый rate limiting, auth, metrics Дополнительная зависимость
Battle-tested Может быть избыточно для MVP
Меньше кода Vendor lock-in (для облачных)

Вариант 2: Самописный на FastAPI

Плюсы Минусы
Полный контроль Нужно писать и поддерживать
Нет лишних зависимостей Rate limiting, auth — своими руками
Гибкость Риск ошибок безопасности

Вариант 3: Nginx + Lua / OpenResty

Плюсы Минусы
Высокая производительность Lua — дополнительный язык
Проверенное решение Сложнее отлаживать

Вопросы для принятия решения

  1. Где аутентификация? — Gateway проверяет JWT или каждый сервис сам?
  2. Rate limiting — нужен ли в MVP?
  3. Инфраструктура — есть ли уже Kubernetes Ingress / Load Balancer?
  4. Команда — есть ли опыт с Kong/Traefik?

Решение

Ожидает обсуждения


ADR-004: Разделение users-service и permissions-service

Статус: Открыт

Контекст: В архитектуре есть два отдельных сервиса: users-service (пользователи, профили) и permissions-service (RBAC, роли). Возможно это избыточно для MVP.

Варианты

Вариант 1: Два отдельных сервиса (текущий)

Плюсы Минусы
Чёткое разделение ответственности Overhead на межсервисное взаимодействие
Можно развивать независимо Сложнее для MVP
Permissions можно переиспользовать Больше точек отказа

Вариант 2: Объединить в один auth-service

Плюсы Минусы
Проще для MVP Может разрастись
Меньше latency Сложнее разделить потом
Один источник правды о пользователе

Вопросы для принятия решения

  1. Сложность RBAC — насколько сложная система прав планируется?
  2. Переиспользование — будут ли другие системы использовать permissions-service?
  3. MVP scope — что минимально необходимо для запуска?

Решение

Ожидает обсуждения


ADR-005: WebSocket масштабирование

Статус: Открыт

Контекст: notification-service использует WebSocket для real-time уведомлений. При нескольких инстансах сервиса нужен механизм доставки сообщения на нужный инстанс.

Варианты

Вариант 1: Sticky Sessions

Клиент всегда идёт на один и тот же инстанс.

Плюсы Минусы
Просто реализовать Неравномерная нагрузка
Не нужен pub/sub При падении инстанса — переподключение

Вариант 2: Redis Pub/Sub

Все инстансы подписаны на Redis, сообщение доставляется всем.

Плюсы Минусы
Равномерная нагрузка Дополнительная зависимость
Отказоустойчивость Больше трафика

Вариант 3: Kafka → все инстансы

Каждый инстанс читает из Kafka и отправляет своим клиентам.

Плюсы Минусы
Уже есть Kafka Дублирование сообщений
Персистентность Нужна фильтрация на клиенте

Вопросы для принятия решения

  1. Количество инстансов — сколько реально будет в production?
  2. Частота сообщений — сколько уведомлений в секунду?
  3. Критичность доставки — что если уведомление не дошло?

Решение

Ожидает обсуждения


ADR-006: Scheduler — гарантия единственного выполнения

Статус: Открыт

Контекст: scheduler-service создаёт задачи по расписанию. При нескольких инстансах может создать дубликаты.

Варианты

Вариант 1: Distributed Lock (Redis/PostgreSQL)

Только один инстанс выполняет задачу.

Плюсы Минусы
Гарантия единственности Сложность реализации
Отказоустойчивость Lock может "застрять"

Вариант 2: Leader Election

Один инстанс — лидер, остальные в standby.

Плюсы Минусы
Простая логика в коде Нужен механизм выбора лидера
Single point of failure

Вариант 3: Один инстанс scheduler'а

Просто не масштабируем этот сервис.

Плюсы Минусы
Максимально просто Нет отказоустойчивости
Для MVP может быть достаточно

Вопросы для принятия решения

  1. Критичность — что если задача не создалась вовремя?
  2. Частота — как часто запускаются scheduled задачи?
  3. MVP — нужен ли scheduler в MVP вообще? (В ROADMAP он в этапе 3)

Решение

Ожидает обсуждения


ADR-007: Консистентность данных между сервисами

Статус: Открыт

Контекст: При создании задачи нужно: сохранить в БД, отправить уведомление, записать в аудит. Что если одна из операций упадёт?

Проблемы

  1. Частичное выполнение — задача создана, но уведомление не отправлено
  2. Дубликаты — retry создал задачу дважды
  3. Порядок событий — аудит записал раньше, чем задача реально создалась

Варианты

Вариант 1: Saga Pattern

Цепочка компенсирующих транзакций.

Вариант 2: Outbox Pattern

Сначала пишем в локальную таблицу outbox, потом отдельный процесс отправляет в Kafka.

Вариант 3: Event Sourcing

Храним события, состояние вычисляется.

Вопросы для принятия решения

  1. Критичность — насколько критична потеря уведомления?
  2. Идемпотентность — как обрабатывать повторные запросы?
  3. Сложность — готовы ли усложнять архитектуру ради гарантий?

Решение

Ожидает обсуждения


ADR-008: Жизненный цикл файлов

Статус: Открыт

Контекст: К задачам прикрепляются файлы (фото уборки). Нужно определить что с ними происходит при удалении/архивации задачи.

Вопросы для принятия решения

  1. Удаление задачи — удалять файлы или оставлять?
  2. Архивация — нужно ли переносить старые файлы в "холодное" хранилище?
  3. Дедупликация — один файл может быть привязан к нескольким задачам?
  4. Квоты — есть ли лимит на размер файлов / количество на задачу?
  5. Доступ — как генерировать URL? Presigned URLs или через API?

Решение

Ожидает обсуждения


ADR-009: gRPC vs REST — когда что использовать

Статус: Открыт

Контекст: В архитектуре указаны оба протокола. Нужно определить границы применения.

Вопросы для принятия решения

  1. Внешний API — только REST или gRPC тоже?
  2. Межсервисное — всё через gRPC или только критичные вызовы?
  3. Команда — есть ли опыт с gRPC?
  4. Клиенты — мобильные приложения будут использовать gRPC?

Потенциальное решение

  • REST — внешний API (клиенты, адаптеры)
  • gRPC — межсервисное взаимодействие (tasks ↔ permissions)

Решение

Ожидает обсуждения


ADR-010: Отсутствующие компоненты в архитектуре

Статус: Открыт

Контекст: При анализе выявлены компоненты, которые не описаны, но могут быть необходимы.

Что не описано

Компонент Зачем нужен Критичность для MVP
Health checks Kubernetes liveness/readiness probes Высокая
Circuit Breaker Защита от каскадных отказов Средняя
Rate Limiting Защита от DDoS/abuse Средняя
Service Discovery Как сервисы находят друг друга Высокая (если не K8s)
Distributed Tracing Отладка цепочек вызовов Низкая для MVP
Config Service Централизованная конфигурация Низкая
Secret Management Хранение credentials Высокая

Вопросы для принятия решения

  1. Kubernetes — будет ли K8s? Если да, многое решается из коробки
  2. MVP scope — что из этого критично для первого релиза?

Решение

Ожидает обсуждения


ADR-011: Безопасность Kafka

Статус: Открыт

Контекст: Через Kafka ходят данные о задачах, гостях, бронированиях. Нужно определить уровень защиты.

Вопросы для принятия решения

  1. Шифрование — нужен ли TLS между сервисами и Kafka?
  2. Аутентификация — SASL или открытый доступ внутри кластера?
  3. Авторизация — ACL на топики (кто может читать/писать)?
  4. Сетевая изоляция — Kafka только во внутренней сети?

Решение

Ожидает обсуждения


ADR-012: Версионирование API

Статус: Открыт

Контекст: API будет развиваться. Нужна стратегия обратной совместимости.

Варианты

Подход Пример Плюсы Минусы
URL versioning /api/v1/tasks Явно, просто Дублирование кода
Header versioning Accept: application/vnd.api.v1+json Чистые URL Сложнее тестировать
Query parameter /api/tasks?version=1 Просто Некрасиво

Вопросы для принятия решения

  1. Клиенты — кто будет потреблять API? Только свои или внешние?
  2. Частота изменений — как часто планируются breaking changes?

Решение

Ожидает обсуждения