42 KiB
Архитектура системы TaskManager
Содержание
- Общее описание
- Архитектурные принципы
- Компоненты системы
- Микросервисы
- Модель данных
- Коммуникация между сервисами
- Контракт сообщений
- Безопасность и авторизация
- Масштабирование
- Технологический стек
Общее описание
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 URLDELETE /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 (Адаптеры)
Общая архитектура адаптера
Каждый адаптер - это отдельный микросервис, который:
- Подключается к внешней системе (API, БД, Webhook endpoint)
- Слушает Kafka топики для исходящих сообщений
- Преобразует данные в/из стандартизированного формата
- Публикует входящие сообщения в 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
Следующие шаги
- Детальная проработка gRPC контрактов (.proto файлы)
- Проектирование REST API спецификации (OpenAPI)
- Разработка примера адаптера (PMS Adapter)
- Проектирование UI/UX для Web админки
- Настройка CI/CD pipeline
- Разработка Docker Compose для локальной разработки
- Kubernetes манифесты для деплоя