219 lines
9.6 KiB
Markdown
219 lines
9.6 KiB
Markdown
# Handoff: миграция отчётов на Domain-архитектуру
|
||
|
||
Дата: 2026-04-26
|
||
|
||
## Что уже сделано
|
||
|
||
### 0. Обновление от 2026-04-27
|
||
|
||
Выполнен следующий шаг из handoff:
|
||
|
||
- добавлен `Infrastructure/Reports/Services/ReportStatisticsReadService`
|
||
- `ReportService::getReportStatistics` теперь делегирует в новый read-service
|
||
- из `ReportService` удалены legacy-private методы статистики:
|
||
- `getStatisticsFromSnapshots`
|
||
- `getStatisticsFromReplica`
|
||
- `getMetrikaResultCount`
|
||
- добавлена константа `MetrikaConfig::STAFF_COUNT`
|
||
- добавлены unit-тесты `ReportStatisticsReadServiceTest`
|
||
|
||
Выполнено продолжение:
|
||
|
||
- добавлен `Infrastructure/Reports/Services/ManualPatientManagementService`
|
||
- из `ReportService` вынесена orchestration manual/special пациентов:
|
||
- создание пациента
|
||
- исход пациента
|
||
- редактирование
|
||
- привязка к МИС
|
||
- операции manual/special пациента
|
||
- синхронизация manual-снапшотов
|
||
- `ReportService` сохраняет совместимые публичные методы, но теперь делегирует их в новый сервис
|
||
|
||
Выполнено финальное сужение legacy-фасада:
|
||
|
||
- добавлен `Infrastructure/Reports/Services/ReanimationIndicatorService`
|
||
- добавлен `Infrastructure/Reports/Services/ReportMetadataReadService`
|
||
- добавлен `Infrastructure/Reports/Services/ReportRuntimeService`
|
||
- добавлен `Infrastructure/Reports/Services/ReportSaveOrchestrator`
|
||
- добавлен `Infrastructure/Reports/Services/ObservationPatientManagementService`
|
||
- добавлен `Infrastructure/Reports/Services/ReportClinicalSearchService`
|
||
- legacy save fallback в `ReportSavePathService` больше не идёт через `ReportService`
|
||
- `LegacyReportServiceAdapter` больше не зависит от `ReportService`
|
||
- `ReportService` теперь совместимый фасад: публичные методы сохранены, бизнес-логика делегируется в новые сервисы
|
||
|
||
Проверка:
|
||
|
||
```bash
|
||
php artisan test tests/Unit/Reports
|
||
```
|
||
|
||
Результат: `19 passed`.
|
||
|
||
### 1. Базовый каркас Domain / Application / Infrastructure
|
||
Добавлены новые слои:
|
||
|
||
- `app/Domain/Reports`
|
||
- `app/Application/Reports`
|
||
- `app/Infrastructure/Reports`
|
||
|
||
Ключевые элементы:
|
||
|
||
- `Domain/Reports/ValueObjects/MetrikaConfig`
|
||
- `Domain/Reports/Models/ReportSnapshot`
|
||
- `Domain/Reports/Contracts/*`
|
||
- `Application/Reports/DTO/*`
|
||
- `Application/Reports/GenerateReportUseCase`
|
||
- `Application/Reports/CompareLegacyAndNewReportUseCase`
|
||
- `Infrastructure/Reports/Repositories/EloquentReportRepository`
|
||
- `Infrastructure/Reports/Adapters/LegacyReportServiceAdapter`
|
||
- `Infrastructure/Reports/Logging/ReportsAuditLogger`
|
||
|
||
### 2. Save-path уже переведён на strangler-схему
|
||
Новый save-flow работает рядом со старым кодом:
|
||
|
||
- старый `ReportService` не удалён
|
||
- новый путь включается через feature-flag
|
||
- legacy остаётся fallback
|
||
- сравнение old/new идёт через comparator и audit logger
|
||
|
||
Точки входа уже знают про новый flow:
|
||
|
||
- `app/Http/Controllers/Web/ReportController.php`
|
||
- `app/Http/Controllers/Api/ReportController.php`
|
||
- `app/Services/AutoReportService.php`
|
||
|
||
### 3. Вынесена существенная часть persistence и orchestration
|
||
Из `ReportService` уже выделены:
|
||
|
||
- `Infrastructure/Reports/Services/ReportStorageService`
|
||
- `Infrastructure/Reports/Services/ReportMetricsFinalizer`
|
||
- `Infrastructure/Reports/Services/CalculatedMetricsSynchronizer`
|
||
- `Infrastructure/Reports/Services/SnapshotPersistenceService`
|
||
- `Infrastructure/Reports/Services/AutoFillReportPayloadBuilder`
|
||
- `Infrastructure/Reports/Services/ManualPatientManagementService`
|
||
- `Infrastructure/Reports/Services/ReanimationIndicatorService`
|
||
- `Infrastructure/Reports/Services/ReportMetadataReadService`
|
||
- `Infrastructure/Reports/Services/ReportRuntimeService`
|
||
- `Infrastructure/Reports/Services/ReportSaveOrchestrator`
|
||
- `Infrastructure/Reports/Services/ObservationPatientManagementService`
|
||
- `Infrastructure/Reports/Services/ReportClinicalSearchService`
|
||
|
||
### 4. Вынесены источники данных
|
||
Сейчас выделены отдельные источники:
|
||
|
||
- `Infrastructure/Reports/Sources/MisPatientSource`
|
||
- `Infrastructure/Reports/Sources/SpecialPatientSource`
|
||
- `Infrastructure/Reports/Sources/SnapshotPatientSource`
|
||
- `Infrastructure/Reports/Sources/MisClinicalDataSource`
|
||
- `Infrastructure/Reports/Sources/LegacyAutoFillPatientSource`
|
||
|
||
### 5. Вынесены Domain-calculators
|
||
Сейчас в Domain уже есть:
|
||
|
||
- `BedDaysCalculator`
|
||
- `PreoperativeDaysCalculator`
|
||
- `DepartmentLoadCalculator`
|
||
|
||
### 6. Read-path пациентов тоже вынесен
|
||
Добавлены:
|
||
|
||
- `Infrastructure/Reports/Services/ReportPatientsReadService`
|
||
- `Infrastructure/Reports/Services/ReportReadContextResolver`
|
||
|
||
Теперь `ReportService` уже делегирует туда:
|
||
|
||
- `getPatientsByStatus`
|
||
- `getPatientsCountByStatus`
|
||
- `getPatientsCountsMap`
|
||
- `getPatientsFromSnapshots`
|
||
|
||
Это важный шаг: `ReportService` постепенно становится legacy facade, а не местом, где живёт вся логика.
|
||
|
||
## Что ещё специально НЕ сделано
|
||
|
||
- старый `ReportService` не удалён, но теперь это совместимый фасад
|
||
- полный cutover на новую архитектуру не выполнен
|
||
- контроллеры и `ReportPageService` всё ещё обращаются к `ReportService`, их можно переводить на конкретные сервисы после ручной проверки
|
||
- integration tests на SQLite здесь не гонялись, потому что в окружении нет `pdo_sqlite`
|
||
|
||
## Проверки и тесты
|
||
|
||
Проходит:
|
||
|
||
```bash
|
||
php artisan test tests/Unit/Reports
|
||
```
|
||
|
||
Сейчас зелёные unit-тесты для:
|
||
|
||
- `MetrikaConfig`
|
||
- `ReportSnapshot`
|
||
- `GenerateReportUseCase`
|
||
- `CompareLegacyAndNewReportUseCase`
|
||
- `ReportInputFactory`
|
||
- `ReportPatientsReadService`
|
||
- domain calculators
|
||
|
||
## Важный контекст по БД и тестам
|
||
|
||
Основное приложение работает с `pgsql` из `.env`, но тесты не обязаны использовать это окружение.
|
||
|
||
Важно:
|
||
|
||
- в `phpunit.xml` тестовый runtime жёстко переключён на `sqlite`
|
||
- в текущем окружении отсутствует `pdo_sqlite`
|
||
- поэтому feature/integration тесты здесь не были полноценно прогнаны
|
||
|
||
Если завтра нужно будет запускать integration-тесты на PostgreSQL, надо отдельно переводить test-конфиг.
|
||
|
||
## Дополнительные важные замечания
|
||
|
||
### 1. В worktree есть изменённые файлы
|
||
Нужно быть осторожным и не перетирать чужие правки.
|
||
|
||
Особенно внимательно смотреть на:
|
||
|
||
- `app/Http/Controllers/Api/ReportController.php`
|
||
- `app/Services/ReportService.php`
|
||
- `app/Services/Reports/PatientQueryBuilder.php`
|
||
|
||
### 2. Есть защитный фикс в конфиге Excel
|
||
Ранее был добавлен безопасный guard в `config/excel.php`, чтобы bootstrap не падал, если в окружении нет нужных excel-классов.
|
||
|
||
### 3. Комментарии в новом слое частично русифицированы
|
||
Русифицированы PHPDoc в основных новых infrastructure/application классах миграции.
|
||
При желании можно отдельным проходом довести до конца все новые DTO, адаптеры и domain models.
|
||
|
||
## Самый логичный следующий шаг
|
||
|
||
Следующая итерация:
|
||
|
||
1. Перевести контроллеры и `ReportPageService` с `ReportService` на конкретные application/infrastructure сервисы.
|
||
2. После ручной проверки удалить `ReportService` как совместимый фасад.
|
||
3. После полного cutover удалить `LegacyAutoFillPatientSource`/legacy comparison-обвязку или оставить только как диагностический инструмент.
|
||
|
||
Рекомендуемое направление:
|
||
|
||
- `ReportService` уже оставлен тонким фасадом
|
||
- переиспользовать `ReportReadContextResolver` для периодов и snapshot-vs-replica решений
|
||
- не удалять legacy save-flow до полного cutover и сравнения old/new
|
||
|
||
## Если нужно быстро продолжить завтра
|
||
|
||
Сначала открыть:
|
||
|
||
- `docs/report-domain-migration-handoff.md`
|
||
- `app/Services/ReportService.php`
|
||
- `app/Infrastructure/Reports/Services/ReportPatientsReadService.php`
|
||
- `app/Infrastructure/Reports/Services/ReportReadContextResolver.php`
|
||
|
||
Потом проверить:
|
||
|
||
```bash
|
||
php artisan test tests/Unit/Reports
|
||
```
|
||
|
||
И дальше брать следующий шаг:
|
||
|
||
- перевод контроллеров с `ReportService` на конкретные сервисы
|