N-Tier Architecture Refactor — Orchestrator Planning Handoff

Updated: 2026-08-08 · Audited: 2026-08-03 · Epic: WI-2081 · Gap Analysis: WI-2104

Point-in-time planning record — do not read as current status. This captures the plan as of 2026-06-26 and is kept for the sequencing rationale and the gap analysis, not as a status board. Phases 2–5 have all resolved since; the status table below still shows them as New/Active, and the note that component-library work must wait for Phase 5 no longer applies — Phase 5 resolved on 2026-07-01 and that work has shipped.

For where the code actually lives, which layer owns what, and what is genuinely outstanding, see N-TIER-ARCHITECTURE.md, which is verified against the repo and carries the date it was last checked. Keeping two documents in sync is what let this one drift; there is one living source and this is not it.

Architecture Target State

ALPAMobile.Domain          ← Pure business rules, no external dependencies
ALPAMobile.Application     ← Service interfaces (contracts), orchestration/use-cases
ALPAMobile.Infrastructure  ← API clients, auth, storage, caching (implements Application interfaces)
ALPAMobile.Presentation    ← Pages, ViewModels, controls (depends on Application interfaces only)
ALPAMobile (MAUI host)     ← Composition root only — MauiProgram.cs wires everything via DI

Dependency rule (enforced by NetArchTest):

Domain ← Application ← Infrastructure
Domain ← Application ← Presentation
NEVER: Domain → anything, Application → Infrastructure/Presentation, Infrastructure → Presentation

Completed Work

Gap Tasks (WI-2104 Children)

Gap WITitleResolved In Phase
WI-2105Replace Service Locator anti-pattern (280+ hits of Handler?.MauiContext?.Services.GetService<T>())Phase 3 + Phase 6
WI-2106Modernize 204 new Command() usages to RelayCommand/AsyncRelayCommandPhase 5
WI-2107Replace custom BindableBase with MVVM Toolkit ObservableObjectPhase 5
WI-2108Move FTDTCalculator & FTDTValidator from ALPAMobile/BusinessLogic/ to Domain layerPhase 2
WI-2109Break up DataManager.cs (2813 lines) and RestService.cs (2048 lines)Phase 4
WI-2110Implement IValidationRule<T> / per-property error binding validation infrastructurePhase 7
WI-2111Introduce INavigationService abstraction (replace Shell.Current in BasePageViewModel)Phase 3
WI-2112Extract ISettingsService interface from AppProperties concrete classPhase 3

Phase 2 — Domain Extraction (WI-2084)

Active Resolves Gap: WI-2108

Domain Model Strategy: Hybrid

Known Specifics

Constraints

Phase 3 — Application Layer & Interface Extraction (WI-2085)

New Resolves Gaps: WI-2105 (partial), WI-2111, WI-2112

ViewModel Conversion — 4-Batch Strategy

BatchFeature AreaNotes
1Auth / Login / SessionBasePageViewModel first — all others inherit from it. Wires INavigationService, ISettingsService.
2My Pilot Group — MEC / LECActively undergoing major ViewModel refactoring. Coordinate with UI Refresh intersection.
3Flight Data / FTDT + Jumpseat / PilotCommsFollows Phase 2 Domain extraction. FTDT is core product.
4Navigation / UI / RemainingShell nav, flyout, menus, banners, misc ViewModels. Final Shell.Current cleanup.

Key Interfaces to Define

Phase 4 — Infrastructure Layer (WI-2086)

New Resolves Gap: WI-2109

DataManager & RestService Decomposition

Target ServiceResponsibility
IAuthService / AuthServiceToken management, refresh
IFlightDataService / FlightDataServiceFTDT-specific API calls
IJumpseatService / JumpseatServiceJumpseat API
IPilotCommsService / PilotCommsServicePilotComms API
IMobileMenuService / MobileMenuServiceMobile menu API
ILocalStorageService / LiteDbStorageServiceLiteDB operations
ICacheService / MemoryCacheServiceIn-memory caching
IPushNotificationService / PushNotificationServicePush token registration

Phase 5 — Presentation Extraction (WI-2087)

New Resolves Gaps: WI-2106, WI-2107

This phase is a prerequisite for the UI Refresh (new component library + design system will be built on this clean surface).

Phase 6 — Composition Root Cleanup (WI-2088)

New Resolves Gap: WI-2105 (final closure)

