Skip to content

Refactor: Introduce Domain Services & Clean API Layer for Codele #8

@webreidi

Description

@webreidi

Goal

Decouple game logic from UI & hosting layers by introducing explicit domain services and DTO boundaries, enabling easier testing, future rule variants, and clearer API evolution.

Current Pain Points

  • Game-specific logic likely resides in Blazor component (PlayCodele.razor) and ApiService Program.cs endpoints.
  • Internal game model (e.g., Guess, LetterStatus) may be leaked directly via API.
  • Hard to extend for variants (hard mode, timed mode) without branching conditionals in UI/API.

Proposed Architecture

Introduce a domain layer (within CodeleLogic or new Codele.Domain) containing:

  • IWordProvider: Provides daily/seeded target word (later can swap to SQL/Redis-backed service)
  • IGuessEvaluator: Pure function/service evaluating a guess -> collection of letter statuses + win state
  • GameSession (aggregate): Holds attempts, target word hash, result state; enforces max attempts
  • IGameService: Orchestrates session creation, applying guesses, emitting DTOs

API Layer Changes (in Codel-Cloud-Native.ApiService):

  • Replace direct logic with thin endpoints calling IGameService
  • Return DTOs: GameSessionDto { GameId, Attempts, MaxAttempts, IsComplete, IsWin } and GuessResultDto { Letters: LetterResultDto[] }
  • Map domain exceptions to ProblemDetails (400/404/409)

Blazor Client (Codel-Cloud-Native.Web):

  • CodeleApiClient consumes only DTOs; remove any assumptions about evaluation rules
  • Local component state becomes a projection of DTO instead of custom interpretation

Implementation Plan

  1. Create interfaces & models in domain project
  2. Implement default services (in-memory word list provider & evaluator) + unit tests
  3. Register services with DI in ApiService (AddScoped / AddSingleton as appropriate)
  4. Refactor existing endpoints to use IGameService
  5. Add DTOs + mapping (manual or small helper)
  6. Update Blazor client to use new endpoints & DTO shapes
  7. Add unit tests for evaluator edge cases (duplicate letters, repeated characters)
  8. Add minimal API tests validating contract shape (can be excluded from CI if integration constraints)
  9. Update README section with domain architecture overview

Acceptance Criteria

  • No direct usage of Guess internal domain types in public API responses
  • All game logic isolated behind interfaces with unit tests
  • Existing game UI still functions unchanged from user perspective
  • New unit tests pass (dotnet test --filter "TestGameLogic" plus new ones)

Out of Scope (Follow-ups)

  • Persistence (handled in a separate issue)
  • Leaderboards / history

Definition of Done

PR merged with green unit tests, updated docs, and refactored endpoints returning DTOs only.

Risk & Mitigation

  • Risk: API contract change breaking frontend -> Mitigate by updating client in same PR.
  • Risk: Over-engineering -> Keep interfaces minimal (single responsibility per interface).

Estimated Effort

Medium (4-6h depending on test coverage depth).

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions