Files
kvitt/PLAN-W4.md
T
jacobh2 7bddc50a53 SPEC v0.28: web client programme (D-129 to D-134), plans W0 to W7
New SPEC §15 Web client and FR-21; §1, §2, G-5, AC-14.1 revised; §8.5 and
§10.5.2 gate lines for /app/, the invite accept and bearer requests (except
/health, /setup/, /i/, /apk/) plus the /app/ CSP via $kvitt_csp, identical in
infra/npm/kvitt.conf and infra/README.md step 4 (checked with nginx 1.31.7);
§10.3, §10.6, §11.1 to §11.3 (rows W0 to W7), §14.7 ownership; change log is
now §16. PLAN-W0..W7 and prompts/W0..W7; HANDOFF numbering D-139 / v0.30.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TQd3pEP9UeN2uifbHknQ7B
2026-10-21 20:49:00 +02:00

5.6 KiB

PLAN-W4: Web analytics and insights

1. Goal

Build the web client's analytics page (W-9), drill-down with D-128's line chart (W-10) and the Insights page (W-11) on the D-133 endpoints, in web/src/features/analytics/, on W0's foundation (SPEC §15.6, §15.8), with a TypeScript port of resolveRange and spendSeries passing their vectors.

2. Read first

  1. SPEC §15 (all, §15.8 especially), FR-21, FR-14 (AC-14.1 as revised, AC-14.2 to AC-14.10), §14.5.4, §9.8, §13.3 rows S-11 and S-12 and the D-128 text (SPEC v0.27: the line chart of a category or account over the range, its own period and granularity, average overlays), D-069, D-070, D-077, D-097, D-128, D-133, and the server agent's D-135 to D-138 (SPEC v0.29) once recorded.
  2. docs/ux/design-spec.md S-11 and S-12 sections, §2.4 (chart and account colours), §2.9 (bar radii), §3.10 (charts); docs/ux/strings.csv keys analytics_*.
  3. contracts/test-vectors/resolve_range.json, spend_series.json; contracts/openapi.yaml /analytics/* (after W7) and web/src/api/schema.d.ts.
  4. web/README.md and W0's report (module map).
  5. Files: web/src/{app,api,lib,components,i18n}/** (read only), web/src/features/analytics/** (W0's placeholders).
  6. CLAUDE.md.

3. Already established

  • W0 owns everything shared; this plan edits only web/src/features/analytics/. Missing shared pieces are requests to the orchestrator.
  • Port (§15.3): resolveRange and spendSeries of §14.5.4 in web/src/features/analytics/domain/, passing resolve_range.json and spend_series.json in Vitest; S-11 and S-12's numbers are computed in the browser from the snapshot (§15.5), including D-128's line chart and its averages, with the same window constant as the app.
  • W-9 (mirrors S-11): range presets of AC-14.2 with custom start and end, granularity month or week, measure household or my share, group by category or account (defaults as AC-14.2 to AC-14.5); the total card per D-069; stacked bars per bucket with legend in sortOrder / account order; category and account breakdowns with amount and percent (AC-14.10); empty state; every bucket shown (AC-14.7); deleted expenses excluded, archived included (AC-14.9). Charts with Recharts styled by the design tokens (bar corners 4 top, 2 bottom, D-097; category and account colours §2.3, §2.4); tooltips and keyboard focus on bars; a table alternative for screen readers.
  • W-10 (mirrors S-12 and D-128): title naming the filter (D-070), total, the line chart of a category or account over the range with its own period and granularity and the average overlays, expense rows opening /app/expenses/:id. Route /app/analytics/:groupKind/:groupId (groupKind category or account), with the bucket and range as query parameters of this plan's choice.
  • W-11 Insights (/app/insights, D-133): reads the /analytics/* endpoints designed by W7 (D-135 to D-138) through W0's client and the generated types: per-category averages and trends per month, overall and per category, and the 2-month forecast per account showing its two parts (recurring templates due, average of non-recurring spend over the last 3 whole months). Nothing of it is computed in the browser. Until W7 has landed on main (no /analytics/* in web/src/api/schema.d.ts), W-11 is a stub page saying the feature is coming, with no fake numbers; the report says which state it shipped in. Online errors as §15.5.
  • Desktop layout: charts may sit side by side from 720 px; under 720 px the S-11 order.

4. Owned paths

From SPEC §14.7: web/src/features/analytics/**. web/package.json only for a dependency line (Recharts is already W0's). Nothing else.

5. Deliverables

  • W-9, W-10, W-11 (full or stub) with every state of §15.6.
  • The two ports with vector tests (13 and 13 cases); tests of presets, week keys, measure switch, percent rounding, drill-down title and rows, the line chart's series and averages, W-11's mapping of endpoint responses (from the contract examples once W7 provides them).

6. Steps

  1. Worktree: from /Users/jhag/projects/kvitt, git worktree add .claude/worktrees/agent-w4 -b agent-w4 main; in it git reset --hard main, tools/install-git-hooks.sh, cd web && npm ci.
  2. Read §2. Confirm W0 has landed; if not, stop and report. Check whether W7 has landed (/analytics/ in contracts/openapi.yaml on main) and whether SPEC v0.27 (D-128) is on main; say in the report what you built against.
  3. npm outdated; record it.
  4. Ports and vector tests; W-9; W-10; W-11.
  5. Manual check (optional): a throwaway server with some expenses, npm run dev. Never the owner's development stack or the Pi.
  6. Gate (§7). Commit on agent-w4, git rebase main, rerun the gate. Never merge, push or remove the worktree.

7. Gate

The web gate, from web/: npm run check. Green: every step passed in this session; Vitest summary quoted, including both vector files.

8. HUMAN steps

From SPEC §11.2: look at the analytics pages in a browser (yes/no), relayed after landing.

9. Out of scope

  • The /analytics/* endpoints themselves and any server or contract change (W7); the Android Insights section (W6).
  • Other pages (W1, W2, W3, W5); edits outside web/src/features/analytics/.

10. Report

  • Branch agent-w4, head commit after rebasing; gate lines; Vitest counts (vectors 13 and 13).
  • W-11 full or stub, and against which contract version; D-128 as read.
  • web_ keys added (en, sv); design-spec mismatches; requests for W0's modules or W7's endpoints.
  • Proposed decision entries (numbered from the brief); open questions with SPEC section numbers.

11. Numbering

Assigned in the start prompt; use TODO(spec) if none was given.