Files
hotel-analysis/Архитектура системы TaskManager.md

42 KiB
Raw Blame History

Назад

Архитектура системы TaskManager

Содержание

  1. Общее описание
  2. Архитектурные принципы
  3. Компоненты системы
  4. Микросервисы
  5. Модель данных
  6. Коммуникация между сервисами
  7. Контракт сообщений
  8. Безопасность и авторизация
  9. Масштабирование
  10. Технологический стек

Общее описание

TaskManager - это интеграционная платформа для управления задачами между различными подразделениями отеля и внешними системами. Система выступает в роли мастер-приложения, объединяющего разрозненные системы (PMS, ERP, системы управления уборкой и т.д.) через адаптеры.

Ключевые особенности:

  • Мультитенантность: поддержка нескольких отелей одного владельца (1-50+ отелей)
  • Модульность: возможность продажи отдельных модулей (базовый функционал, модуль мероприятий, модуль уборки и т.д.)
  • Расширяемость: простота добавления новых адаптеров для интеграции с внешними системами
  • Гибкость: настраиваемые роли, статусы задач, правила маршрутизации

Архитектурные принципы

1. Микросервисная архитектура

Система построена на микросервисах, каждый из которых отвечает за свою domain-область.

2. Event-Driven Architecture

Использование Apache Kafka для асинхронной коммуникации и обработки событий.

3. Адаптер-паттерн для интеграций

Каждая внешняя система имеет свой адаптер, который:

  • Преобразует данные внешней системы в стандартизированный формат
  • Работает как по push, так и по pull модели (в зависимости от возможностей внешней системы)
  • Изолирует логику интеграции от бизнес-логики

4. API Gateway

Единая точка входа для клиентских приложений с поддержкой:

  • REST API для простых запросов
  • gRPC для высокопроизводительной коммуникации
  • WebSocket для real-time обновлений

5. CQRS (Command Query Responsibility Segregation)

Разделение операций чтения и записи для повышения производительности.


Компоненты системы

┌─────────────────────────────────────────────────────────────────┐
│                        Client Layer                              │
├─────────────────────────────────────────────────────────────────┤
│  Web Admin  │  Mobile Apps  │  External Systems  │  Telegram Bot│
└──────┬────────────┬─────────────────┬────────────────┬──────────┘
       │            │                 │                │
       └────────────┴─────────────────┴────────────────┘
                            │
┌───────────────────────────┼───────────────────────────────────────┐
│                     API Gateway Layer                             │
├───────────────────────────┴───────────────────────────────────────┤
│         REST API    │    gRPC    │    WebSocket                   │
└───────────────────────────┬───────────────────────────────────────┘
                            │
┌───────────────────────────┼───────────────────────────────────────┐
│                    Service Layer                                  │
├───────────────────────────┴───────────────────────────────────────┤
│                                                                   │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐           │
│  │   Tasks      │  │ Connections  │  │    Users     │           │
│  │   Service    │  │   Service    │  │   Service    │           │
│  └──────────────┘  └──────────────┘  └──────────────┘           │
│                                                                   │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐           │
│  │Notification  │  │ File Storage │  │   Audit      │           │
│  │  Service     │  │   Service    │  │   Service    │           │
│  └──────────────┘  └──────────────┘  └──────────────┘           │
│                                                                   │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐           │
│  │  Scheduler   │  │ Permissions  │  │   Events     │           │
│  │   Service    │  │   Service    │  │   Service    │           │
│  └──────────────┘  └──────────────┘  └──────────────┘           │
│                                                                   │
└───────────────────────────────────────────────────────────────────┘
                            │
┌───────────────────────────┼───────────────────────────────────────┐
│                   Message Broker (Kafka)                          │
├───────────────────────────┴───────────────────────────────────────┤
│  Topics: tasks.created, tasks.updated, tasks.completed,           │
│          notifications.send, audit.log, etc.                      │
└───────────────────────────┬───────────────────────────────────────┘
                            │
┌───────────────────────────┼───────────────────────────────────────┐
│                    Adapter Layer                                  │
├───────────────────────────┴───────────────────────────────────────┤
│                                                                   │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐           │
│  │PMS Adapter   │  │ERP Adapter   │  │Housekeeping  │           │
│  │ (Opera/...)  │  │              │  │   Adapter    │           │
│  └──────────────┘  └──────────────┘  └──────────────┘           │
│                                                                   │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐           │
│  │Telegram Bot  │  │   Custom     │  │    Custom    │           │
│  │  Adapter     │  │  Adapter #N  │  │  Adapter #M  │           │
│  └──────────────┘  └──────────────┘  └──────────────┘           │
│                                                                   │
└───────────────────────────┬───────────────────────────────────────┘
                            │
┌───────────────────────────┼───────────────────────────────────────┐
│                     Data Layer                                    │
├───────────────────────────┴───────────────────────────────────────┤
│                                                                   │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐           │
│  │  PostgreSQL  │  │    Redis     │  │      S3      │           │
│  │ (Main DB)    │  │   (Cache)    │  │ (File Store) │           │
│  └──────────────┘  └──────────────┘  └──────────────┘           │
│                                                                   │
└───────────────────────────────────────────────────────────────────┘

Микросервисы

1. API Gateway

Назначение: Единая точка входа для всех клиентских приложений

Ответственность:

  • Маршрутизация запросов к соответствующим микросервисам
  • Аутентификация и авторизация
  • Rate limiting
  • Request/Response трансформация
  • Логирование запросов

Технологии: Kong / Envoy / NGINX + gRPC Gateway

