Skip to Content
Tech debtArchitecture

Architecture & Code Debt

Code structure, patterns, sync, and offline debt. Canonical architecture lives in Global architecture. Back to register.

Patterns (TD-12)

  • The codebase historically ran two presentation patterns: Android MVI (core-ui BaseViewModel + per-feature Clean-Arch modules) and a lighter service-oriented MVVM in shared/ (StateFlow + direct Ktor service calls). The mobile consolidation (migrations.md) retires the Android MVI side; the shared MVVM is now the single target pattern.
  • The rationale doc that would capture this (docs/architecture/PATTERNS_AND_TRADEOFFS.md) was never written — only a draft plan exists: plan-patterns-and-tradeoffs.md (now annotated as partly superseded).

Target: document the shared-MVVM boundaries; decide whether to introduce a small shared MVI primitive (intent + reducer) only where complexity justifies it.

God-files / decomposition (TD-07)

Status as of 2026-06:

FileLOCStatus
shared/.../services/finance/FinanceService.kt162 (was 1015)Done — extracted into 8 sub-services: FinanceTransactionService, FinanceAccountService, FinanceBudgetService, FinanceGoalService, FinanceProductService, FinanceReconcileService, FinanceScheduledTransactionService, FinancePredictionService. The original FinanceService is now a thin facade.
shared/.../viewmodel/WorkoutViewModel.kt814⬜ Open
shared/.../viewmodel/RecipesViewModel.kt778⬜ Open
shared/.../services/work/WorkService.kt638⬜ Open
shared/.../viewmodel/StudyViewModel.kt581⬜ Open
shared/.../services/timers/TimerService.kt557⬜ Open

Pattern: Each sub-service takes (baseUrl, httpClient, tokenStorageImpl) in its constructor, same as the original. Callers continue using FinanceService — the facade delegates transparently.

Finance module follow-ups (TD-09)

Closed (see commit history under features/finance/): duplicate coroutine scope, ChangeTab stub, bogus budget if-else, unsafe ?: "" IDs, pagination bug. Remaining:

  • FinanceRepositoryImpl doRequest duplication → generic helper.
  • Custom exception types + error logging instead of generic failures.
  • Input validation (amounts, date ranges, required fields, account existence).
  • KDoc on public methods; ADRs for non-obvious decisions.

Sync design incomplete (TD-08)

sync-algorithm-design.md defines goals (multiplatform, conflict resolution, offline queue) but the “Sync Data Model” is explicitly “to be defined.” The Android Retrofit sync was removed; a shared Ktor-based design is intended but unfinished.

Target: finish the sync data model + conflict-resolution rules, or formally record that the app is network-only post-consolidation (decide alongside the offline question below).

Offline & sync describes a stale-while-revalidate, Room-backed offline-first UX with Firebase Remote Config data-policy modes. The mobile consolidation drops the Android Room/offline layer (network-only), so this doc and the shipped behavior have diverged. (Note: Wasm is not a shipped client.)

Target: reconcile architecture/offline-and-sync.md with the post-consolidation reality — either re-introduce a shared offline cache or document network-only as the decision.

Responsive breakpoints (TD-10)

OterWindowSize exists in shared/.../ui/util/OterWindowSize.kt with breakpoints Compact <600dp, Medium 600–840dp, Expanded >840dp. Most screens now use it (via OterWindowSizeProvider / LocalOterWindowSize). The following component files were migrated from direct BoxWithConstraints { maxWidth < 600.dp } to the shared helper in 2026-06: TransactionToolbar, TransactionGridView, FilterSidePanel, TaskGrid, ScheduledTransactionToolbar, ScheduledTransactionGridView, BudgetTrackerWrapper.

Remaining: Some screens still use ad-hoc maxWidth values for layout sizing (not breakpoint comparisons) — these are acceptable as they relate to specific component dimensions rather than responsive breakpoints.

Feature stubs (TD-11) — Done (2026-06)

Previously stubbed: Finance savings-goals & debts tabs now call loadSavingsGoals()/loadDebts() via FinanceService; Settings paywall button shows “coming soon” temporary text; GeneralMenuIconUtils docs are complete (icons fall back to base until theme-specific resources are added). All in-code TODOs removed.