mnemo_cards/mnemo_cards_backend/docs/SHOULD_EXTRACT_DATABASE.md

326 lines
11 KiB
Markdown
Raw Permalink Normal View History

2026-01-03 13:14:27 +00:00
# 📦 Стоит ли выносить Database (Drift + DAO) в отдельный пакет?
## 🤔 Краткий ответ
**Для текущего проекта: НЕТ, выносить не нужно.**
Но давайте разберем, когда это имеет смысл, а когда нет.
---
## ✅ Когда выносить имеет смысл
### 1. Множественное использование в разных проектах
Если database используется в нескольких независимых проектах:
```
mnemo_cards_database/ ← Отдельный пакет
├── lib/
│ ├── database.dart
│ ├── tables/
│ └── daos/
└── pubspec.yaml
mnemo_cards_backend/ ← Использует database
└── pubspec.yaml
dependencies:
mnemo_cards_database:
path: ../mnemo_cards_database
mnemo_cards_admin_tool/ ← Тоже использует database
└── pubspec.yaml
dependencies:
mnemo_cards_database:
path: ../mnemo_cards_database
mnemo_cards_analytics/ ← И это тоже
└── pubspec.yaml
dependencies:
mnemo_cards_database:
path: ../mnemo_cards_database
```
**Плюсы:**
- ✅ Переиспользование в нескольких проектах
- ✅ Централизованное управление схемой БД
- ✅ Общие миграции для всех проектов
- ✅ Избежание дублирования кода
**Когда это нужно:**
- У вас несколько backend сервисов (микросервисы)
- Есть отдельные инструменты (admin panel, analytics, migration tools)
- Разные команды работают с одной БД
---
### 2. Публикация как библиотека
Если вы хотите опубликовать database layer как отдельную библиотеку:
```yaml
# mnemo_cards_database/pubspec.yaml
name: mnemo_cards_database
version: 1.0.0
publish_to: pub.dev # Публикуется для всех
```
**Плюсы:**
- ✅ Можно использовать в других проектах
- ✅ Версионирование отдельно от backend
- ✅ Переиспользование в открытых проектах
---
### 3. Тестирование изолированно
Если нужно тестировать database layer отдельно:
```
mnemo_cards_database/
├── lib/
└── test/
└── database_test.dart # Тесты только для database
mnemo_cards_backend/
└── test/
└── integration_test.dart # Интеграционные тесты
```
**Плюсы:**
- ✅ Изолированное тестирование database layer
- ✅ Можно тестировать без запуска всего backend
**Но:** Обычно этого можно достичь и без вынесения в отдельный пакет.
---
## ❌ Когда выносить НЕ нужно (ваш случай)
### 1. Один проект использует database
**Текущая ситуация:**
```
mnemo_cards_backend/
├── lib/
│ ├── database/ ← Используется ТОЛЬКО здесь
│ │ ├── database.dart
│ │ ├── tables/
│ │ └── daos/
│ ├── api/ ← Использует database
│ ├── user/ ← Использует database
│ └── packs/ ← Использует database
└── pubspec.yaml
```
**Почему не нужно выносить:**
- ❌ Нет переиспользования (только один потребитель)
- ❌ Усложняет структуру проекта без выгоды
- ❌ Больше файлов для навигации
- ❌ Дополнительные настройки pubspec.yaml
- ❌ Усложняет рефакторинг (нужно менять два пакета)
---
### 2. Тесная связанность с бизнес-логикой
**В вашем проекте database тесно связана с backend:**
```dart
// database используется ВЕЗДЕ в backend
lib/api/v2/users_api_v2.dart → database
lib/user/user_manager.dart → database
lib/packs/pack_manager.dart → database
lib/api/purchase/payment_manager.dart → database
lib/cron/*.dart → database
```
**Проблемы при выносе:**
1. **Циклические зависимости:**
```
mnemo_cards_database/
└── нужно что-то из mnemo_cards_backend (конвертеры, хелперы)
mnemo_cards_backend/
└── зависит от mnemo_cards_database
```
2. **Конвертеры и extensions:**
```dart
// Где должны быть эти extensions?
extension UserToUserModel on User { ... } // В database или backend?
extension CardPackToCardPackModel on CardPack { ... }
```
3. **Зависимости:**
```dart
// database.dart использует converters.dart
// converters.dart может использовать что-то из backend
```
---
### 3. Database специфична для backend
**В вашем проекте:**
- Database структура создана специально для backend логики
- Таблицы отражают бизнес-логику backend
- DAO методы оптимизированы под нужды backend
- Нет планов использовать в других проектах
**Если database специфична для одного проекта - выносить не стоит.**
---
## 📊 Сравнение: Ваш проект vs Когда нужно выносить
| Критерий | Ваш проект | Когда нужно выносить |
|----------|------------|---------------------|
| **Количество потребителей** | 1 (только backend) | 3+ проекта |
| **Микросервисы** | Нет | Да, несколько сервисов |
| **Общая БД** | Одна БД для backend | Одна БД для многих сервисов |
| **Переиспользование** | Нет | Да, используется в разных местах |
| **Независимая разработка** | Нет | Да, разные команды |
| **Версионирование** | Одно с backend | Отдельное версионирование |
---
## 🎯 Альтернативы вынесению
### 1. Модульная структура внутри проекта
**Вместо отдельного пакета, используйте модульную структуру:**
```
mnemo_cards_backend/
├── lib/
│ ├── database/ ← Database модуль (НЕ отдельный пакет)
│ │ ├── database.dart
│ │ ├── tables/
│ │ └── daos/
│ ├── api/ ← API модуль
│ ├── user/ ← User модуль
│ └── packs/ ← Packs модуль
```
**Плюсы:**
- ✅ Четкое разделение ответственности
- ✅ Легко навигироваться
- ✅ Нет проблем с зависимостями
- ✅ Можно вынести позже, если понадобится
---
### 2. Barrel exports для изоляции
**Создайте единую точку входа для database:**
```dart
// lib/database/database.dart
export 'database_impl.dart';
export 'daos/user_dao.dart';
export 'daos/pack_dao.dart';
// ...
// Использование:
import 'package:mnemo_cards_backend/database/database.dart';
```
**Плюсы:**
- ✅ Чистые импорты
- ✅ Легко рефакторить (меняем только один файл)
- ✅ Можно вынести позже (меняем только exports)
---
## 🔮 Когда стоит пересмотреть решение
### Если появятся:
1. **Второй backend сервис:**
```
mnemo_cards_backend_api/ ← Основной API
mnemo_cards_backend_admin/ ← Admin API
```
→ Тогда имеет смысл вынести общую database
2. **Отдельные инструменты:**
```
mnemo_cards_migration_tool/ ← Миграции
mnemo_cards_analytics/ ← Аналитика
```
→ Тогда имеет смысл вынести database
3. **Публикация как библиотека:**
- Если планируется публикация на pub.dev
→ Тогда нужно вынести в отдельный пакет
---
## 💡 Рекомендации для вашего проекта
### ✅ Что делать СЕЙЧАС:
1. **Оставить database внутри backend:**
```
mnemo_cards_backend/
└── lib/
└── database/ ← Остается здесь
```
2. **Использовать модульную структуру:**
- Четко разделять database, api, user, packs модули
- Использовать barrel exports для чистоты импортов
3. **Документировать архитектуру:**
- Описать модульную структуру
- Объяснить, когда и как выносить в отдельный пакет
### ❌ Что НЕ делать:
1.Не выносить database в отдельный пакет без необходимости
2.Не усложнять структуру без реальной выгоды
3.Не создавать лишние абстракции
---
## 📝 Вывод
### Для вашего проекта: НЕ ВЫНОСИТЬ
**Причины:**
1. ✅ Database используется только в одном проекте (backend)
2. ✅ Тесная связанность с бизнес-логикой backend
3. ✅ Нет планов на переиспользование
4. ✅ Вынос усложнит структуру без выгоды
### Когда пересмотреть решение:
1. 🔄 Появится второй сервис, использующий ту же БД
2. 🔄 Появится отдельный инструмент (admin, analytics)
3. 🔄 Планируется публикация database как библиотеки
4. 🔄 Разные команды будут работать с database независимо
### Альтернатива:
✅ Используйте **модульную структуру** внутри проекта:
- Четкое разделение модулей
- Barrel exports для изоляции
- Легко вынести позже, если понадобится
---
**Итог:** Ваша текущая структура правильная для проекта с одним backend. Выносить database в отдельный пакет стоит только когда появится реальная необходимость (несколько потребителей, переиспользование).
2026-01-08 13:02:47 +00:00
2026-01-24 12:31:47 +00:00