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

1054 lines
42 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[Назад](/README.md)
# Архитектура системы 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**:
```protobuf
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`
**Модель связи** (направленная):
```json
{
"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**:
```protobuf
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**:
```protobuf
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**:
```protobuf
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**:
```protobuf
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.*`
**Модель лога**:
```json
{
"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**:
```protobuf
service AuditService {
rpc LogAction(LogActionRequest) returns (Empty);
rpc GetAuditLog(GetAuditLogRequest) returns (GetAuditLogResponse);
}
```
---
### 9. Scheduler Service
**Назначение**: Управление периодическими задачами
**Ответственность**:
- Создание расписаний для задач (cron-подобный синтаксис)
- Триггеринг создания задач по расписанию
- Управление повторяющимися задачами
**База данных**: PostgreSQL
- Таблицы: `schedules`, `schedule_executions`
**Модель расписания**:
```json
{
"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**:
```protobuf
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`
**Модель мероприятия**:
```json
{
"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**:
```protobuf
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 (Отели)
```sql
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 (Подразделения)
```sql
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 (Пользователи)
```sql
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 (Задачи)
```sql
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 (Статусы задач)
```sql
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 (Зависимости задач)
```sql
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 (История изменений)
```sql
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 (Вложения)
```sql
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 (Файлы)
```sql
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 (Связи между адаптерами)
```sql
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 (Расписания)
```sql
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
```sql
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)
```json
{
"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 события, которое вызвало это событие
}
```
### Стандартизированное сообщение для адаптеров
Адаптеры преобразуют внешний формат в этот контракт:
```json
{
"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 токена**:
```json
{
"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 манифесты для деплоя