Files
gridpilot.gg/plans/2025-12-15_clean-architecture-migration-plan.md
2025-12-15 15:47:34 +01:00

8.0 KiB
Raw Blame History

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 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.
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