Extract roll engines and log helpers
This commit is contained in:
32
TASKS.md
32
TASKS.md
@@ -17,7 +17,7 @@ The user-visible proof is intentionally boring: after starting the app, logging
|
||||
- [x] (2026-04-04 22:46Z) Inspected the current frontend state. `RpgRoller/Components/Pages/WorkspaceState.cs`, `WorkspaceSessionCoordinator.cs`, `WorkspaceCampaignCoordinator.cs`, `WorkspaceCampaignScopeCoordinator.cs`, `WorkspacePlayCoordinator.cs`, `WorkspaceAdminCoordinator.cs`, `WorkspaceLiveStateController.cs`, `WorkspaceFeedbackService.cs`, and `WorkspaceToast.cs` already exist.
|
||||
- [x] (2026-04-04 22:46Z) Marked the large structural extractions as already done in this plan instead of treating the repository as pre-refactor.
|
||||
- [x] (2026-04-04 23:03Z) Completed backend shared-helper consolidation. `GameStateStore` now owns campaign-state version mutations, `GameAuthorization`, `GameContextResolver`, and `GameDtoMapper` now own the shared helper seams, and the domain services delegate to them instead of keeping private copies.
|
||||
- [ ] Complete backend roll decomposition. Remaining work: extract the dice engines, breakdown formatting, and compact log summary logic out of `RpgRoller/Services/GameRollService.cs` while preserving all existing roll behavior.
|
||||
- [x] (2026-04-04 23:20Z) Completed backend roll decomposition. Dice execution now lives in `RollEngine`, `StandardRollEngine`, `D6RollEngine`, and `RolemasterRollEngine`, while `RollBreakdownFormatter` and `CampaignLogSummaryBuilder` own the extracted formatting and compact-log helpers.
|
||||
- [x] (2026-04-04 23:03Z) Finished thinning `RpgRoller/Services/GameService.cs` for startup and campaign-state bootstrap. The constructor now loads persistence and rebuilds campaign-state versions through `GameStateStore` without keeping private helper methods.
|
||||
- [ ] Finish thinning `RpgRoller/Components/Pages/Workspace.razor.cs`. Remaining work: remove the large mirror of `WorkspaceState` properties and the excess pass-through wrappers so the file acts as a composition root plus lifecycle and JS-invokable bridge.
|
||||
- [ ] Update `README.md` and this ExecPlan after the remaining code changes land so the documentation reflects the final, not intermediate, structure. Completed in this iteration: backend helper descriptions and current remaining scope.
|
||||
@@ -33,6 +33,9 @@ The user-visible proof is intentionally boring: after starting the app, logging
|
||||
- Observation: `GameRollService` is now the main backend monolith.
|
||||
Evidence: `RpgRoller/Services/GameRollService.cs` still owns D6 logic, Rolemaster logic, log summary formatting, event badge generation, and JSON dice serialization in one file.
|
||||
|
||||
- Observation: the roll split preserved behavior cleanly because the extracted helper boundaries were already pure and ruleset-scoped.
|
||||
Evidence: after moving dice execution into ruleset engines and moving summary text into `CampaignLogSummaryBuilder`, the existing D6, Rolemaster, log paging, detail, custom-roll, and Playwright smoke tests passed without contract changes.
|
||||
|
||||
- Observation: the frontend refactor introduced one extra collaborator that was not named in the original blueprint, and that collaborator is worth keeping.
|
||||
Evidence: `RpgRoller/Components/Pages/WorkspaceCampaignScopeCoordinator.cs` now owns selected-campaign reload, selected-character synchronization, log reset, and unauthorized-session handling. Those behaviors are cohesive and should not be pushed back into `Workspace.razor.cs`.
|
||||
|
||||
@@ -60,6 +63,10 @@ The user-visible proof is intentionally boring: after starting the app, logging
|
||||
Rationale: the extracted logic is pure over `GameStateStore` plus method inputs, so static helpers keep wiring simple while still removing the duplication that was obscuring the domain services.
|
||||
Date/Author: 2026-04-04 / Codex
|
||||
|
||||
- Decision: Instantiate the extracted roll engines inside `GameRollService` instead of pushing more constructor parameters through `GameService`.
|
||||
Rationale: the new engines depend only on `IDiceRoller`, so local construction keeps the facade wiring small while still carving the algorithmic work out of the service orchestration path.
|
||||
Date/Author: 2026-04-04 / Codex
|
||||
|
||||
- Decision: Keep validation instructions in this ExecPlan even though this revision is documentation-only.
|
||||
Rationale: `PLANS.md` requires executable validation guidance, but the user explicitly requested no CI or test work for this pass. The commands remain here for the implementation pass that follows later.
|
||||
Date/Author: 2026-04-04 / Codex
|
||||
@@ -68,7 +75,7 @@ The user-visible proof is intentionally boring: after starting the app, logging
|
||||
|
||||
The repository now has the shared backend seams that the earlier rewrite described as missing. `GameStateStore` owns campaign-state version mutation, `GameAuthorization` owns shared access checks, `GameContextResolver` owns session and campaign resolution, and `GameDtoMapper` owns the backend read-model construction that had been repeated across services.
|
||||
|
||||
The remaining work is narrower than before. The repository now needs second-wave cleanup focused mainly on `GameRollService` algorithm extraction and the final `Workspace` binding cleanup. `GameService` is already at the intended facade shape, so later iterations can stay smaller and more reviewable.
|
||||
The remaining work is narrower than before. The repository now needs the final `Workspace` binding cleanup. `GameService` is already at the intended facade shape, and `GameRollService` is now primarily orchestration plus persistence-facing log record handling.
|
||||
|
||||
## Context and Orientation
|
||||
|
||||
@@ -78,7 +85,7 @@ A "thin facade" in this plan means a class that mainly wires collaborators and f
|
||||
|
||||
The current backend state is better than the old monolith. `RpgRoller/Services/GameService.cs` already delegates its public methods to `GameAuthService`, `GameCampaignService`, `GameCharacterService`, `GameSkillService`, `GameRollService`, and `GameUserAdministrationService`. `RpgRoller/Services/GamePersistenceService.cs` already owns SQLite loading and saving. `RpgRoller/Services/SkillDefinitionValidator.cs`, `RoleSerializer.cs`, `RollVisibilityParser.cs`, `CustomRollOptionsResolver.cs`, and `GameStateCloneFactory.cs` already exist as helper files.
|
||||
|
||||
The backend shared-helper duplication is now resolved. `RpgRoller/Services/GameStateStore.cs` owns campaign-state version mutations. `RpgRoller/Services/GameAuthorization.cs` owns shared access checks. `RpgRoller/Services/GameContextResolver.cs` owns session-token and campaign resolution. `RpgRoller/Services/GameDtoMapper.cs` owns the backend read models returned by the services. The main backend target that remains is `RpgRoller/Services/GameRollService.cs`, which still combines dice algorithms, compact log formatting, event badges, and dice serialization in one file.
|
||||
The backend shared-helper duplication is now resolved. `RpgRoller/Services/GameStateStore.cs` owns campaign-state version mutations. `RpgRoller/Services/GameAuthorization.cs` owns shared access checks. `RpgRoller/Services/GameContextResolver.cs` owns session-token and campaign resolution. `RpgRoller/Services/GameDtoMapper.cs` owns the backend read models returned by the services. Roll execution is now split across `RpgRoller/Services/RollEngine.cs`, `StandardRollEngine.cs`, `D6RollEngine.cs`, `RolemasterRollEngine.cs`, `RollBreakdownFormatter.cs`, and `CampaignLogSummaryBuilder.cs`, leaving `RpgRoller/Services/GameRollService.cs` as a smaller workflow coordinator.
|
||||
|
||||
The current frontend state is also better than the old monolith. `RpgRoller/Components/Pages/WorkspaceState.cs` holds most UI state and many computed projections. Session/bootstrap behavior lives in `WorkspaceSessionCoordinator.cs`. Campaign management and modal flows live in `WorkspaceCampaignCoordinator.cs`. Selected campaign scope refresh lives in `WorkspaceCampaignScopeCoordinator.cs`. Play/log behavior lives in `WorkspacePlayCoordinator.cs`. Admin behavior lives in `WorkspaceAdminCoordinator.cs`. Live event reconciliation lives in `WorkspaceLiveStateController.cs`. Toast and announcement behavior lives in `WorkspaceFeedbackService.cs`.
|
||||
|
||||
@@ -127,16 +134,15 @@ Start every future implementation pass by re-reading the plan and checking the c
|
||||
git status --short
|
||||
rg --files RpgRoller/Services RpgRoller/Components/Pages
|
||||
|
||||
Shared backend helper consolidation is complete in the current tree. The next backend pass should begin by inspecting the remaining roll-service concentration before editing:
|
||||
The remaining implementation pass is frontend-focused. Begin by inspecting the `Workspace` composition surface before editing:
|
||||
|
||||
Get-Content RpgRoller\Services\GameService.cs
|
||||
Get-Content RpgRoller\Services\GameRollService.cs
|
||||
Get-Content RpgRoller\Services\GameAuthorization.cs
|
||||
Get-Content RpgRoller\Services\GameContextResolver.cs
|
||||
Get-Content RpgRoller\Services\GameDtoMapper.cs
|
||||
Get-Content RpgRoller\Services\GameStateStore.cs
|
||||
Get-Content RpgRoller\Components\Pages\Workspace.razor.cs
|
||||
Get-Content RpgRoller\Components\Pages\Workspace.razor
|
||||
Get-Content RpgRoller\Components\Pages\WorkspaceState.cs
|
||||
Get-Content RpgRoller\Components\Pages\WorkspaceCampaignScopeCoordinator.cs
|
||||
Get-Content RpgRoller\Components\Pages\WorkspacePlayCoordinator.cs
|
||||
|
||||
Keep the next extraction small. Move one cohesive cluster at a time out of `GameRollService` so tests can prove that dice totals, breakdown strings, and compact log responses stayed unchanged.
|
||||
Keep the next extraction small. Remove one block of mirrored state or pass-through wrappers at a time so component behavior can stay stable and the Playwright smoke flow can keep proving the result.
|
||||
|
||||
When beginning frontend cleanup, inspect the current composition surface before editing:
|
||||
|
||||
@@ -157,7 +163,7 @@ The expected result is simple: no failing tests, no coverage regression, and the
|
||||
|
||||
## Validation and Acceptance
|
||||
|
||||
This implementation revision ran targeted helper tests during extraction. Full repo validation through `pwsh ./scripts/ci-local.ps1` remains mandatory before considering the iteration complete.
|
||||
This implementation revision ran targeted helper tests during extraction and later full repo validation through `pwsh ./scripts/ci-local.ps1`. The same full validation remains mandatory after the frontend pass.
|
||||
|
||||
The backend is accepted when `RpgRoller/Services/GameService.cs` contains only collaborator wiring, ruleset enumeration, and public delegation; when shared authorization, context, mapping, and campaign-state helper logic each live in one place; and when `RpgRoller/Services/GameRollService.cs` no longer embeds the dice engines or compact log summary builders.
|
||||
|
||||
@@ -267,3 +273,5 @@ In `RpgRoller/Components/Pages/WorkspaceState.cs`, keep all plain state plus pur
|
||||
Revision note (2026-04-04): Replaced the old blueprint with an ExecPlan, reconciled it against the code already present in the repository, and marked completed versus remaining refactor work after direct file inspection. The reason for this rewrite is that `AGENTS.md` now requires complex refactors to be tracked as ExecPlans maintained under `PLANS.md`.
|
||||
|
||||
Revision note (2026-04-04 23:03Z): Marked backend shared-helper consolidation and `GameService` facade thinning as complete after implementing `GameAuthorization`, `GameContextResolver`, `GameDtoMapper`, and `GameStateStore` tracker methods. Updated the remaining scope so the next pass starts with `GameRollService` decomposition and later `Workspace` cleanup.
|
||||
|
||||
Revision note (2026-04-04 23:20Z): Marked backend roll decomposition as complete after extracting `RollEngine`, the ruleset-specific engines, `RollBreakdownFormatter`, and `CampaignLogSummaryBuilder`. Updated the remaining scope so the next pass can focus entirely on `Workspace` cleanup.
|
||||
|
||||
Reference in New Issue
Block a user