SPEC §15.6 W-21 to W-23, §9.12 CP-1 to CP-14, FR-22 (D-174, D-180):
- api/cards.ts: the card snapshot read through E-40 (pulled from 0, then from its
cursor on focus, every 60 s and after every card write; cursor_ahead restarts),
E-44 sent at once; shared because cards, expenses, accounts and settings read it.
- features/cards: W-21 Kortköp (header with artwork, Uppdatera via E-42, filters with
counts, day groups, Preliminär/Insättning/Utländsk valuta, the CP-10 match chip,
the purchase as a side panel from 720 px and a dialog below with every S-23 sheet
action, expiring/expired/fetch-failed/first-fetch/empty states, ?attempt= polling
E-38 every 2 s, ?account= as S-27); W-22 catalogue and connect step (history
7/30/90/180, E-37 with client web, the bank's https page in the same tab);
W-23 the connection (E-41 shorter history, renew, E-43 with erase_handled).
The committed SJ Prio artwork mapped from image key sj_prio_mastercard, the
D-173 drawn card for unknown keys.
- lib/domain/matchCardPurchase (§14.5.8) with its cases; vectors.test.ts runs K1's
match_card_purchase.json against it (moved from NOT_PORTED to PORTED).
- W-5 ?cardPurchase= prefill per CP-9 and the link on save; W-6 card line with
Ta bort koppling; W-3 "Från kortköp" while connected; W-13 "Anslut kort" row.
- Sidebar and bottom bar: Kortköp after Översikt (D-172); icons credit_card,
link_off, visibility_off added to the generated table; /cards in the dev proxy.
- test/cards.ts fixtures and the fake server's card endpoints.
Strings: the §13.3 keys from K2's docs/ux/strings.csv (dictionaries regenerated), plus
K2's cards_foreign_amount (the foreign amount) and settings_cards_expired (W-13 row of an
ended connection); web-only texts as web_cards_ and web_expenses_ keys.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TQd3pEP9UeN2uifbHknQ7B
W-5 expense editor (S-7): amount, description, category quick row and
"Alla" grid with the §9.11 suggestion for a new expense (CS-1 to CS-7),
the four fixed option rows (D-102), split modes default, ratio, exact and
full with live shares, notes, inline §9.6 validation, one POST /sync per
save, delete with confirmation, the discard dialog on Cancel, Esc and
in-app navigation (D-080), rejection and network failures shown on the
page with the form kept (§15.5). Defaults per AC-8.6 with this browser's
last account and category; ?account= preselects the opener's account.
W-6 expense detail (S-8): hero, facts, shares and mode, recurring
template badge, the AC-12.4 timeline, deleted and missing states.
W-12 search with filters in the URL query, count and sum, rows a hundred
at a time, and the CSV export (UTF-8 BOM, semicolons, CRLF, decimal
comma, ISO dates, header in the page language), built in the browser.
The §9.11 port passes contracts/test-vectors/suggest_category.json (65
cases); the keyword table is a Vite raw import of
contracts/category-keywords.csv, which needs ../contracts in
server.fs.allow (vite.config.ts).
Shared editor fields of design-spec §3.7 in web/src/components/editor/
for W5's template editor.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TQd3pEP9UeN2uifbHknQ7B
web/ is the browser client's scaffold: Vite 8, React 19, TypeScript 5.9 strict, React Router 7 (basename /app, every
fixed route with a lazy placeholder page), TanStack Query 5 (refetch on focus and every 60 s), openapi-typescript
types generated from contracts/openapi.yaml with openapi-fetch. Reads go through GET /sync (no REST reads exist for
the ledger, SPEC §7): useLedger() pulls from cursor 0 and then incrementally, restarting on a new epoch or
cursor_ahead. Login pairs the browser as "Web · <browser>" with an invite code (E-3); every call sends the SPEC
§14.3.1 headers, a 401 signs out. kvitt-domain's split, balances, allocation and settlement rules are ported to
web/src/lib and pass every case of contracts/test-vectors. Design tokens from design-spec §2 in tokens.css
(light-dark()), Material Symbols Rounded (Apache-2.0) as generated inline SVG, sv/en catalogs generated from
docs/ux/strings.csv plus web-strings.csv. Gate: cd web && npm run check.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TQd3pEP9UeN2uifbHknQ7B