- kvitt-server invite-partner: a partner invite by the admin as E-12 does (cancels the pending one, 72 h, link with
?from=<admin>), exit 2 household full, 3 no admin; README lines in server/ and infra/.
- Tests: invite-partner, migrate (schema at SCHEMA_VERSION, idempotent), healthcheck (200, 503, nothing listening),
serve SIGTERM drain (in-flight request finishes, new connections refused, exit 0; gives up after SHUTDOWN_DRAIN).
- Push sender: one info line "push sent" per message with push_type, devices_sent, devices_targeted and 8-character
device-id tails (SPEC §8.7 aggregates); per-device line stays at debug.
- tools/contracts-check.py: stale TODO(spec) replaced by the §9.11 CS-5 citation; shapes updated for invite_kind
(D-086), app_version_name (D-090) and fid (D-096), 134 checks pass.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TQd3pEP9UeN2uifbHknQ7B
- migrations/0002_categories_v2.sql, byte-identical to contracts/schema/migrations/0002_categories_v2.sql
(SPEC §14.1.1), with an identity test; SCHEMA_VERSION = 2 (E-1 reports it, the importer's check follows).
- Seed test on a fresh database (the fourteen rows of AC-7.2, server_version 11 to 14) and an upgrade test of a
v1 database in use (0001 applied through the migrator, then users, a custom, a renamed and an archived default,
an account, a recurring template, expenses): every earlier row unchanged, the four rows above the old
sequence, foreign_key_check empty, schema_version 2, a pull from the old cursor returns exactly the four rows.
- DefaultCategoryKey with the fourteen keys (wire enum and contracts/openapi.yaml); icons 33 and colours 14
(§9.7) in validation.
- The two category examples M12a held back (E-26 response-default, sync/pull-page-categories-v2) and its
contracts-check patch for them and the enum.
- Importer: splitwise_categories.csv per the §10.8 v0.8 table (D-053), DEFAULT_KEYS of fourteen, synthetic
fixtures for the finer mapping (Insurance/Försäkringar to insurance among them), a schema-1 refusal test.
- Test harnesses seed users at server_version 15/16 (after the fourteen seeds); pull counts 10 -> 14.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TQd3pEP9UeN2uifbHknQ7B
- contracts/schema/migrations/0002_categories_v2.sql: server migration 0002 rebuilds categories with the
14-key default_key CHECK, inserts housing, insurance, children and fees with server_versions taken from
the global sequence, sets schema_version 2. server-v1.sql unchanged.
- contracts/category-keywords.csv: the keyword table of the suggestion (148 entries, from docs/ux).
- contracts/test-vectors/suggest_category.json: 65 Kotlin-only cases of CS-4 to CS-6.
- contracts/examples/E-1-health: schema_version 2.
- tools/contracts-check.py: reference suggestCategory, keyword-table checks, 0002 load checks on a fresh
and an in-use database, plain icon/color check, new icon and colour tokens.
- android/domain: suggestCategory (CS-4 to CS-6, code points, platform NFC and categories through
UnicodeText), vector runner for suggest_category, eight vector files.
- server/crates/kvitt-domain/tests/vectors.rs: suggest_category is Kotlin-only.
The OpenAPI DefaultCategoryKey extension and the two new category examples are held back until the
server's wire types know the new keys (M12b).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TQd3pEP9UeN2uifbHknQ7B
Gradle project in android/ with every module of SPEC §6.2 (build-logic convention plugins, version catalog,
architecture check in check), :core:model types and repository interfaces of §14.2.4 and §14.5, :domain
implementing §14.5.2 and §14.5.4 (125 vector cases), scenario-driven fakes with the empty scenario, Room 3
entities and KvittDatabase v1 with exported schema, :app shell with Hilt, en/sv strings with MissingTranslation
as a lint error, Roborazzi goldens of the empty screen in light and dark.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
contracts/openapi.yaml (OpenAPI 3.1, E-1..E-33, error shape and the
exhaustive error code enum, device bearer scheme), contracts/schema/
server-v1.sql (SPEC §14.1 verbatim), seven test-vector files per §14.5.5,
80 examples (every JSON body of §14.3.4, every error code, sync pull/push,
every FCM push type), and tools/contracts-check.py (stdlib-only reference
of §9.1, §9.3, §9.4 and §14.5.4 plus shape checks; the M1 gate).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Write SPEC.md v0.1 from the owner interview (requirements, data model,
stack, API outline, security, business rules, deployment, milestones,
UX sprint brief, contracts). Fill the CLAUDE.md blanks, move the Gradle
pin files into android/, point the tools at android/ and server/, and
record the git bootstrap exception in the handoff.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>