SPEC v0.35: card purchases via Enable Banking (D-158 to D-176), plans K0 to K3
Owner request and answers of 2026-10-24: each user connects their own SJ Prio
Mastercard through Enable Banking (restricted production, BankID); only the
card holder sees the purchases; a fourth bottom destination "Kortköp"
(revises D-048); "Anslut kort" in Settings with the card artwork; one- and
two-tap linking to household expenses; web as a later plan.
FR-22, §9.12 (CP-1 to CP-14), server schema 4 (migration 0004), Room 2,
E-36 to E-44, S-23 to S-27, W-21 to W-23, OQ-7, OQ-8. PLAN-K0 describes the
test app of 2ce317f and the remaining run and report; K1 server, K2 Android,
K3 web. HANDOFF and prompts/README updated.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+15
-4
@@ -3,7 +3,8 @@
|
||||
Living document, rewritten in place (never a second copy). A new orchestrator session reads CLAUDE.md, then this.
|
||||
|
||||
## 1. Where things stand
|
||||
- State as of 2026-10-24. `main` at `5305f37` (W0b web shared follow-ups), pushed to `origin` 2026-10-24; before it `07c36d2` (L-10, D-156) and `593c727` (SPEC v0.33, D-156, D-157). Release 140 (`kvitt-140`, deployed 2026-10-21) runs on both phones (verified 2026-10-24). Next: the Pi image build of the pushed `main` with the complete web app (the Gitea workflow on the Pi runner; this pass's `server/Dockerfile` and workflow change triggers another run when pushed), then the owner deploys it (§3 step 3), logs in from the laptop browser (the web client's first use, D-156) and runs the browser checks (§3 step 4). This docs pass (`agent-docs-v34`) records L-10 as implemented and W0b (SPEC v0.34, no new decision) and passes the web's version code into the image build (`ARG KVITT_VERSION_CODE` in `server/Dockerfile`, `--build-arg KVITT_VERSION_CODE=<git rev-list --count HEAD>` in the workflow). Gates on `main`: server 300 tests, web 609 tests, contracts-check 136.
|
||||
- State as of 2026-10-24. `main` at `2ce317f` (the K0 card test app), after `5d948f9` (SPEC v0.34) and `5305f37` (W0b web shared follow-ups, pushed to `origin` 2026-10-24); before them `07c36d2` (L-10, D-156) and `593c727` (SPEC v0.33, D-156, D-157). Release 140 (`kvitt-140`, deployed 2026-10-21) runs on both phones (verified 2026-10-24). Next: the Pi image build of the pushed `main` with the complete web app (the Gitea workflow on the Pi runner; this pass's `server/Dockerfile` and workflow change triggers another run when pushed), then the owner deploys it (§3 step 3), logs in from the laptop browser (the web client's first use, D-156) and runs the browser checks (§3 step 4). This docs pass (`agent-docs-v34`) records L-10 as implemented and W0b (SPEC v0.34, no new decision) and passes the web's version code into the image build (`ARG KVITT_VERSION_CODE` in `server/Dockerfile`, `--build-arg KVITT_VERSION_CODE=<git rev-list --count HEAD>` in the workflow). Gates on `main`: server 300 tests, web 609 tests, contracts-check 136.
|
||||
- **Card purchases programme** (owner request and answers 2026-10-24, SPEC v0.35, D-158 to D-176, FR-22, §9.12): each user connects their own SJ Prio Mastercard (SEB Kort) through Enable Banking's restricted production mode with BankID; the server alone holds the key and sessions, fetches purchases up to 4 times a day in the background plus "Uppdatera", and only the card holder sees them (not in `GET /sync`, audit, push or analytics); a fourth bottom destination "Kortköp" (Översikt, Kortköp, Statistik, Inställningar, revising D-048), "Anslut kort" in Settings with the SJ Prio artwork, "Skapa utgift" prefilled into S-7, one-tap links to matching expenses (same amount, ±3 days), "Från kortköp" on account detail; server schema 4 (migration 0004), Room 2, endpoints E-36 to E-44, screens S-23 to S-27, web W-21 to W-23. Plans `PLAN-K0.md` to `PLAN-K3.md`, prompts `prompts/K0.md` to `prompts/K3.md`, written by `agent-a3b7abf183f883261`. **Next: K0** — the test app landed `2ce317f` (`docs/spikes/k0/app.py`, one command, key and session in the git-ignored `docs/spikes/k0/.local/`); what remains is running it with the owner (and the partner) and the report `docs/spikes/K0-enable-banking.md`, whose answers to the K0 `TODO(spec)` items of §9.12 go into SPEC v0.36 before K1 starts. Then K1 (server, contract) lands first, K2 (Android) after it, K3 (web) after K2; they may run in parallel. K0 waits on the owner steps of §3 (Enable Banking account and ToS, the application, the key, linking both cards).
|
||||
- **Verified 2026-10-24** (owner, D-156): Samsung Auto Blocker was the cause of the silent update failure; turning it off let the update install, and the owner turned it back on, so every in-app update on the Samsung phones needs it off (the D-155 blocked text names it; SPEC AC-16.3, `infra/README.md`). The editor keyboard fix (S-19, S-15, S-6, `05ec3f3`) works on the device. The first backup on the Kvitt Pi ran and a snapshot pair is in the Drive folder (AC-18.1). The runner Pi's disk reached 11 of 15 GB during image builds; the owner runs `docker builder prune -af` between builds (SPEC §10.3).
|
||||
- **Kvitt host name** (owner decision 2026-10-19): `kvitt.suorra.duckdns.org`, a subdomain of the owner's DuckDNS family domain `suorra.duckdns.org`; NPM issues its Let's Encrypt certificate; `KVITT_PUBLIC_HOST=kvitt.suorra.duckdns.org`, so `KVITT_PUBLIC_URL=https://kvitt.suorra.duckdns.org` (port 443, D-124). It is in `infra/pi/.env.example` and `infra/pi/.env` (`KVITT_PUBLIC_HOST`) and `android/local.properties` (`kvitt.publicHost`, git-ignored). SPEC §10.1 and §10.5.1 point here.
|
||||
- **NPM proxy host** for `kvitt.suorra.duckdns.org` is Online with a Let's Encrypt certificate (owner, 2026-10-19). The router needs no new rule: external TCP 443 already forwards to the Home Assistant Pi (owner confirmed, D-124).
|
||||
@@ -78,6 +79,10 @@ Living document, rewritten in place (never a second copy). A new orchestrator se
|
||||
- Disk: the MacBook had about 72 GB free during the v0.20 docs pass (2026-10-19); run `tools/clean-builds.sh` when it drops under about 5 GB.
|
||||
|
||||
## 2. Open work (one line each, with who owns it: agent or owner)
|
||||
- Land the card-purchases docs pass (orchestrator): SPEC v0.35, D-158 to D-176, `PLAN-K0.md` to `PLAN-K3.md`, `prompts/K0.md` to `K3.md`, `prompts/README.md`, this file; gate `python3 tools/contracts-check.py` (no contract file changed).
|
||||
- K0 run and report (Opus agent with the owner, `prompts/K0.md`): after the owner steps of §3 item 5; then a docs agent records K0's answers as SPEC v0.36 before K1.
|
||||
- K1, K2, K3 (Opus agents, after SPEC v0.36; disjoint decision ranges): K1 lands first, K2 after K1, K3 after K2. K2's card artwork follow-up if the owner's PNG arrives after K2 (one mapping line and re-recorded goldens).
|
||||
- Card design-spec sections S-23 to S-27 for `docs/ux/design-spec.md` (docs agent, from K2's report).
|
||||
- Land `agent-docs-v34` (orchestrator): SPEC v0.34, D-156 implemented, L-10 note, the version-code ARG in `server/Dockerfile` and the workflow, HANDOFF; gate `python3 tools/contracts-check.py`.
|
||||
- `infra/build-images.sh` (agent, next infra pass): pass `--build-arg KVITT_VERSION_CODE=$(git rev-list --count HEAD)` to the server build as the workflow does (v0.34); without it the Mac-built image's web reports version code 1.
|
||||
- Pi image with the complete web app (built from the push of `5305f37`, or of `agent-docs-v34` once landed and pushed): watch the workflow run, then the owner deploys it (§3 step 3) and checks the web client from the laptop browser (§3 step 4); HUMAN step 2 if the NPM block is not yet current. Release 140 (W6 Insights, D-155) runs on both phones; its Insights need this image.
|
||||
@@ -113,7 +118,12 @@ Standing note for every in-app update on the Samsung phones: turn Auto Blocker o
|
||||
3. Deploy the new image (the complete web app and E-34/E-35, SPEC §10.10), once the Gitea workflow run of the pushed `main` has succeeded: on the Kvitt Pi in `~/kvitt`, set `KVITT_TAG` in `.env` to the tag the run printed, then `docker compose pull && docker compose up -d`; `server` and `backup` healthy (yes/no). Release 140 runs on both phones; S-11's Insights work once this image runs.
|
||||
4. Web client in a browser on the laptop (after step 3, D-156): on the phone, Inställningar › Para ihop en enhet › För mig, create a code; on the laptop open `https://kvitt.suorra.duckdns.org/app/`, "Logga in i Kvitt", type the code, log in: Home shows (yes/no). Then, each yes/no: Home and one account open; add, edit and delete an expense; Sök, export a CSV and open it in Numbers (columns and amounts right); Gör upp: record a payment and delete it; Statistik, open a category row (line chart), Insikter; each Settings page opens; on the phone Inställningar › Enheter shows `Web · <browser>`, "Ta bort åtkomst" on it, and the browser shows the login page with the removed-device message.
|
||||
|
||||
5. Card purchases, K0 (PLAN-K0 §8; relay one at a time, skip what is done; the application with the redirect URL `https://kvitt.suorra.duckdns.org/cards/callback` may already exist): (a) sign up at `https://enablebanking.com` (Control Panel), confirm the email, accept the Terms of Service (licence step, yes/no); (b) Control Panel › API applications › "Add a new application": Production, name "Kvitt", redirect URL exactly `https://kvitt.suorra.duckdns.org/cards/callback`, key generated in the browser, register: a `.pem` downloads (yes/no); (c) move the `.pem` into `/Users/jhag/projects/kvitt/docs/spikes/k0/.local/`, keeping its name; (d) recommended: add the `location = /cards/callback { … }` block of SPEC §10.5.2 to NPM's Advanced tab, Save, row Online (yes/no); (e) the application › "Activate by linking accounts": Sweden, SJ Prio Mastercard, BankID: the card is linked (yes/no); (f) with the partner: link her card with her BankID (yes/no, or the exact message); (g) the test app with the agent: connect, paste the address, "Uppdatera", "Bakgrundshämtning" (yes/no each); (h) the next day the same without BankID (yes/no).
|
||||
6. Card artwork (when K2 runs): the SJ Prio Mastercard PNG (at least 1012 × 638 px) at `android/feature/cards/src/main/res/drawable-nodpi/card_sj_prio_mastercard.png`, and the same file at `web/src/features/cards/assets/card-sj-prio-mastercard.png` (owner cleared its use, D-173).
|
||||
|
||||
## 4. Owner questions (asked, unanswered)
|
||||
- OQ-7 (SPEC §12): a notification for new card purchases? Default: none in this version (D-171).
|
||||
- OQ-8 (SPEC §12): turning several card purchases into expenses at once? Default: not in this version (D-171).
|
||||
- Firewall rule limiting the Kvitt Pi's port 8080 to the HA Pi: deferred (2026-10-24, D-156); ask again only if the owner raises it.
|
||||
- Image-build location: the Pi 3 runner or the Mac fallback; the owner decides after the current run's result (D-156).
|
||||
- State-class naming (`*Ui`, `*UiState`, `*State` mixed): fix one convention, or leave as built?
|
||||
@@ -123,9 +133,10 @@ Standing note for every in-app update on the Samsung phones: turn Auto Blocker o
|
||||
- Nothing.
|
||||
|
||||
## 6. Numbering
|
||||
- Decisions: D-001 to D-157 used, except D-008, D-009 and D-150 (never used). Next free: **D-158**.
|
||||
- Spec version: v0.34 written (L-10 implemented, W0b; no new decision). Next **v0.35**.
|
||||
- Server schema version **3** (migration 0003); next **4**. Room schema version **1** (`android/data/schemas/se.hagstedt.kvitt.data.db.KvittDatabase/1.json`); next **2**. Unchanged by v0.27 to v0.34 (no plan since needed a migration).
|
||||
- Decisions: D-001 to D-176 used, except D-008, D-009 and D-150 (never used); D-158 to D-176 are the card purchases (v0.35). Next free: **D-177**.
|
||||
- Spec version: v0.35 written (card purchases, D-158 to D-176). Next **v0.36** (K0's answers, before K1).
|
||||
- Server schema version **3** in code (migration 0003); **4** specified (migration 0004, §14.1.3) for K1. Room schema version **1** in code; **2** specified (§14.2.3) for K2.
|
||||
- New ids in v0.35: FR-22 (AC-22.1 to AC-22.15), US-18, US-19, CP-1 to CP-14 (§9.12), S-23 to S-27, W-21 to W-23, E-36 to E-44, OQ-7, OQ-8; plans K0 to K3.
|
||||
- Sync protocol **1**, push payload **1**.
|
||||
|
||||
## 7. How the work is run
|
||||
|
||||
Reference in New Issue
Block a user