Endpoints:

  • REST API: /api/v1/*
  • gRPC: порт 50051
  • WebSocket: /ws/*

2. Tasks Service

Назначение: Управление жизненным циклом задач

Ответственность:

  • CRUD операции с задачами
  • Управление статусами задач (с поддержкой кастомных статусов)
  • Управление зависимостями между задачами
  • Назначение исполнителей
  • Версионирование задач (история изменений)
  • Прикрепление файлов к задачам

База данных: PostgreSQL

  • Таблицы: tasks, task_statuses, task_dependencies, task_history, task_attachments

Kafka Topics:

  • Публикует: tasks.created, tasks.updated, tasks.status_changed, tasks.completed, tasks.cancelled
  • Подписан на: scheduler.task_trigger, connections.route_task

gRPC Service:

service TaskService {
  rpc CreateTask(CreateTaskRequest) returns (Task);
  rpc UpdateTask(UpdateTaskRequest) returns (Task);
  rpc GetTask(GetTaskRequest) returns (Task);
  rpc ListTasks(ListTasksRequest) returns (ListTasksResponse);
  rpc ChangeTaskStatus(ChangeStatusRequest) returns (Task);
  rpc AddDependency(AddDependencyRequest) returns (TaskDependency);
}

3. Connections Service

Назначение: Управление связями между системами и правилами маршрутизации

Ответственность:

  • Хранение конфигурации связей между адаптерами
  • Определение правил маршрутизации сообщений
  • Динамическое обновление правил без перезапуска
  • Валидация связей

База данных: PostgreSQL

  • Таблицы: connections, routing_rules, adapters

Модель связи (направленная):

{
  "id": "uuid",
  "source_adapter_id": "uuid",
  "target_adapter_id": "uuid",
  "routing_rules": [
    {
      "condition": "task_type == 'cleaning'",
      "action": "route",
      "enabled": true
    }
  ],
  "enabled": true,
  "created_at": "timestamp",
  "updated_at": "timestamp"
}

Kafka Topics:

  • Публикует: connections.updated, connections.route_task
  • Подписан на: tasks.created, adapters.message_received

gRPC Service:

service ConnectionService {
  rpc CreateConnection(CreateConnectionRequest) returns (Connection);
  rpc UpdateConnection(UpdateConnectionRequest) returns (Connection);
  rpc DeleteConnection(DeleteConnectionRequest) returns (Empty);
  rpc ListConnections(ListConnectionsRequest) returns (ListConnectionsResponse);
  rpc RouteMessage(RouteMessageRequest) returns (RouteMessageResponse);
}

4. Users Service

Назначение: Управление пользователями и их профилями

Ответственность:

  • CRUD операции с пользователями
  • Управление профилями
  • Привязка к отелям и подразделениям
  • Хранение настроек пользователя

База данных: PostgreSQL

  • Таблицы: users, user_profiles, user_hotels, departments

Kafka Topics:

  • Публикует: users.created, users.updated, users.deleted

gRPC Service:

service UserService {
  rpc CreateUser(CreateUserRequest) returns (User);
  rpc GetUser(GetUserRequest) returns (User);
  rpc UpdateUser(UpdateUserRequest) returns (User);
  rpc ListUsers(ListUsersRequest) returns (ListUsersResponse);
}

5. Permissions Service

Назначение: Управление ролями и правами доступа (RBAC)

Ответственность:

  • Управление ролями (с поддержкой кастомных ролей на уровне отеля)
  • Управление правами доступа
  • Проверка прав доступа
  • Привязка пользователей к ролям

База данных: PostgreSQL

  • Таблицы: roles, permissions, role_permissions, user_roles

Предопределенные роли:

  • system_admin - системный администратор
  • support - техническая поддержка
  • hotel_admin - администратор отеля
  • department_head - руководитель подразделения
  • worker - сотрудник

Кастомные роли: отель может создавать свои роли на основе базовых

gRPC Service:

service PermissionService {
  rpc CreateRole(CreateRoleRequest) returns (Role);
  rpc AssignRole(AssignRoleRequest) returns (UserRole);
  rpc CheckPermission(CheckPermissionRequest) returns (PermissionResponse);
  rpc ListRoles(ListRolesRequest) returns (ListRolesResponse);
}

6. Notification Service

Назначение: Отправка уведомлений через различные каналы

Ответственность:

  • Отправка Email
  • Отправка Push-уведомлений
  • Отправка SMS
  • Отправка сообщений в Telegram
  • Отправка сообщений в другие мессенджеры (WhatsApp, Viber и т.д.)
  • Управление шаблонами уведомлений
  • Управление подписками пользователей

База данных: PostgreSQL

  • Таблицы: notification_templates, notification_subscriptions, notification_log

Kafka Topics:

  • Подписан на: notifications.send, tasks.created, tasks.assigned, tasks.completed

Интеграции:

  • Email: SMTP
  • Push: Firebase Cloud Messaging (FCM) / Apple Push Notification Service (APNS)
  • SMS: Twilio / другие провайдеры
  • Telegram: Telegram Bot API
  • WhatsApp: WhatsApp Business API

gRPC Service:

service NotificationService {
  rpc SendNotification(SendNotificationRequest) returns (NotificationResponse);
  rpc CreateTemplate(CreateTemplateRequest) returns (Template);
  rpc Subscribe(SubscribeRequest) returns (Subscription);
}

7. File Storage Service

Назначение: Управление файлами и изображениями

Ответственность:

  • Загрузка файлов в S3
  • Генерация временных ссылок для скачивания
  • Управление метаданными файлов
  • Оптимизация изображений (resize, compress)
  • Удаление файлов

Хранилище: AWS S3 / MinIO (S3-compatible)

База данных: PostgreSQL

  • Таблицы: files, file_metadata

REST API:

  • POST /api/v1/files/upload - загрузка файла
  • GET /api/v1/files/{id} - получение метаданных
  • GET /api/v1/files/{id}/download - генерация signed URL
  • DELETE /api/v1/files/{id} - удаление файла

8. Audit Service

Назначение: Логирование всех действий в системе

Ответственность:

  • Запись всех изменений в системе
  • Хранение истории действий пользователей
  • Предоставление API для просмотра логов
  • Ретеншн политика (удаление старых логов)

База данных: PostgreSQL (с партиционированием по дате)

  • Таблицы: audit_log (партиционирована)

Kafka Topics:

  • Подписан на: *.created, *.updated, *.deleted, tasks.*, users.*

Модель лога:

{
  "id": "uuid",
  "timestamp": "2025-12-13T10:00:00Z",
  "user_id": "uuid",
  "hotel_id": "uuid",
  "action": "task.created",
  "entity_type": "task",
  "entity_id": "uuid",
  "changes": {
    "before": {},
    "after": {}
  },
  "ip_address": "192.168.1.1",
  "user_agent": "Mozilla/5.0..."
}

gRPC Service:

service AuditService {
  rpc LogAction(LogActionRequest) returns (Empty);
  rpc GetAuditLog(GetAuditLogRequest) returns (GetAuditLogResponse);
}

9. Scheduler Service

Назначение: Управление периодическими задачами

Ответственность:

  • Создание расписаний для задач (cron-подобный синтаксис)
  • Триггеринг создания задач по расписанию
  • Управление повторяющимися задачами

База данных: PostgreSQL

  • Таблицы: schedules, schedule_executions

Модель расписания:

{
  "id": "uuid",
  "name": "Уборка холла каждый день в 8:00",
  "cron_expression": "0 8 * * *",
  "task_template": {
    "title": "Уборка холла",
    "description": "Провести уборку холла",
    "task_type": "cleaning",
    "assignee_id": "uuid"
  },
  "enabled": true,
  "timezone": "Europe/Moscow",
  "next_run": "2025-12-14T08:00:00Z"
}

Kafka Topics:

  • Публикует: scheduler.task_trigger

gRPC Service:

service SchedulerService {
  rpc CreateSchedule(CreateScheduleRequest) returns (Schedule);
  rpc UpdateSchedule(UpdateScheduleRequest) returns (Schedule);
  rpc DeleteSchedule(DeleteScheduleRequest) returns (Empty);
  rpc ListSchedules(ListSchedulesRequest) returns (ListSchedulesResponse);
}

10. Events Service

Назначение: Управление мероприятиями (модуль Events Management)

Ответственность:

  • Создание мероприятий
  • Автоматическая генерация задач для разных подразделений
  • Генерация документа "функшн"
  • Управление конференц-залами и ресурсами

База данных: PostgreSQL

  • Таблицы: events, event_tasks, conference_rooms, event_resources

Модель мероприятия:

{
  "id": "uuid",
  "title": "Конференция по маркетингу",
  "description": "Описание мероприятия",
  "start_time": "2025-12-20T10:00:00Z",
  "end_time": "2025-12-20T18:00:00Z",
  "conference_room_id": "uuid",
  "tasks": [
    {
      "department": "housemen",
      "title": "Расставить 50 стульев и 10 столов",
      "due_before": "2025-12-20T09:00:00Z"
    },
    {
      "department": "it",
      "title": "Подготовить проектор и экран",
      "due_before": "2025-12-20T09:30:00Z"
    },
    {
      "department": "restaurant",
      "title": "Организовать кофе-брейк на 50 человек",
      "due_before": "2025-12-20T12:00:00Z"
    }
  ]
}

Kafka Topics:

  • Публикует: events.created, events.task_generated

gRPC Service:

service EventService {
  rpc CreateEvent(CreateEventRequest) returns (Event);
  rpc UpdateEvent(UpdateEventRequest) returns (Event);
  rpc GenerateTasks(GenerateTasksRequest) returns (GenerateTasksResponse);
  rpc GenerateFunction(GenerateFunctionRequest) returns (FunctionDocument);
}

Adapter Layer (Адаптеры)

Общая архитектура адаптера

Каждый адаптер - это отдельный микросервис, который:

  1. Подключается к внешней системе (API, БД, Webhook endpoint)
  2. Слушает Kafka топики для исходящих сообщений
  3. Преобразует данные в/из стандартизированного формата
  4. Публикует входящие сообщения в Kafka

Базовая структура адаптера:

adapter/
├── connector/         # Логика подключения к внешней системе
│   ├── api_client.py  # REST/SOAP/GraphQL клиент
│   ├── db_client.py   # Прямое подключение к БД (если требуется)
│   └── webhook.py     # Обработчик входящих webhook'ов
├── transformer/       # Преобразование данных
│   ├── inbound.py     # Внешний формат -> Стандартный формат
│   └── outbound.py    # Стандартный формат -> Внешний формат
├── kafka/
│   ├── consumer.py    # Обработка исходящих сообщений
│   └── producer.py    # Публикация входящих сообщений
└── config.py          # Конфигурация адаптера

Примеры адаптеров

1. PMS Adapter (например, Opera)

Функции:

  • Получение информации о бронированиях
  • Создание задач на основе заездов/выездов
  • Обновление статуса номеров

Режим работы: Pull (опрос API) + Push (Webhook для событий)

Kafka Topics:

  • Публикует: adapters.pms.reservation_created, adapters.pms.checkout
  • Подписан на: tasks.room_ready, tasks.room_cleaned

2. Housekeeping Adapter

Функции:

  • Получение задач на уборку номеров
  • Отправка статусов выполнения уборки
  • Загрузка фото до/после уборки

Режим работы: Push (мобильное приложение отправляет данные)

Kafka Topics:

  • Публикует: adapters.housekeeping.task_started, adapters.housekeeping.task_completed
  • Подписан на: tasks.cleaning_assigned

3. Telegram Bot Adapter

Функции:

  • Прием запросов от гостей через Telegram
  • Отправка уведомлений сотрудникам
  • Интерактивные кнопки для частых запросов

Режим работы: Push (Telegram Webhook)

Kafka Topics:

  • Публикует: adapters.telegram.guest_request
  • Подписан на: notifications.send, tasks.assigned

Модель данных

Основные сущности

1. Hotels (Отели)

CREATE TABLE hotels (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name VARCHAR(255) NOT NULL,
    address TEXT,
    owner_id UUID NOT NULL, -- один владелец, несколько отелей
    settings JSONB DEFAULT '{}',
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW()
);

2. Departments (Подразделения)

CREATE TABLE departments (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    hotel_id UUID REFERENCES hotels(id),
    name VARCHAR(255) NOT NULL,
    type VARCHAR(50), -- housekeeping, technical, it, restaurant, etc.
    created_at TIMESTAMP DEFAULT NOW()
);

3. Users (Пользователи)

CREATE TABLE users (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    email VARCHAR(255) UNIQUE NOT NULL,
    phone VARCHAR(50),
    first_name VARCHAR(100),
    last_name VARCHAR(100),
    password_hash VARCHAR(255),
    is_active BOOLEAN DEFAULT TRUE,
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE user_hotels (
    user_id UUID REFERENCES users(id),
    hotel_id UUID REFERENCES hotels(id),
    department_id UUID REFERENCES departments(id),
    PRIMARY KEY (user_id, hotel_id)
);

4. Tasks (Задачи)

CREATE TABLE tasks (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    hotel_id UUID REFERENCES hotels(id),
    title VARCHAR(500) NOT NULL,
    description TEXT,
    task_type VARCHAR(100), -- cleaning, maintenance, delivery, etc.
    priority VARCHAR(20) DEFAULT 'normal', -- low, normal, high, urgent
    status_id UUID REFERENCES task_statuses(id),

    -- Исполнители
    creator_id UUID REFERENCES users(id),
    assignee_id UUID REFERENCES users(id),
    department_id UUID REFERENCES departments(id),

    -- Временные метки
    due_date TIMESTAMP,
    started_at TIMESTAMP,
    completed_at TIMESTAMP,
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW(),

    -- Мета-информация
    metadata JSONB DEFAULT '{}', -- для хранения дополнительных полей
    source_system VARCHAR(100), -- откуда пришла задача
    external_id VARCHAR(255) -- ID во внешней системе
);

CREATE INDEX idx_tasks_assignee ON tasks(assignee_id);
CREATE INDEX idx_tasks_hotel ON tasks(hotel_id);
CREATE INDEX idx_tasks_status ON tasks(status_id);
CREATE INDEX idx_tasks_created ON tasks(created_at);

5. Task Statuses (Статусы задач)

CREATE TABLE task_statuses (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    hotel_id UUID REFERENCES hotels(id), -- NULL для глобальных статусов
    name VARCHAR(100) NOT NULL,
    code VARCHAR(50) NOT NULL, -- created, assigned, in_progress, completed, cancelled, rejected
    is_final BOOLEAN DEFAULT FALSE, -- финальный статус (completed, cancelled)
    color VARCHAR(7), -- HEX цвет для UI
    order_index INT, -- порядок отображения
    is_custom BOOLEAN DEFAULT FALSE, -- кастомный статус отеля
    created_at TIMESTAMP DEFAULT NOW()
);

-- Предопределенные статусы
INSERT INTO task_statuses (name, code, is_final, order_index) VALUES
    ('Создана', 'created', FALSE, 1),
    ('Назначена', 'assigned', FALSE, 2),
    ('В работе', 'in_progress', FALSE, 3),
    ('Выполнена', 'completed', TRUE, 4),
    ('Отменена', 'cancelled', TRUE, 5),
    ('Отклонена', 'rejected', TRUE, 6);

6. Task Dependencies (Зависимости задач)

CREATE TABLE task_dependencies (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    task_id UUID REFERENCES tasks(id) ON DELETE CASCADE,
    depends_on_task_id UUID REFERENCES tasks(id) ON DELETE CASCADE,
    dependency_type VARCHAR(50) DEFAULT 'finish_to_start', -- finish_to_start, start_to_start
    created_at TIMESTAMP DEFAULT NOW(),
    UNIQUE(task_id, depends_on_task_id)
);

7. Task History (История изменений)

CREATE TABLE task_history (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    task_id UUID REFERENCES tasks(id) ON DELETE CASCADE,
    user_id UUID REFERENCES users(id),
    action VARCHAR(100), -- created, status_changed, assigned, updated
    changes JSONB, -- {"field": "status", "old": "created", "new": "in_progress"}
    created_at TIMESTAMP DEFAULT NOW()
);

CREATE INDEX idx_task_history_task ON task_history(task_id, created_at DESC);

8. Task Attachments (Вложения)

CREATE TABLE task_attachments (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    task_id UUID REFERENCES tasks(id) ON DELETE CASCADE,
    file_id UUID REFERENCES files(id),
    attachment_type VARCHAR(50), -- photo_before, photo_after, document, voice
    uploaded_by UUID REFERENCES users(id),
    created_at TIMESTAMP DEFAULT NOW()
);

9. Files (Файлы)

CREATE TABLE files (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    filename VARCHAR(500),
    file_size BIGINT,
    mime_type VARCHAR(100),
    s3_bucket VARCHAR(255),
    s3_key VARCHAR(500),
    uploaded_by UUID REFERENCES users(id),
    created_at TIMESTAMP DEFAULT NOW()
);

10. Connections (Связи между адаптерами)

CREATE TABLE adapters (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name VARCHAR(255) NOT NULL,
    type VARCHAR(100), -- pms, erp, housekeeping, telegram, custom
    config JSONB, -- конфигурация подключения
    is_active BOOLEAN DEFAULT TRUE,
    created_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE connections (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    source_adapter_id UUID REFERENCES adapters(id),
    target_adapter_id UUID REFERENCES adapters(id),
    routing_rules JSONB DEFAULT '[]', -- массив правил маршрутизации
    is_enabled BOOLEAN DEFAULT TRUE,
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW()
);

11. Schedules (Расписания)

CREATE TABLE schedules (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    hotel_id UUID REFERENCES hotels(id),
    name VARCHAR(255),
    cron_expression VARCHAR(100), -- "0 8 * * *"
    task_template JSONB, -- шаблон задачи для создания
    timezone VARCHAR(50) DEFAULT 'UTC',
    is_enabled BOOLEAN DEFAULT TRUE,
    next_run TIMESTAMP,
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE schedule_executions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    schedule_id UUID REFERENCES schedules(id),
    executed_at TIMESTAMP DEFAULT NOW(),
    task_id UUID REFERENCES tasks(id), -- созданная задача
    status VARCHAR(50) -- success, failed
);

12. Roles & Permissions

CREATE TABLE roles (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    hotel_id UUID REFERENCES hotels(id), -- NULL для глобальных ролей
    name VARCHAR(100) NOT NULL,
    code VARCHAR(50), -- system_admin, support, hotel_admin, etc.
    is_custom BOOLEAN DEFAULT FALSE,
    created_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE permissions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    resource VARCHAR(100), -- tasks, users, connections, etc.
    action VARCHAR(50), -- create, read, update, delete
    description TEXT
);

CREATE TABLE role_permissions (
    role_id UUID REFERENCES roles(id),
    permission_id UUID REFERENCES permissions(id),
    PRIMARY KEY (role_id, permission_id)
);

CREATE TABLE user_roles (
    user_id UUID REFERENCES users(id),
    role_id UUID REFERENCES roles(id),
    hotel_id UUID REFERENCES hotels(id), -- в контексте какого отеля
    PRIMARY KEY (user_id, role_id, hotel_id)
);

Коммуникация между сервисами

1. Синхронная коммуникация (gRPC)

Используется для:

  • Запросы на чтение (GET операции)
  • Операции требующие немедленного ответа
  • Проверка прав доступа

Примеры:

  • API Gateway → Tasks Service: получение списка задач
  • API Gateway → Users Service: получение профиля пользователя
  • Tasks Service → Permissions Service: проверка прав доступа

2. Асинхронная коммуникация (Kafka)

Используется для:

  • Операции записи (создание, обновление)
  • Распространение событий
  • Интеграция между сервисами

Структура Kafka топиков:

tasks.created           # Создана новая задача
tasks.updated           # Задача обновлена
tasks.status_changed    # Изменен статус задачи
tasks.assigned          # Задача назначена
tasks.completed         # Задача выполнена

users.created
users.updated
users.deleted

connections.updated     # Обновлены связи
connections.route_task  # Маршрутизация задачи

notifications.send      # Отправить уведомление

scheduler.task_trigger  # Триггер для создания задачи по расписанию

adapters.*.message      # Сообщения от адаптеров (подстановочные топики)

audit.*                 # Все события для аудита

3. REST API (для внешних клиентов)

Используется для:

  • Web админка
  • Мобильные приложения (если gRPC не поддерживается)
  • Webhook endpoints для адаптеров

Контракт сообщений

Стандартизированное сообщение (Kafka Event)

{
  "event_id": "uuid",
  "event_type": "task.created",
  "timestamp": "2025-12-13T10:00:00Z",
  "version": "1.0",

  "source": {
    "service": "tasks-service",
    "adapter_id": "uuid",
    "system": "pms_opera"
  },

  "target": {
    "adapter_id": "uuid",
    "system": "housekeeping_app"
  },

  "payload": {
    "task": {
      "id": "uuid",
      "hotel_id": "uuid",
      "title": "Уборка номера 305",
      "description": "Гость выехал, требуется полная уборка",
      "task_type": "cleaning",
      "priority": "normal",
      "status": "created",

      "assignee": {
        "id": "uuid",
        "name": "Иванова Мария",
        "department": "housekeeping"
      },

      "metadata": {
        "room_number": "305",
        "checkout_time": "2025-12-13T12:00:00Z",
        "guest_name": "Петров А.А.",
        "special_requirements": []
      },

      "due_date": "2025-12-13T14:00:00Z",
      "created_at": "2025-12-13T10:00:00Z"
    }
  },

  "correlation_id": "uuid", // для трейсинга
  "causation_id": "uuid"    // ID события, которое вызвало это событие
}

Стандартизированное сообщение для адаптеров

Адаптеры преобразуют внешний формат в этот контракт:

{
  "message_id": "uuid",
  "message_type": "task_create_request",
  "timestamp": "2025-12-13T10:00:00Z",

  "source_system": "pms_opera",
  "target_system": "taskmanager",

  "hotel_id": "uuid",

  "data": {
    "task": {
      // стандартные поля задачи
    }
  },

  "external_reference": {
    "system": "pms_opera",
    "id": "OPERA-12345",
    "type": "reservation"
  }
}

Безопасность и авторизация

1. Аутентификация

  • JWT токены для API Gateway
  • mTLS для межсервисной коммуникации (gRPC)
  • API Keys для внешних систем (адаптеры)

2. Авторизация (RBAC)

Проверка прав на уровне:

  • API Gateway (базовая проверка роли)
  • Каждый сервис (детальная проверка permissions)

Формат JWT токена:

{
  "sub": "user_id",
  "email": "user@example.com",
  "hotels": ["hotel_id_1", "hotel_id_2"],
  "roles": [
    {
      "hotel_id": "hotel_id_1",
      "role": "hotel_admin"
    }
  ],
  "exp": 1234567890
}

3. Изоляция данных

  • Все запросы фильтруются по hotel_id на уровне БД
  • Row Level Security (RLS) в PostgreSQL
  • Пользователи видят только данные отелей, к которым у них есть доступ

Масштабирование

1. Horizontal Scaling

  • Все сервисы stateless и могут масштабироваться горизонтально
  • Kubernetes HPA (Horizontal Pod Autoscaler) на основе CPU/Memory

2. Database Scaling

  • Read Replicas для PostgreSQL
  • Connection Pooling (PgBouncer)
  • Партиционирование для больших таблиц (audit_log, task_history)

3. Kafka Scaling

  • Партиционирование топиков по hotel_id
  • Consumer Groups для параллельной обработки

4. Caching

  • Redis для кэширования:
    • Данных пользователей
    • Разрешений (permissions)
    • Конфигурации связей (connections)
    • Списков задач

Технологический стек

Backend Services

  • Язык: Python 3.11+
  • Фреймворк: FastAPI (для REST) + gRPC
  • ORM: SQLAlchemy
  • Миграции БД: Alembic

Message Broker

  • Apache Kafka (одиночный инстанс для MVP)

Databases

  • PostgreSQL 15+ (основная БД)
  • Redis 7+ (кэш, сессии)

File Storage

  • AWS S3 / MinIO (S3-compatible)

API Gateway

  • Kong / Envoy / NGINX + gRPC Gateway

Frontend

  • Framework: React 18+ с TypeScript
  • UI Library: Material-UI / Ant Design
  • State Management: Redux Toolkit / Zustand
  • API Client: gRPC-Web

Infrastructure

  • Containerization: Docker
  • Orchestration: Kubernetes
  • CI/CD: GitLab CI / GitHub Actions
  • Monitoring: Prometheus + Grafana
  • Logging: ELK Stack (Elasticsearch, Logstash, Kibana) / Loki
  • Tracing: Jaeger / OpenTelemetry

Development Tools

  • API Documentation: OpenAPI (Swagger) для REST, Buf для gRPC
  • Code Quality: Ruff, Black, MyPy
  • Testing: Pytest, pytest-asyncio

Следующие шаги

  1. Детальная проработка gRPC контрактов (.proto файлы)
  2. Проектирование REST API спецификации (OpenAPI)
  3. Разработка примера адаптера (PMS Adapter)
  4. Проектирование UI/UX для Web админки
  5. Настройка CI/CD pipeline
  6. Разработка Docker Compose для локальной разработки
  7. Kubernetes манифесты для деплоя