Files
kvitt/PLAN-M7b.md
T
jacobh2 5e1be38364 Plans and start prompts for every milestone; SPEC v0.2
PLAN-<id>.md for U1, U2, M1, M2a, M2b, M2c-dev, M2c-pi, M3, M4, M5, M6,
M7a-M7f, M8, M9, M10, M11, each with the eleven fixed sections, and a
start prompt per plan in prompts/ plus prompts/README.md (dependency
order and parallel waves).

SPEC v0.2: owner answers D-001 (development-first, M2c split into
M2c-dev and M2c-pi, Gitea registry), D-002 (local backups deleted once
on Drive), D-003 (Splitwise CSV format, English and Swedish variants,
category mapping), OQ-1, OQ-2, OQ-4 answered; M1's readings of
ambiguous contract points stated explicitly in §14.3 to §14.5.
HANDOFF §2 lists the plans.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 21:05:34 +02:00

10 KiB
Raw Blame History

PLAN-M7b: Feature home and account

1. Goal

Build :feature:home (Home S-4, sync status S-16, update banner and dialog S-17) and :feature:account (account detail S-5, account editor S-6) against the :core:model interfaces and :core:fakes. Every state of every screen is screenshot-tested in Swedish and English, light and dark.

2. Read first

  1. docs/ux/design-spec.md: tokens, component inventory, and the sections for S-4, S-5, S-6, S-16, S-17.
  2. docs/ux/strings.csv (keys for these screens) and docs/ux/screens/S-4-*, docs/ux/screens/S-5-*, docs/ux/screens/S-6-*, docs/ux/screens/S-16-*, docs/ux/screens/S-17-*.
  3. SPEC §13.2 Navigation model and §13.3 Screens (rows S-4, S-5, S-6, S-16, S-17 and the states paragraph).
  4. SPEC §14.2.4 UI contract: HomeRepository/HomeState, AccountRepository/AccountDetailState, SyncRepository/SyncStatusState, UpdateRepository/UpdateState, ConnectivityRepository, BalanceView, AccountSummary, SyncSummary, LedgerRow, LedgerMonth, ExpenseEffect, Rejection, OnlineResult.
  5. SPEC §4 FR-5 AC-5.1; FR-6 Expense accounts (AC-6.1 to AC-6.7); FR-8 AC-8.10; FR-10 Balances; FR-11 AC-11.7; FR-15 AC-15.4, AC-15.5; FR-16 AC-16.2 to AC-16.4; §9.2, §9.3, §9.8 (relative time); §14.4.6 Rejection reasons.
  6. SPEC §6.2 (module table), §9.8 Formatting, §9.9 Online-only actions, §11.2 (row M7b), §11.3 (note M7x), §14.7.
  7. Files: android/core/model/**, android/core/design/** (read only), android/core/fakes/**, android/build-logic/**, CLAUDE.md (BUILD AND VERIFY: Screenshots; ARCHITECTURE RULES; ANTI-PATTERNS).

3. Already established

  • Features depend only on :core:model, :core:design and :core:fakes; :core:fakes only in test, screenshot-test and debug-preview configurations, never in a release build. Features never depend on :data or :domain (§6.2, §11.3, CLAUDE.md Layering).
  • Screens consume the *State classes through the repository interfaces of §14.2.4; no field may be added except through a contract change (§14.2.4, §14.8).
  • Fake scenarios go only in android/core/fakes/src/main/kotlin/se/hagstedt/kvitt/fakes/<feature>/ (§11.3, §14.7).
  • Strings live in the module's src/main/res/values/strings.xml and values-sv/strings.xml with keys from docs/ux/strings.csv; no string outside that file without a decisions entry (§13.4, §14.7, AC-19.1).
  • No hard-coded colours, sizes or strings; tokens and shared components come from :core:design, which features may not edit (CLAUDE.md, §14.7). Money and dates go through MoneyFormatter and DateFormatter (§9.8).
  • Online-only actions are disabled with "Needs connection" when offline (§9.9); a REST failure shows "Could not reach the server".
  • Navigation graph, deep links and Hilt bindings are in :app (M8); a feature exposes its screens with navigation callbacks in the form M2b's feature convention fixed (§11.3).
  • Layout and visuals follow docs/ux/design-spec.md; TalkBack labels as it specifies; 48 dp targets, 200 % font scale reflow (§13.1).
  • No placeholder text in previews or screenshots; goldens are committed; open every changed PNG before committing (CLAUDE.md).
  • Home shows the global balance from the viewer's side (" owes you X", "You owe X", "All settled up"), every active account with its balance, archived accounts in a collapsed "Archived (n)" section, "Settle up" when non-zero, the sync line with "Last synced …" and pending count, and the update banner (AC-10.1, AC-10.2, AC-15.4, §13.3 S-4).
  • The account screen shows its balance ("Settled up" at zero) and expenses and settlements interleaved by date, grouped by month with household-spend month totals; rows per AC-8.10 and AC-11.7 (AC-10.3, §9.3, §13.3 S-5).
  • Account editor: ratios entered as percent with up to two decimals, the second user's value always 100 minus the first, stored as bp; starts at 50/50; online only (AC-6.1, AC-6.7). Archive/unarchive any time; delete only when deletable (AC-6.4, AC-6.5).
  • Sync status lists pending changes, "Changes not synced" from sync_rejections with the §14.4.6 explanations, the clock-skew warning, and "Sync now" (AC-15.5, §9.10, §13.3 S-16).
  • Update: banner with version name; first time, a dialog explaining "Install unknown apps"; download progress; "Download failed, try again" (AC-16.2 to AC-16.4).

4. Owned paths

From SPEC §14.7, verbatim: android/feature/home/**, android/feature/account/** (owner M7b), and from the android/core/fakes/** row: "M7x add files only under fakes/<feature>/", here android/core/fakes/src/main/kotlin/se/hagstedt/kvitt/fakes/home/, android/core/fakes/src/main/kotlin/se/hagstedt/kvitt/fakes/account/ (§11.3). Catalog entries and module includes may be added (§14.7, android/gradle/** row).

Edit nothing outside these paths; a needed change elsewhere is a contract request to the orchestrator.

5. Deliverables

  • android/feature/home/build.gradle.kts: dependencies :core:model, :core:design; :core:fakes for tests and debug only.
  • android/feature/home/src/main/kotlin/se/hagstedt/kvitt/feature/home/**: the screens of this module and their state holders.
  • android/feature/home/src/main/res/values/strings.xml, values-sv/strings.xml: keys from docs/ux/strings.csv.
  • android/core/fakes/src/main/kotlin/se/hagstedt/kvitt/fakes/home/**: a scenario per state below.
  • android/feature/account/build.gradle.kts: dependencies :core:model, :core:design; :core:fakes for tests and debug only.
  • android/feature/account/src/main/kotlin/se/hagstedt/kvitt/feature/account/**: the screens of this module and their state holders.
  • android/feature/account/src/main/res/values/strings.xml, values-sv/strings.xml: keys from docs/ux/strings.csv.
  • android/core/fakes/src/main/kotlin/se/hagstedt/kvitt/fakes/account/**: a scenario per state below.
  • Screenshot tests and committed goldens for every screen × state × light/dark × sv/en.
  • Unit tests for the state holders (input handling, enablement rules, error mapping).

Screens and states. Required states for every screen below (SPEC §13.3): loaded, empty, offline (with pending changes), loading (first sync only), error (a failed online action), and for lists long content (long Swedish names, 7-digit amounts), each where it applies. A state that docs/ux/design-spec.md marks not applicable for a screen is skipped and named in the report. Each state is screenshot-tested in light and dark, Swedish and English. Screen-specific states from §13.3 "Must show" are added per screen:

  • S-4: global balance owes-you, you-owe and all-settled-up; pending count > 0; rejected count > 0; clock skew; sync running; update banner shown; archived section collapsed and expanded; empty "Create your first account"; offline; loading (first sync); long content (long Swedish account names, 7-digit amounts).
  • S-5: positive, negative and zero balance; archived badge; pending-sync marker on a row; delete allowed and not allowed; empty account; offline; error (failed archive or delete); long content.
  • S-6: create and edit; preview line ("Of 100,00 kr: …"); non-50/50 ratio with decimals; error name_taken; error validation_failed; "Needs connection" (offline); saving in progress.
  • S-16: all synced; pending list; rejections of each reason of §14.4.6; clock-skew warning; sync running; error (last sync failed); offline; long content.
  • S-17: banner; first-time "Install unknown apps" explanation dialog; downloading with progress; failure "Download failed, try again"; needs install permission; offline ("Needs connection").

6. Steps

  1. Worktree. From the main checkout /Users/jhag/projects/kvitt: git worktree add .claude/worktrees/agent-m7b -b agent-m7b main, then in .claude/worktrees/agent-m7b: git reset --hard main. Copy android/local.properties from the main checkout (add sdk.dir=/opt/homebrew/share/android-commandlinetools if missing; never overwrite or commit). Run tools/install-git-hooks.sh.
  2. Read §2 in order. Confirm M6 has landed (android/core/design/ has components on main); if not, stop and report. If a component the design spec assigns to :core:design is missing, file a contract request; do not build it inside the feature.
  3. Run python3 tools/dependency-report/latest.py; record the lines. No new library is expected; any one added is at its latest stable version from official docs; record it.
  4. Write the fake scenarios under the feature's fakes/<feature>/ directory for every state listed in §5.
  5. Write the state holders and screens, one screen at a time, with strings from docs/ux/strings.csv in both languages.
  6. Write the screenshot tests; record goldens; open every PNG and compare with docs/ux/screens/.
  7. Run the gate (§7). Commit on agent-m7b, git rebase main, rerun the gate. Never merge, push or remove the worktree.

7. Gate

From SPEC §11.2, verbatim: "as M7a", that is "Android gate with screenshot tests of every state, sv and en, light and dark". Command, from android/: PATH=/opt/homebrew/opt/openjdk@25/bin:$PATH ../tools/gradle-serial.sh check. Green means: BUILD SUCCESSFUL in this session; screenshot verification passes for :feature:home, :feature:account; the report lists, per screen, every state × light/dark × sv/en golden; unit tests 0 failures in fresh XML.

8. HUMAN steps

From SPEC §11.2, verbatim: "none".

9. Out of scope

  • Other screens: S-1, S-2, S-3, S-18 (M7a); S-7, S-8 (M7c); S-9, S-10 (M7d); S-11, S-12 (M7e); S-13, S-14, S-15, S-19, S-20, S-21, S-22 (M7f).
  • Navigation graph, deep links, Hilt bindings, notifications (M8); real repositories (M5).
  • Editing :core:design (requests go to the orchestrator) or :core:model; any dependency on :data or :domain.
  • Fake scenarios outside this plan's fakes/<feature>/ directories.

10. Report

  • Branch agent-m7b, head commit hash after rebasing on main.
  • Gate output: BUILD line, actionable tasks line, screenshot task result, test counts from fresh XML.
  • Screens × states table with golden file names; states skipped as not applicable.
  • Versions added (if any) with sources; dependency-report lines.
  • Strings used that are missing from strings.csv (should be none) and design-spec mismatches.
  • Numbering used or TODO(spec) occurrences.
  • Contract requests (:core:design, :core:model), open questions, spec gaps (with section numbers).

11. Numbering

Decision ids, spec version and schema version are assigned by the orchestrator in the start prompt; use TODO(spec) if none was given.