stuff
Some checks are pending
Backend CI / test (push) Waiting to run
Backend CI / build (push) Blocked by required conditions
Mobile App CI / test (push) Waiting to run
Mobile App CI / build-android (push) Blocked by required conditions
Mobile App CI / build-ios (push) Blocked by required conditions
Web App CI / test (push) Waiting to run
Web App CI / build (push) Blocked by required conditions
Deploy Mnemo Cards / Deploy Backend (push) Waiting to run
Deploy Mnemo Cards / Deploy Web App (push) Blocked by required conditions
Deploy Mnemo Cards / Final Verification (push) Blocked by required conditions
Deploy Telegram Bot / Deploy Telegram Bot (push) Waiting to run
Some checks are pending
Backend CI / test (push) Waiting to run
Backend CI / build (push) Blocked by required conditions
Mobile App CI / test (push) Waiting to run
Mobile App CI / build-android (push) Blocked by required conditions
Mobile App CI / build-ios (push) Blocked by required conditions
Web App CI / test (push) Waiting to run
Web App CI / build (push) Blocked by required conditions
Deploy Mnemo Cards / Deploy Backend (push) Waiting to run
Deploy Mnemo Cards / Deploy Web App (push) Blocked by required conditions
Deploy Mnemo Cards / Final Verification (push) Blocked by required conditions
Deploy Telegram Bot / Deploy Telegram Bot (push) Waiting to run
This commit is contained in:
parent
9c2456f685
commit
8d3d4cd1f7
5 changed files with 2105 additions and 0 deletions
|
|
@ -0,0 +1,57 @@
|
|||
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
group('MatrixTestQuestionBody', () {
|
||||
test('json roundtrip preserves fields', () {
|
||||
final body = MatrixTestQuestionBody(
|
||||
id: 'q1',
|
||||
matrixSize: 3,
|
||||
word: 'hola',
|
||||
answer: 'card_1',
|
||||
cards: const [
|
||||
MatrixCardDto(
|
||||
id: 'card_1',
|
||||
image: '/api/v2/packs/p1/cards/card_1/image',
|
||||
original: 'hola',
|
||||
translation: 'привет',
|
||||
),
|
||||
MatrixCardDto(
|
||||
id: 'card_2',
|
||||
image: '/api/v2/packs/p1/cards/card_2/image',
|
||||
original: 'adios',
|
||||
translation: 'пока',
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
final json = body.toJson();
|
||||
final parsed = AbstractTestQuestion.fromJson(json) as MatrixTestQuestionBody;
|
||||
|
||||
expect(parsed.questionType, TestQuestionType.matrix);
|
||||
expect(parsed.id, 'q1');
|
||||
expect(parsed.matrixSize, 3);
|
||||
expect(parsed.word, 'hola');
|
||||
expect(parsed.answer, 'card_1');
|
||||
expect(parsed.cards.length, 2);
|
||||
expect(parsed.cards.first.original, 'hola');
|
||||
expect(parsed.cards.first.translation, 'привет');
|
||||
expect(parsed.cards.first.image, contains('/cards/card_1/image'));
|
||||
});
|
||||
|
||||
test('matrixSize falls back to default when missing', () {
|
||||
final json = <String, dynamic>{
|
||||
'questionType': 'matrix',
|
||||
'id': 'q1',
|
||||
'word': 'hola',
|
||||
'answer': 'card_1',
|
||||
'buttons': const [],
|
||||
};
|
||||
|
||||
final parsed = AbstractTestQuestion.fromJson(json) as MatrixTestQuestionBody;
|
||||
expect(parsed.matrixSize, 3);
|
||||
expect(parsed.cards, isEmpty);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
121
mnemo_cards_common/test/user_dto_telegram_test.dart
Normal file
121
mnemo_cards_common/test/user_dto_telegram_test.dart
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
import 'package:test/test.dart';
|
||||
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
||||
|
||||
void main() {
|
||||
group('UserDto telegram field', () {
|
||||
test('should serialize and deserialize with telegram', () {
|
||||
final userDto = UserDto(
|
||||
id: 'test-id',
|
||||
name: 'Test User',
|
||||
email: 'test@example.com',
|
||||
telegram: '@testuser',
|
||||
admin: false,
|
||||
packs: ['pack1', 'pack2'],
|
||||
purchases: ['purchase1'],
|
||||
);
|
||||
|
||||
final json = userDto.toJson();
|
||||
expect(json['telegram'], equals('@testuser'));
|
||||
expect(json['email'], equals('test@example.com'));
|
||||
|
||||
final deserialized = UserDto.fromJson(json);
|
||||
expect(deserialized.telegram, equals('@testuser'));
|
||||
expect(deserialized.email, equals('test@example.com'));
|
||||
expect(deserialized.name, equals('Test User'));
|
||||
});
|
||||
|
||||
test('should handle null telegram', () {
|
||||
final userDto = UserDto(
|
||||
id: 'test-id',
|
||||
name: 'Test User',
|
||||
email: 'test@example.com',
|
||||
telegram: null,
|
||||
admin: false,
|
||||
);
|
||||
|
||||
final json = userDto.toJson();
|
||||
expect(json['telegram'], isNull);
|
||||
|
||||
final deserialized = UserDto.fromJson(json);
|
||||
expect(deserialized.telegram, isNull);
|
||||
expect(deserialized.email, equals('test@example.com'));
|
||||
});
|
||||
|
||||
test('should handle missing telegram in JSON', () {
|
||||
final json = {
|
||||
'id': 'test-id',
|
||||
'name': 'Test User',
|
||||
'email': 'test@example.com',
|
||||
'admin': false,
|
||||
'packs': <String>[],
|
||||
'purchases': <String>[],
|
||||
};
|
||||
|
||||
final userDto = UserDto.fromJson(json);
|
||||
expect(userDto.telegram, isNull);
|
||||
expect(userDto.email, equals('test@example.com'));
|
||||
});
|
||||
|
||||
test('should support telegram without email for Telegram-only users', () {
|
||||
final userDto = UserDto(
|
||||
id: 'test-id',
|
||||
name: 'Telegram User',
|
||||
email: null,
|
||||
telegram: '@telegram_only',
|
||||
admin: false,
|
||||
);
|
||||
|
||||
final json = userDto.toJson();
|
||||
expect(json['telegram'], equals('@telegram_only'));
|
||||
expect(json['email'], isNull);
|
||||
|
||||
final deserialized = UserDto.fromJson(json);
|
||||
expect(deserialized.telegram, equals('@telegram_only'));
|
||||
expect(deserialized.email, isNull);
|
||||
});
|
||||
|
||||
test('should work with copyWith for telegram', () {
|
||||
final userDto = UserDto(
|
||||
id: 'test-id',
|
||||
name: 'Test User',
|
||||
email: 'test@example.com',
|
||||
telegram: '@oldusername',
|
||||
admin: false,
|
||||
);
|
||||
|
||||
final updated = userDto.copyWith(telegram: '@newusername');
|
||||
expect(updated.telegram, equals('@newusername'));
|
||||
expect(updated.email, equals('test@example.com'));
|
||||
expect(userDto.telegram, equals('@oldusername')); // Original unchanged
|
||||
});
|
||||
|
||||
test('should handle both email and telegram contact methods', () {
|
||||
final userDto = UserDto(
|
||||
id: 'test-id',
|
||||
name: 'Test User',
|
||||
email: 'user@example.com',
|
||||
telegram: '@testuser',
|
||||
admin: true,
|
||||
packs: ['pack1'],
|
||||
purchases: ['purchase1'],
|
||||
);
|
||||
|
||||
expect(userDto.email, equals('user@example.com'));
|
||||
expect(userDto.telegram, equals('@testuser'));
|
||||
expect(userDto.admin, isTrue);
|
||||
|
||||
final json = userDto.toJson();
|
||||
final deserialized = UserDto.fromJson(json);
|
||||
|
||||
expect(deserialized.email, equals('user@example.com'));
|
||||
expect(deserialized.telegram, equals('@testuser'));
|
||||
expect(deserialized.admin, isTrue);
|
||||
});
|
||||
|
||||
test('empty UserDto should have null telegram', () {
|
||||
final empty = UserDto.empty;
|
||||
expect(empty.telegram, isNull);
|
||||
expect(empty.email, isNull);
|
||||
});
|
||||
});
|
||||
}
|
||||
32
plans/README.md
Normal file
32
plans/README.md
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
# 📋 Планы на будущее
|
||||
|
||||
Эта папка содержит планы развития проекта Mnemo Cards.
|
||||
|
||||
## Структура
|
||||
|
||||
Планы сохраняются в формате Markdown с описанием задач, архитектурных решений и стратегий развития.
|
||||
|
||||
## Текущие планы
|
||||
|
||||
- **[микросервисная_архитектура.md](./микросервисная_архитектура.md)** - План разделения монолитного backend на микросервисы
|
||||
|
||||
## Формат планов
|
||||
|
||||
Каждый план содержит:
|
||||
|
||||
- **Название и краткое описание** - что планируется сделать
|
||||
- **Анализ текущего состояния** - что есть сейчас
|
||||
- **Детальный план** - как будет реализовано
|
||||
- **TODO список** - конкретные задачи для выполнения
|
||||
- **Риски и митигация** - потенциальные проблемы и способы их решения
|
||||
|
||||
## Использование
|
||||
|
||||
Планы используются для:
|
||||
|
||||
- Архитектурных решений
|
||||
- Долгосрочного планирования
|
||||
- Документирования стратегических изменений
|
||||
- Координации работы команды
|
||||
|
||||
После начала реализации плана, TODO список обновляется для отслеживания прогресса.
|
||||
1352
plans/telegram_bot_product_features.md
Normal file
1352
plans/telegram_bot_product_features.md
Normal file
File diff suppressed because it is too large
Load diff
543
plans/микросервисная_архитектура.md
Normal file
543
plans/микросервисная_архитектура.md
Normal file
|
|
@ -0,0 +1,543 @@
|
|||
---
|
||||
name: Микросервисная архитектура Mnemo Cards
|
||||
overview: План разделения монолитного backend на микросервисы с учетом независимого деплоя, разных технологий и организации команды. Используется гибридный подход к базам данных.
|
||||
todos:
|
||||
- id: analyze_dependencies
|
||||
content: Проанализировать зависимости между модулями и создать карту зависимостей
|
||||
status: pending
|
||||
- id: design_api_gateway
|
||||
content: Спроектировать API Gateway для маршрутизации запросов к микросервисам
|
||||
status: pending
|
||||
- id: create_shared_jwt_lib
|
||||
content: Создать shared библиотеку для валидации JWT токенов
|
||||
status: pending
|
||||
- id: plan_database_migration
|
||||
content: Спланировать миграцию базы данных (схемы/отдельные БД)
|
||||
status: pending
|
||||
- id: extract_auth_service
|
||||
content: Выделить Auth Service как первый микросервис
|
||||
status: pending
|
||||
- id: extract_payment_service
|
||||
content: Выделить Payment Service как второй микросервис
|
||||
status: pending
|
||||
- id: setup_service_communication
|
||||
content: Настроить коммуникацию между сервисами (синхронная/асинхронная)
|
||||
status: pending
|
||||
- id: setup_monitoring
|
||||
content: Настроить мониторинг и логирование для микросервисов
|
||||
status: pending
|
||||
- id: create_docker_compose
|
||||
content: Создать docker-compose для локальной разработки всех микросервисов
|
||||
status: pending
|
||||
---
|
||||
|
||||
# План разделения на микросервисы
|
||||
|
||||
## Анализ текущей архитектуры
|
||||
|
||||
Текущий монолит включает следующие доменные области:
|
||||
|
||||
1. **Authentication & User Management** - JWT, Telegram auth, пользователи
|
||||
2. **Content Management** - Packs, Cards, Tests, Games
|
||||
3. **Payments & Subscriptions** - YooKassa, Google Play, RuStore
|
||||
4. **Statistics & Analytics** - User statistics, achievements, word statistics
|
||||
5. **Admin Panel** - Админские функции
|
||||
6. **Telegram Bot** - Бот для авторизации
|
||||
7. **Cron Jobs & Background Tasks** - Фоновые задачи
|
||||
|
||||
## Предлагаемое разделение на микросервисы
|
||||
|
||||
### 1. **Auth Service** (Сервис аутентификации)
|
||||
|
||||
**Ответственность:**
|
||||
|
||||
- JWT токены (access/refresh)
|
||||
- Регистрация/логин пользователей
|
||||
- Telegram авторизация (генерация кодов)
|
||||
- Управление пользователями (CRUD)
|
||||
- ACL и авторизация
|
||||
|
||||
**База данных:**
|
||||
|
||||
- `users`, `auth`, `tokens`, `refresh_tokens`, `telegram_auth_codes`
|
||||
|
||||
**API Endpoints:**
|
||||
|
||||
- `/api/v2/auth/*` (register, login, refresh, logout, telegram)
|
||||
- `/api/v2/users/*` (CRUD пользователей)
|
||||
|
||||
**Зависимости:**
|
||||
|
||||
- PostgreSQL (собственная схема)
|
||||
- Telegram Bot API (для авторизации)
|
||||
|
||||
**Технологии:**
|
||||
|
||||
- Dart + Shelf (можно оставить или перейти на Go/Node.js)
|
||||
|
||||
**Особенности:**
|
||||
|
||||
- Критический сервис - должен быть высокодоступным
|
||||
- Низкая задержка критична для всех запросов
|
||||
|
||||
---
|
||||
|
||||
### 2. **Content Service** (Сервис контента)
|
||||
|
||||
**Ответственность:**
|
||||
|
||||
- Управление паками карточек (CardPacks)
|
||||
- Управление карточками (GameCards)
|
||||
- Управление тестами (Tests)
|
||||
- Управление играми (Games assets)
|
||||
- Голоса карточек (CardVoices)
|
||||
- Доступ к контенту (проверка прав доступа через Auth Service)
|
||||
|
||||
**База данных:**
|
||||
|
||||
- `card_packs`, `game_cards`, `card_pack_cards`, `card_voices`, `tests`, `tasks`
|
||||
|
||||
**API Endpoints:**
|
||||
|
||||
- `/api/v2/packs/*`
|
||||
- `/api/v2/tests/*`
|
||||
- `/api/v2/games/*`
|
||||
- `/api/v2/voice/*`
|
||||
|
||||
**Зависимости:**
|
||||
|
||||
- PostgreSQL (собственная схема или shared с Payments для связей)
|
||||
- Auth Service (проверка доступа через API или shared token validation)
|
||||
|
||||
**Технологии:**
|
||||
|
||||
- Dart + Shelf (можно перейти на Python/FastAPI для удобства работы с контентом)
|
||||
|
||||
**Особенности:**
|
||||
|
||||
- Статические файлы (изображения, аудио) - можно вынести в CDN/Storage
|
||||
- Высокая нагрузка на чтение
|
||||
|
||||
---
|
||||
|
||||
### 3. **Payment Service** (Сервис платежей)
|
||||
|
||||
**Ответственность:**
|
||||
|
||||
- Обработка платежей через YooKassa
|
||||
- Обработка IAP (Google Play, RuStore)
|
||||
- Управление промокодами
|
||||
- Управление скидками (discounts)
|
||||
- Покупка паков
|
||||
- Webhooks от платежных систем
|
||||
|
||||
**База данных:**
|
||||
|
||||
- `payments`, `promo_codes`, `discounts`, `subscriptions` (или отдельный сервис)
|
||||
|
||||
**API Endpoints:**
|
||||
|
||||
- `/api/v2/purchases/*`
|
||||
- `/api/v2/promocodes/*`
|
||||
- `/api/v2/discounts/*`
|
||||
- `/api/webhooks/yookassa`, `/api/webhooks/google-play`, `/api/webhooks/rustore`
|
||||
|
||||
**Зависимости:**
|
||||
|
||||
- PostgreSQL (собственная схема)
|
||||
- Auth Service (проверка пользователя)
|
||||
- Content Service (информация о паках для покупки)
|
||||
- YooKassa API, Google Play API, RuStore API
|
||||
|
||||
**Технологии:**
|
||||
|
||||
- Dart + Shelf или Node.js/TypeScript (удобная работа с webhooks)
|
||||
|
||||
**Особенности:**
|
||||
|
||||
- Высокие требования к безопасности
|
||||
- Идемпотентность операций
|
||||
- Обработка webhooks
|
||||
|
||||
---
|
||||
|
||||
### 4. **Subscription Service** (Сервис подписок)
|
||||
|
||||
**Ответственность:**
|
||||
|
||||
- Управление подписками пользователей
|
||||
- Проверка активности подписки
|
||||
- Фичи подписки
|
||||
- Автопродление (через cron)
|
||||
|
||||
**База данных:**
|
||||
|
||||
- `subscriptions` (может быть shared с Payment Service на этапе миграции)
|
||||
|
||||
**API Endpoints:**
|
||||
|
||||
- `/api/v2/subscriptions/*`
|
||||
|
||||
**Зависимости:**
|
||||
|
||||
- PostgreSQL (собственная схема или shared с Payment)
|
||||
- Auth Service (проверка пользователя)
|
||||
- Payment Service (создание подписки через платеж)
|
||||
|
||||
**Технологии:**
|
||||
|
||||
- Dart + Shelf или отдельный микросервис
|
||||
|
||||
**Вариант:** Можно объединить с Payment Service на первом этапе, если логика тесно связана.
|
||||
|
||||
---
|
||||
|
||||
### 5. **Statistics Service** (Сервис статистики)
|
||||
|
||||
**Ответственность:**
|
||||
|
||||
- Статистика пользователей (user statistics)
|
||||
- Статистика по словам (word statistics)
|
||||
- Достижения (achievements)
|
||||
- Сессии обучения (study sessions)
|
||||
- Аналитика и отчеты
|
||||
|
||||
**База данных:**
|
||||
|
||||
- `user_datas`, `word_statistics`, `achievements`, `study_sessions`, `pack_progress`
|
||||
|
||||
**API Endpoints:**
|
||||
|
||||
- `/api/v2/users/me/statistics/*`
|
||||
- `/api/v2/users/me/achievements`
|
||||
- `/api/v2/users/me/sessions`
|
||||
|
||||
**Зависимости:**
|
||||
|
||||
- PostgreSQL (собственная схема или отдельная БД для аналитики - TimescaleDB/ClickHouse)
|
||||
- Auth Service (проверка пользователя)
|
||||
- Content Service (информация о паках/карточках)
|
||||
|
||||
**Технологии:**
|
||||
|
||||
- Dart + Shelf или Python (удобно для аналитики) или Go (высокая производительность)
|
||||
|
||||
**Особенности:**
|
||||
|
||||
- Высокая нагрузка на запись (tracking событий)
|
||||
- Возможность использовать TimescaleDB для временных рядов
|
||||
- Отложенная обработка данных (бэтчинг)
|
||||
|
||||
---
|
||||
|
||||
### 6. **Admin Service** (Админ панель)
|
||||
|
||||
**Ответственность:**
|
||||
|
||||
- Админская авторизация
|
||||
- Управление контентом (CRUD паков, карточек)
|
||||
- Аналитика для админов
|
||||
- Управление пользователями
|
||||
- Audit логирование
|
||||
|
||||
**База данных:**
|
||||
|
||||
- `audit` (отдельная таблица для логирования действий)
|
||||
- Использует данные из других сервисов
|
||||
|
||||
**API Endpoints:**
|
||||
|
||||
- `/api/v2/admin/*`
|
||||
|
||||
**Зависимости:**
|
||||
|
||||
- Auth Service (проверка админ прав)
|
||||
- Content Service (управление контентом)
|
||||
- Payment Service (управление платежами)
|
||||
- Statistics Service (аналитика)
|
||||
|
||||
**Технологии:**
|
||||
|
||||
- Dart + Shelf (можно оставить текущий стек)
|
||||
|
||||
**Особенности:**
|
||||
|
||||
- Агрегирует данные из нескольких сервисов
|
||||
- Требует высоких прав доступа
|
||||
|
||||
---
|
||||
|
||||
### 7. **Telegram Bot Service** (Сервис Telegram бота)
|
||||
|
||||
**Ответственность:**
|
||||
|
||||
- Обработка команд Telegram бота
|
||||
- Генерация кодов авторизации для веба
|
||||
- Интеграция с Auth Service
|
||||
|
||||
**База данных:**
|
||||
|
||||
- Может использовать shared `telegram_auth_codes` или собственную
|
||||
|
||||
**API Endpoints:**
|
||||
|
||||
- `/api/v2/telegram-bot/*`
|
||||
- Telegram Bot API webhook
|
||||
|
||||
**Зависимости:**
|
||||
|
||||
- Auth Service (создание/проверка кодов)
|
||||
- Telegram Bot API
|
||||
|
||||
**Технологии:**
|
||||
|
||||
- Dart + Shelf или Node.js/TypeScript (удобные библиотеки для Telegram)
|
||||
|
||||
**Особенности:**
|
||||
|
||||
- Относительно изолированный сервис
|
||||
- Может работать независимо
|
||||
|
||||
---
|
||||
|
||||
### 8. **Background Jobs Service** (Сервис фоновых задач)
|
||||
|
||||
**Ответственность:**
|
||||
|
||||
- Cron задачи (backup, проверка платежей, генерация промокодов, etc.)
|
||||
- Асинхронная обработка задач
|
||||
- Очереди задач (опционально)
|
||||
|
||||
**Зависимости:**
|
||||
|
||||
- Все остальные сервисы (для выполнения задач)
|
||||
|
||||
**Технологии:**
|
||||
|
||||
- Dart (текущий стек) или перейти на специализированное решение (Bull/BullMQ на Node.js, Celery на Python)
|
||||
|
||||
**Альтернатива:** Можно интегрировать в каждый сервис отдельно или использовать общий Job Queue (Redis + Worker).
|
||||
|
||||
---
|
||||
|
||||
## Стратегия миграции
|
||||
|
||||
### Фаза 1: Подготовка (1-2 недели)
|
||||
|
||||
1. **Выделить общие компоненты:**
|
||||
|
||||
- Общие DTO/models в `mnemo_cards_common`
|
||||
- Shared database connection pool
|
||||
- API Gateway (опционально, можно использовать nginx/kong)
|
||||
|
||||
2. **Создать API Gateway:**
|
||||
|
||||
- Единая точка входа для клиентов
|
||||
- Маршрутизация к микросервисам
|
||||
- Агрегация запросов (если нужно)
|
||||
- Rate limiting, CORS
|
||||
|
||||
### Фаза 2: Выделение критических сервисов (2-4 недели)
|
||||
|
||||
**Приоритет 1: Auth Service**
|
||||
|
||||
- Выделить аутентификацию в отдельный сервис
|
||||
- Создать JWT validation library для других сервисов
|
||||
- Мигрировать пользователей
|
||||
|
||||
**Приоритет 2: Payment Service**
|
||||
|
||||
- Выделить платежи
|
||||
- Изолировать webhooks
|
||||
- Мигрировать платежные данные
|
||||
|
||||
### Фаза 3: Выделение остальных сервисов (4-8 недель)
|
||||
|
||||
**Приоритет 3: Content Service**
|
||||
|
||||
- Выделить управление контентом
|
||||
- Вынести статические файлы в CDN/Storage
|
||||
|
||||
**Приоритет 4: Statistics Service**
|
||||
|
||||
- Выделить статистику
|
||||
- Оптимизировать запись данных (бэтчинг)
|
||||
|
||||
**Приоритет 5: Остальные сервисы**
|
||||
|
||||
- Admin Service
|
||||
- Telegram Bot Service
|
||||
- Background Jobs Service
|
||||
|
||||
### Фаза 4: Оптимизация (ongoing)
|
||||
|
||||
- Разделение баз данных (Database per Service)
|
||||
- Кэширование (Redis)
|
||||
- Message Queue для асинхронной коммуникации
|
||||
- Мониторинг и логирование (ELK, Prometheus)
|
||||
|
||||
---
|
||||
|
||||
## Схема коммуникации между сервисами
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
Client[Web Client] --> Gateway[API Gateway]
|
||||
|
||||
Gateway --> AuthService[Auth Service]
|
||||
Gateway --> ContentService[Content Service]
|
||||
Gateway --> PaymentService[Payment Service]
|
||||
Gateway --> SubscriptionService[Subscription Service]
|
||||
Gateway --> StatisticsService[Statistics Service]
|
||||
Gateway --> AdminService[Admin Service]
|
||||
|
||||
TelegramBot[Telegram Bot] --> AuthService
|
||||
TelegramBot --> Gateway
|
||||
|
||||
PaymentService --> AuthService
|
||||
PaymentService --> ContentService
|
||||
SubscriptionService --> AuthService
|
||||
SubscriptionService --> PaymentService
|
||||
StatisticsService --> AuthService
|
||||
StatisticsService --> ContentService
|
||||
AdminService --> AuthService
|
||||
AdminService --> ContentService
|
||||
AdminService --> PaymentService
|
||||
AdminService --> StatisticsService
|
||||
|
||||
BackgroundJobs[Background Jobs] --> AuthService
|
||||
BackgroundJobs --> PaymentService
|
||||
BackgroundJobs --> StatisticsService
|
||||
|
||||
AuthService --> AuthDB[(Auth DB)]
|
||||
ContentService --> ContentDB[(Content DB)]
|
||||
PaymentService --> PaymentDB[(Payment DB)]
|
||||
SubscriptionService --> SubscriptionDB[(Subscription DB)]
|
||||
StatisticsService --> StatisticsDB[(Statistics DB)]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Рекомендации по базам данных (гибридный подход)
|
||||
|
||||
### Вариант 1: Shared Database на первом этапе
|
||||
|
||||
- Все сервисы используют одну БД, но разные схемы (namespaces)
|
||||
- Упрощает миграцию
|
||||
- Позволяет постепенно разделять
|
||||
|
||||
### Вариант 2: Database per Service (целевое состояние)
|
||||
|
||||
**Auth Service:**
|
||||
|
||||
- `auth_db` - users, tokens, refresh_tokens, telegram_auth_codes
|
||||
|
||||
**Content Service:**
|
||||
|
||||
- `content_db` - card_packs, game_cards, card_voices, tests, tasks
|
||||
|
||||
**Payment Service:**
|
||||
|
||||
- `payment_db` - payments, promo_codes, discounts
|
||||
|
||||
**Subscription Service:**
|
||||
|
||||
- `subscription_db` - subscriptions
|
||||
|
||||
**Statistics Service:**
|
||||
|
||||
- `statistics_db` - user_datas, word_statistics, achievements, study_sessions
|
||||
- Или TimescaleDB для временных рядов
|
||||
|
||||
### Переходные связи:
|
||||
|
||||
Для связей между сервисами использовать:
|
||||
|
||||
- **API calls** - синхронная коммуникация (для проверки доступа, получения данных)
|
||||
- **Event-driven** - асинхронная коммуникация (опционально, через message queue)
|
||||
- **Shared IDs** - использование UUID для связи между сервисами
|
||||
|
||||
---
|
||||
|
||||
## Технологические рекомендации
|
||||
|
||||
### API Gateway
|
||||
|
||||
- **Kong** или **nginx** - для маршрутизации
|
||||
- Или **Istio** для более сложных сценариев
|
||||
|
||||
### Service Mesh (опционально)
|
||||
|
||||
- **Istio** или **Linkerd** - для управления трафиком, безопасности, observability
|
||||
|
||||
### Message Queue (для асинхронной коммуникации)
|
||||
|
||||
- **Redis Pub/Sub** или **RabbitMQ** или **NATS**
|
||||
- Для событий: payment_completed, user_registered, etc.
|
||||
|
||||
### Мониторинг
|
||||
|
||||
- **Prometheus + Grafana** - метрики
|
||||
- **ELK Stack** (Elasticsearch, Logstash, Kibana) - логи
|
||||
- **Jaeger** или **Zipkin** - distributed tracing
|
||||
|
||||
### Кэширование
|
||||
|
||||
- **Redis** - для кэширования токенов, контента, статистики
|
||||
|
||||
---
|
||||
|
||||
## Файлы, которые нужно будет изменить/создать
|
||||
|
||||
### Новые директории для микросервисов:
|
||||
|
||||
- `services/auth-service/`
|
||||
- `services/content-service/`
|
||||
- `services/payment-service/`
|
||||
- `services/subscription-service/`
|
||||
- `services/statistics-service/`
|
||||
- `services/admin-service/`
|
||||
- `services/telegram-bot-service/`
|
||||
- `services/background-jobs-service/`
|
||||
|
||||
### Общие компоненты:
|
||||
|
||||
- `shared/jwt-validator/` - библиотека для валидации JWT
|
||||
- `shared/database-migrations/` - миграции БД
|
||||
- `shared/common-models/` - общие модели (уже есть в `mnemo_cards_common`)
|
||||
|
||||
### Конфигурация:
|
||||
|
||||
- `docker-compose.microservices.yml` - оркестрация всех сервисов
|
||||
- `infrastructure/` - terraform/k8s конфигурации
|
||||
|
||||
---
|
||||
|
||||
## Критерии успешности разделения
|
||||
|
||||
1. ✅ Каждый сервис можно деплоить независимо
|
||||
2. ✅ Сервисы могут использовать разные технологии
|
||||
3. ✅ Отказ одного сервиса не ломает остальные
|
||||
4. ✅ Легко масштабировать отдельные сервисы
|
||||
5. ✅ Четкое разделение ответственности
|
||||
6. ✅ Тестируемость каждого сервиса отдельно
|
||||
|
||||
---
|
||||
|
||||
## Риски и митигация
|
||||
|
||||
### Риск 1: Сложность отладки распределенной системы
|
||||
|
||||
**Митигация:** Использовать distributed tracing (Jaeger), централизованное логирование
|
||||
|
||||
### Риск 2: Сетевая задержка между сервисами
|
||||
|
||||
**Митигация:** Кэширование, асинхронная коммуникация где возможно, оптимизация API calls
|
||||
|
||||
### Риск 3: Консистентность данных между сервисами
|
||||
|
||||
**Митигация:** Event-driven архитектура, eventual consistency, saga pattern для транзакций
|
||||
|
||||
### Риск 4: Усложнение деплоя
|
||||
|
||||
**Митигация:** Docker Compose для разработки, Kubernetes для продакшена, CI/CD для каждого сервиса
|
||||
Loading…
Reference in a new issue