[Назад](/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 манифесты для деплоя