From fc671482c861a7e76cd88060fcc33809b87488e5 Mon Sep 17 00:00:00 2001 From: Marc Mintel Date: Mon, 15 Dec 2025 15:47:34 +0100 Subject: [PATCH] wip --- ...12-15_clean-architecture-migration-plan.md | 153 ++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 plans/2025-12-15_clean-architecture-migration-plan.md diff --git a/plans/2025-12-15_clean-architecture-migration-plan.md b/plans/2025-12-15_clean-architecture-migration-plan.md new file mode 100644 index 000000000..8d6cdfb6d --- /dev/null +++ b/plans/2025-12-15_clean-architecture-migration-plan.md @@ -0,0 +1,153 @@ +# 2025-12-15 Clean Architecture Migration Plan for GridPilot + +## 1. Current State Summary + +- **Core**: Modular structure with domains (`analytics`, `automation`, `identity`, `media`, `notifications`, `racing`, `social`, `shared`). Contains pure domain elements (`entities`, `value-objects`, `repositories` interfaces, `use-cases`, `ports`). Violations: Infrastructure leaks (`infrastructure/repositories/InMemory*` in `analytics`, `automation`), adapters in `automation/infrastructure/adapters`. +- **Apps/API**: NestJS app with internal layers (`application/services`, `infrastructure/database`, `presentation/controllers`). Mostly placeholder (`hello.service`, `analytics.controller`). [`apps/api/src/infrastructure/database/database.module.ts`](apps/api/src/infrastructure/database/database.module.ts) suggests persistence setup but minimal implementation. +- **Apps/Website**: `lib/` holds DI (`di-container.ts`, `di-tokens.ts`), auth (`InMemoryAuthService.ts`), presenters (40+ `presenters/*.ts` – business logic mixed with presentation), utils. Presenters likely contain domain logic violating isolation. +- **Apps/Companion**: DI setup (`di-container.ts`), IPC handlers, renderer components. +- **Testing**: Comprehensive `/tests/` (`unit/`, `integration/`, `e2e/`, `smoke/`, `bdd/`) testing domains/use-cases. `/testing-support/` with fakers, demo adapters – partial match but not structured as `/testing/factories/fakes/fixtures/helpers`. +- **Persistence**: Sparse; no ORM entities, migrations, or real repos visible. In-memory only in core. +- **Overall**: Partial Clean Arch adoption in core domains; infra/UI mixing; no top-level `/adapters`; testing scattered. + +## 2. Gap Analysis per Layer/Domain + +### Core (Business Rules) +- **Compliant**: Domain entities/VO/services/use-cases/ports in `core/*/domain|application`. +- **Violations**: Infra in core (`InMemory repos`, adapters). Must extract to `/adapters`. +- **Domains**: `analytics` (page views), `automation` (racing wizards), `media` (avatars), `notifications`, `racing` (leagues/races), `social` – all need infra purge. + +### Adapters (Details) +- **Gap**: No `/adapters/` top-level. Persistence (typeorm/inmemory), auth/media/notifications/logging missing structure. +- **Action**: Move core infra; implement mappers, ORM entities, real repos. + +### Apps (Delivery) +- **Backend (API)**: Internal layers ok as composition root but move domain deps to core refs. +- **Frontend (Website/Companion)**: Presenters/DI in `lib/` – extract business to core use-cases, keep UI presenters thin. +- **Violations**: Domain logic in presenters (`LeagueStandingsPresenter.ts` etc.). + +### Testing +- **Gap**: `/tests/unit/domain/` mixes support/cases. `/testing-support/` unstructured. +- **Action**: Pure cases in `/tests`, support to `/testing/factories` etc. No DTOs in domain tests. + +### Persistence/Bootstrap +- **Gap**: No `/adapters/persistence/migrations`, `/adapters/bootstrap`. Database.module placeholder. + +## 3. Phased Migration Plan + +Focus: Backend/core first (Phases 1-7), then frontend (8-10), testing (11), verification (12). + +### Phase 1: Directory Setup & Skeleton +- **Scope**: Create dirs: `/adapters/persistence/{typeorm,inmemory}`, `/adapters/{auth,media,notifications,logging}`, `/adapters/bootstrap`, `/testing/{fixtures,factories,fakes,helpers}`, `/adapters/persistence/migrations`. +- **Focus**: Backend structure. +- **Prerequisites**: None. +- **Outcome**: Empty skeleton matching target. +- **Risks**: Path conflicts (low). + +### Phase 2: Purge Core Infrastructure – In-Memory Repos +- **Scope**: Move `core/*/infrastructure/repositories/InMemory*` → `/adapters/persistence/inmemory/*/InMemory*.ts`. Delete source dirs. Update core imports to ports only. +- **Focus**: Core purity (analytics, automation). +- **Prerequisites**: Phase 1. +- **Outcome**: Core interfaces-only repos. +- **Risks**: Import breaks in tests/use-cases. + +### Phase 3: Extract Automation Adapters +- **Scope**: Move `core/automation/infrastructure/adapters/*` → `/adapters/*` (e.g., logging → `/adapters/logging`). Update paths. +- **Focus**: Backend adapters. +- **Prerequisites**: Phase 2. +- **Outcome**: Centralized adapters. +- **Risks**: DI token mismatches. + +### Phase 4: Implement Persistence Mappers & ORM Skeleton +- **Scope**: Create `/adapters/persistence/typeorm/*/OrmEntity.ts`, `Mapper.ts` for key domains (racing League/Race, analytics PageView). Stub repos. +- **Focus**: Backend persistence. +- **Prerequisites**: Phase 1-3. +- **Outcome**: ORM ready for data migration. +- **Risks**: Schema design errors. + +### Phase 5: Migrate API Layers to Core Dependencies +- **Scope**: Refactor `apps/api/src/application/*`, `presentation/*` to use core use-cases/ports. Move `infrastructure/database/*` → `/adapters/persistence/typeorm`. +- **Focus**: Backend API. +- **Prerequisites**: Phase 4. +- **Outcome**: API as thin delivery. +- **Risks**: Controller logic loss. + +### Phase 6: Add Migrations & Bootstrap +- **Scope**: Create `/adapters/persistence/migrations/*.ts` for schema. `/adapters/bootstrap/EnsureInitialData.ts` using use-cases. +- **Focus**: Backend operability. +- **Prerequisites**: Phase 4. +- **Outcome**: Schema + bootstrap. +- **Risks**: Data loss on migrate. + +### Phase 7: Core Domain Refinements +- **Scope**: Enforce entities immutable/private ctor/factory methods across domains. Add domain events if missing. +- **Focus**: Backend core. +- **Prerequisites**: Phase 1-6. +- **Outcome**: Strict domain. +- **Risks**: Breaking changes in use-cases. + +### Phase 8: Refactor Website Presenters +- **Scope**: Extract business logic from `apps/website/lib/presenters/*` to core use cases/domain services; keep thin presenters in `apps/website/lib/presenters` as UI adapters implementing core output ports. +- **Focus**: Frontend/backend split. +- **Prerequisites**: Phase 7. +- **Outcome**: Business logic extracted to core; thin UI presenters remain in app. +- **Risks**: UI logic entanglement. +- **Presenter Note**: Core defines presenter interfaces (output ports) if needed; implementations (adapters) stay in apps/website. + +### Phase 9: Clean Frontend DI & Auth +- **Scope**: Remove `apps/website/lib/{di-*,auth/*}` or thin to delivery. Use core ports. +- **Focus**: Frontend. +- **Prerequisites**: Phase 8. +- **Outcome**: Apps pure delivery. +- **Risks**: Auth breakage. + +### Phase 10: Companion Alignment +- **Scope**: Align `apps/companion/{main/renderer/lib}` to use core/adapters. Extract any domain. +- **Focus**: Frontend. +- **Prerequisites**: Phase 9. +- **Outcome**: Consistent delivery. +- **Risks**: Electron IPC changes. + +### Phase 11: Testing Restructure +- **Scope**: Move test support to `/testing/factories/*Factory.ts`, `fakes/*Fake.ts`. Pure cases in `/tests`. Enforce no DTOs in domain tests. +- **Focus**: Testing. +- **Prerequisites**: All prior. +- **Outcome**: Strict testing. +- **Risks**: Test failures. + +### Phase 12: Verification & Enforcement +- **Scope**: Add ESLint/dependency-cruiser rules for layers. Run full test suite, e2e. +- **Focus**: All. +- **Prerequisites**: Phase 11. +- **Outcome**: Enforced architecture. +- **Risks**: Rule false positives. + +```mermaid +graph TD + A[Phase 1: Dirs] --> B[Phase 2: Core Purge] + B --> C[Phase 3: Adapters] + C --> D[Phase 4: ORM] + D --> E[Phase 5: API] + E --> F[Phase 6: Migrate/Bootstrap] + F --> G[Phase 7: Domain Refine] + G --> H[Phase 8: Refactor Website Presenters] + H --> I[Phase 9: Frontend Clean] + I --> J[Phase 10: Companion] + J --> K[Phase 11: Testing] + K --> L[Phase 12: Verify] +``` + +## 4. TODO Checklist + +- [ ] Phase 1: Directory Setup & Core Skeleton +- [ ] Phase 2: Purge Core Infrastructure – In-Memory Repos +- [ ] Phase 3: Extract Automation Adapters +- [ ] Phase 4: Implement Persistence Mappers & ORM Skeleton +- [ ] Phase 5: Migrate API Layers to Core Dependencies +- [ ] Phase 6: Add Migrations & Bootstrap +- [ ] Phase 7: Core Domain Refinements +- [ ] Phase 8: Refactor Website Presenters (logic to core use cases; thin adapters in app) +- [ ] Phase 9: Clean Frontend DI & Auth +- [ ] Phase 10: Companion Alignment +- [ ] Phase 11: Testing Restructure +- [ ] Phase 12: Verification & Enforcement