Quick and Claude Opus 5
05af63ea2b
feat(settings): add canonical typed storage for the settings contract
...
The cross-platform settings contract needs one typed store behind it before a
resolver, routes or a migration can exist. This adds that storage to both
user-store backends and holds them to identical behavior.
PostgreSQL gets user_setting_values with the scope CHECK constraints, the five
partial unique indexes that enforce one explicit value per identity, and the
covering indexes the one-query read path needs, plus user_setting_mutations for
mutation_id idempotency and the inert user_setting_migration_rejects audit
table. The per-user SQLite store gets the same shape minus user_id, since that
database is already user-scoped.
The UserStore interface grows the typed operations: read one explicit value at
one scope, collect every candidate row for a resolution request in a single
query, upsert with a revision increment, unset, and the idempotency receipt
operations. The resolution read deliberately returns unranked candidates so the
resolver can rank in Go — one query per request, never one per scope, which the
pgx query-count test pins.
Delete behavior is application-enforced. Neither backend can inherit it from
constraints: the SQLite store declares no foreign keys, and library, series and
device columns are not FK targets in Postgres either. Profile deletion cascades
to profile-anchored values while account scope survives, forgetting a device
clears its profile_device values alongside the legacy overrides, and the
library/series purges remove only what is scoped to that entity.
The shared conformance suite covers all of it, including the set-versus-unset
distinction for false, 0, "" and null, so a divergence between the two backends
fails a test rather than reaching a client.
Part of #376
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com >
2026-07-27 01:22:23 +00:00
..
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-07 15:57:05 -04:00
2026-06-07 15:57:05 -04:00
2026-06-07 15:57:05 -04:00
2026-06-07 15:57:05 -04:00
2026-06-07 15:57:05 -04:00
2026-06-07 15:57:05 -04:00
2026-06-07 15:57:05 -04:00
2026-06-07 15:57:05 -04:00
2026-06-07 15:57:05 -04:00
2026-06-07 15:57:05 -04:00
2026-06-07 15:57:05 -04:00
2026-06-07 15:57:05 -04:00
2026-06-07 15:57:05 -04:00
2026-06-07 15:57:05 -04:00
2026-06-07 15:57:05 -04:00
2026-06-07 15:57:05 -04:00
2026-06-07 15:57:05 -04:00
2026-06-07 15:57:05 -04:00
2026-06-07 15:57:05 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-06 23:51:30 -04:00
2026-06-09 13:00:48 -04:00
2026-06-08 18:17:08 -04:00
2026-06-07 15:57:05 -04:00
2026-06-07 17:18:55 -04:00
2026-06-07 17:18:55 -04:00
2026-06-09 13:00:48 -04:00
2026-06-07 21:32:40 -04:00
2026-06-10 08:18:35 -04:00
2026-06-10 08:18:35 -04:00
2026-06-10 08:18:35 -04:00
2026-06-09 13:00:48 -04:00
2026-06-08 21:55:35 -04:00
2026-06-08 21:55:35 -04:00
2026-06-08 21:55:35 -04:00
2026-06-16 17:58:01 -04:00
2026-06-16 18:17:08 -04:00
2026-06-09 19:28:53 -04:00
2026-06-09 19:44:40 -04:00
2026-06-10 08:18:35 -04:00
2026-06-10 08:18:35 -04:00
2026-06-10 08:18:35 -04:00
2026-06-10 17:18:18 -04:00
2026-06-10 14:58:54 -04:00
2026-06-10 14:58:54 -04:00
2026-06-10 11:56:59 -04:00
2026-06-16 20:13:10 -04:00
2026-06-10 16:02:42 -04:00
2026-06-16 20:13:10 -04:00
2026-06-11 14:55:46 -04:00
2026-06-11 14:55:46 -04:00
2026-06-11 14:55:46 -04:00
2026-06-11 16:04:22 -04:00
2026-06-11 18:09:37 -04:00
2026-06-11 17:16:27 -04:00
2026-06-11 19:51:03 -04:00
2026-06-11 19:51:03 -04:00
2026-06-11 20:55:30 -04:00
2026-06-11 23:04:35 -04:00
2026-06-12 16:20:55 -04:00
2026-06-12 09:32:53 -04:00
2026-06-15 15:34:13 -04:00
2026-06-15 15:34:13 -04:00
2026-06-17 13:12:18 -04:00
2026-06-17 09:51:43 -04:00
2026-06-17 09:51:43 -04:00
2026-06-16 20:13:10 -04:00
2026-06-17 13:48:57 -04:00
2026-06-18 10:07:58 -04:00
2026-06-18 10:07:58 -04:00
2026-07-02 14:23:14 -04:00
2026-06-19 06:13:26 +02:00
2026-07-01 22:05:36 -04:00
2026-07-01 22:05:36 -04:00
2026-07-01 22:05:36 -04:00
2026-07-01 22:05:36 -04:00
2026-06-23 14:26:14 -04:00
2026-06-24 11:03:38 -04:00
2026-06-24 11:03:38 -04:00
2026-06-25 13:29:30 -04:00
2026-06-25 16:20:14 -04:00
2026-06-25 20:46:08 -04:00
2026-06-25 20:46:08 -04:00
2026-06-25 20:50:45 -04:00
2026-06-25 22:43:23 -04:00
2026-06-26 12:09:45 -04:00
2026-06-26 16:05:53 -04:00
2026-06-26 16:05:53 -04:00
2026-06-26 16:06:01 -04:00
2026-07-01 23:21:25 -04:00
2026-07-01 17:25:16 -04:00
2026-07-01 17:25:16 -04:00
2026-07-01 22:05:36 -04:00
2026-07-01 22:05:36 -04:00
2026-07-02 11:42:28 -04:00
2026-07-05 00:16:34 -04:00
2026-07-05 00:16:34 -04:00
2026-07-05 17:38:19 -04:00
2026-07-05 17:38:19 -04:00
2026-07-05 17:38:19 -04:00
2026-07-05 17:38:19 -04:00
2026-07-04 23:43:19 -04:00
2026-07-05 17:38:19 -04:00
2026-07-05 00:19:31 -04:00
2026-07-05 14:58:19 -04:00
2026-07-06 12:23:32 -04:00
2026-07-06 18:52:44 -04:00
2026-07-06 18:52:44 -04:00
2026-07-06 18:52:44 -04:00
2026-07-09 09:55:51 -04:00
2026-07-09 10:28:06 -04:00
2026-07-09 14:13:31 -04:00
2026-07-09 14:13:31 -04:00
2026-07-09 19:06:36 -04:00
2026-07-09 23:08:04 -04:00
2026-07-10 22:30:04 -04:00
2026-07-10 22:30:04 -04:00
2026-07-16 14:34:35 -04:00
2026-07-16 17:55:36 -04:00
2026-07-14 11:51:27 -04:00
2026-07-16 17:55:36 -04:00
2026-07-14 11:51:27 -04:00
2026-07-14 00:21:46 +02:00
2026-07-14 00:21:46 +02:00
2026-07-16 17:33:21 -04:00
2026-07-14 13:44:39 -04:00
2026-07-14 16:04:43 -04:00
2026-07-16 13:58:44 -04:00
2026-07-22 13:43:57 +02:00
2026-07-22 13:43:57 +02:00
2026-07-21 10:03:11 -04:00
2026-07-24 12:02:52 -04:00
2026-07-24 12:18:49 -04:00
2026-07-24 12:18:49 -04:00
2026-07-24 12:02:52 -04:00
2026-07-24 12:18:49 -04:00
2026-07-26 11:19:33 -04:00
2026-07-27 01:22:23 +00:00