Consolidate ALL DI registration into MauiProgram.cs. Remove ALL remaining service locator patterns.

builder.Services.AddDomainServices();
builder.Services.AddApplicationServices();
builder.Services.AddInfrastructureServices(builder.Configuration);
builder.Services.AddPresentationServices();

Phase 7 — SOLID Hardening (WI-2089)

New Resolves Gap: WI-2110

Validation infrastructure target:

// Application layer
public interface IValidationRule<T> { bool Check(T value); string ValidationMessage { get; } }
public class ValidatableObject<T> : ObservableObject { ... } // INotifyDataErrorInfo

Phase 8 — Test Coverage Strategy (WI-2090)

New

LayerCoverage TargetApproach
Domain90%+Pure logic, no mocks needed
Application80%+Mock Infrastructure interfaces
Infrastructure60%+Integration tests, not unit
Presentation/VMs70%+Mock Application interfaces

Tooling: NUnit 4.x + NSubstitute + Coverlet (unit) / NUnit 4.x + Appium v8 (UI) / NetArchTest.Rules (architecture)

Action required: Add NSubstitute NuGet reference to UnitTest.csproj

Sequencing & Dependencies

Phase 0 ✅ → Phase 1 ✅ → Phase 2 → Phase 3 → Phase 4
                                        ↓          ↓
                                    Phase 5    Phase 6
                                        ↓
                                    Phase 7
                                        ↓
                                    Phase 8

Critical path: Phase 3 (Application/DI) unlocks Phase 5 (Presentation) and Phase 6 (Composition Root). Phase 2 (Domain) can partially run in parallel with Phase 3.

UI Refresh intersection: Phase 5 is the gateway. The new component library / design system work should NOT begin until Phase 5 is complete.

Sub-Agent Guidance

  1. Worktrees are required — each phase gets its own git worktree targeting DotNet10
  2. Commit messages must include ADO link: feat: extract INavigationService and wire DI AB#2085 AB#2111
  3. PR target: imp/blazor-hybrid branch always (was DotNet10 when this plan was written)
  4. Architecture test gate: Run NetArchTest suite after every migration step
  5. Phase 3 ViewModel batching: 4 PRs in order — Auth → MEC/LEC → FTDT/Jumpseat → Nav/UI
  6. Review before merge: Dr. Castro reviews all PRs before merge to DotNet10

ADO Work Item Reference

WITitleStatePhase
2081N-Tier Architecture Refactor — Foundation for Testability (Epic)New
2082Phase 0 — Guardrails & Architecture Tests✅ Resolved0
2083Phase 1 — Layer Projects Scaffolding✅ Resolved1
2084Phase 2 — Domain ExtractionActive2
2085Phase 3 — Application Layer & Interface ExtractionNew3
2086Phase 4 — Infrastructure LayerNew4
2087Phase 5 — Presentation ExtractionNew5
2088Phase 6 — Composition Root CleanupNew6
2089Phase 7 — SOLID HardeningNew7
2090Phase 8 — Test Coverage StrategyNew8
2105GAP-1: Replace Service Locator (280+ hits)ActivePh3+6
2106GAP-2: Modernize 204 new Command() usagesActivePh5
2107GAP-3: Replace BindableBase with ObservableObjectActivePh5
2108GAP-4: Move FTDTCalculator/Validator to DomainActivePh2
2109GAP-5: Break up DataManager (2813L) + RestService (2048L)ActivePh4
2110GAP-6: IValidationRule<T> / per-property validationActivePh7
2111GAP-7: INavigationService (decouple from Shell.Current)ActivePh3
2112GAP-8: ISettingsService interface from AppPropertiesActivePh3

AppProperties Decomposition (WI-2113)

Analysis confirmed: AppProperties is NOT a settings class — it mixes three distinct concerns:

BucketInterface TargetStorage
User-defined preferences (survive logout)ISettingsServicePreferences API
Runtime user app state (cleared on logout)IUserAppDataServiceLiteDB
Diagnostic controls (DEBUG only)IDevDiagnosticsServicePreferences API
Device push tokensIDeviceTokenStore (Infrastructure)SecureStorage
Installation keyIInstallationService (Infrastructure)Preferences API
Auth tokens (already handled)ITokenStore (already exists)SecureStorage

Sequencing note: IUserAppDataService interface is defined in Phase 3, but its LiteDB-backed implementation requires WI-2109 (Phase 4) to be complete first.