Commit Graph

376 Commits

Author SHA1 Message Date
logaritmisk 7d40a2cd56 chore: use cargo-nextest as the test runner
- .config/nextest.toml: hang-timeout profile (warn 60s, kill 120s)
- justfile: 'just test' = cargo nextest run --workspace + cargo test --doc
- CLAUDE.md: refresh stale Status + Commands for the real workspace + nextest

163 tests run in ~7s (vs multi-minute serial cargo test).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 22:36:59 +02:00
logaritmisk 873efe199f merge: reference-data edit/delete lifecycle (#30 + #36)
CI / web (push) Has been cancelled
Backend update/delete endpoints (audited, 409+count when referenced) and in-place
frontend edit/delete UI for vocabularies (rename), terms, authorities, and field
definitions. Shared DeleteConfirmDialog; Storybook stories. Closes #30, #36.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 22:30:00 +02:00
logaritmisk 27caaa9787 test+refactor: audit-row assertions + uniform PATCH rollback (review follow-ups)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-05 21:04:09 +02:00
logaritmisk c9120848f5 feat(web): edit/delete authorities in place (#30) 2026-06-05 20:35:26 +02:00
logaritmisk 83ca506702 feat(web): rename vocabularies + edit/delete terms in place (#30) 2026-06-05 20:32:35 +02:00
logaritmisk 65ca79f2bd feat(web): edit/delete field definitions on /fields (in-place edit pane) (#36) 2026-06-05 20:24:57 +02:00
logaritmisk 194f18c8ed feat(web): reusable DeleteConfirmDialog with in-use handling + stories 2026-06-05 20:12:23 +02:00
logaritmisk 282e6430d4 feat(web): mutation hooks + InUseError + i18n for reference-data edit/delete 2026-06-05 20:06:23 +02:00
logaritmisk 78c950d2ee chore(web): regenerate API types for reference-data edit/delete
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 20:04:03 +02:00
logaritmisk 3e7c6ad712 feat: edit/delete field definitions — audited, blocked when in use (#36)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-05 19:58:38 +02:00
logaritmisk 47240dafcc feat: edit/delete authorities, blocked when referenced (#30) 2026-06-05 19:53:20 +02:00
logaritmisk 83a7202861 feat: rename + delete vocabularies, blocked when in use (#30) 2026-06-05 19:41:39 +02:00
logaritmisk 09baf2949f feat: edit/delete terms — audited, blocked when referenced (#30)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-05 19:30:24 +02:00
logaritmisk f6053068be docs(plans): reference-data edit/delete lifecycle (#30 + #36)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 18:30:55 +02:00
logaritmisk e58b150ab2 docs(specs): reference-data edit/delete lifecycle (#30 + #36)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 18:15:53 +02:00
logaritmisk e7ae41362e chore: add 'just storybook' recipe
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 17:00:09 +02:00
logaritmisk ffcfb41c7e merge: set up Storybook (preview + MSW + stories for real components)
CI / web (push) Has been cancelled
Storybook 10.4.2 (react-vite) with the addon-vitest/a11y/docs/mcp addons.
.storybook/preview.tsx wired to the real provider tree (QueryClient + ConfigProvider
+ MemoryRouter), real CSS + i18n, and MSW reusing src/test/handlers.ts. 8 colocated
stories for real components (Button/Badge/Input/Checkbox/VisibilityBadge/LabelEditor/
Highlight/SearchResultRow) incl. one CssCheck. Boilerplate removed.

112 web tests (existing 85 survived + 27 storybook); typecheck/lint/build clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 16:58:08 +02:00
logaritmisk b2d026f217 feat(web): set up Storybook (preview + MSW + stories for real components) 2026-06-05 16:55:40 +02:00
logaritmisk 4e1138f8ce merge: follow-ups batch (#38 #28 #41 #26)
CI / web (push) Has been cancelled
#38 enum-type SearchHitView.visibility + tighten VisibilityBadge prop.
#28 set_fields 422 carries the offending field (FieldErrorView); the object form
highlights it (both direct-edit and create-redirect paths name the field).
#41 normalize localized_text values to the default language on save.
#26 pin pnpm via packageManager + align CI to pnpm 11.

85 web tests; api suite green; bundle 145.8 KB gz; en/sv parity.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 15:54:04 +02:00
logaritmisk e6fc3eaf2c build(web): pin pnpm via packageManager + align CI to pnpm 11 (#26)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-05 15:50:40 +02:00
logaritmisk b4d71b0f80 fix(web): VisibilityBadge typed to the union (#38); normalize localized_text to default language on save (#41)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-05 15:46:48 +02:00
logaritmisk 0a29127f7e fix(web): name the field in the edit banner on create->fields-error redirect (#28)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-05 15:43:35 +02:00
logaritmisk 0c9db7bcdb feat(web): highlight the offending field on a set_fields 422 (#28)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-05 15:39:49 +02:00
logaritmisk d6dc1c9b57 feat(api): field-level set_fields 422 body (#28); enum-type SearchHitView.visibility (#38)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-05 15:32:48 +02:00
logaritmisk cd3606c0e9 docs(plans): follow-ups batch (#38 #28 #41 #26)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 15:29:35 +02:00
logaritmisk 260eac903e merge: instance locale (env) + single-language content authoring
CI / web (push) Has been cancelled
DEFAULT_LANGUAGE/DEFAULT_TIMEZONE env config surfaced via public GET /api/config;
SPA config provider defaults the UI language from the instance (overridable per
browser). Content authoring collapsed to a single language (LabelEditor +
localized_text) at the instance default. The multilingual content SCHEMA is left
completely untouched (dormant) — re-enabling is UI-only, zero migration. Storage
stays UTC; timezone exposed for future display/PDF use.

81 web tests; full backend green; bundle 145.7 KB gz; en/sv parity 106/106.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 15:16:12 +02:00
logaritmisk 9d0475e8ec feat(web): single-language content authoring (LabelEditor + localized_text at default lang)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-05 15:05:20 +02:00
logaritmisk 04e9c95c52 refactor(web): split config hook/context (.ts) from provider (.tsx) to clear react-refresh lint
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-05 15:01:33 +02:00
logaritmisk de11292203 feat(web): config provider — fetch /api/config, default UI language from instance
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-05 14:58:01 +02:00
logaritmisk 825b23adec test(server): assert default_language/default_timezone config defaults 2026-06-05 14:55:37 +02:00
logaritmisk 2460a1368d feat: DEFAULT_LANGUAGE/DEFAULT_TIMEZONE config + public GET /api/config 2026-06-05 14:52:09 +02:00
logaritmisk 4a76d6043a docs(plans): instance locale + single-language content authoring (4 tasks)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 14:29:40 +02:00
logaritmisk 0f43c75b24 docs(specs): instance locale (env) + single-language content authoring
Keep the multilingual content schema (dormant); simplify authoring inputs to one
language. Default language + timezone via env vars (no settings table). Public
/api/config endpoint surfaces them to the SPA. Per-account UI language deferred.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 14:23:32 +02:00
logaritmisk 3c6a41a80a merge: tier 4 hardening batch 1 (#1 #2 #21)
#1 graceful shutdown on SIGINT/SIGTERM (axum with_graceful_shutdown).
#2 configurable DB pool size (--db-max-connections / DB_MAX_CONNECTIONS, default 5).
#21 audit vocabulary/term/authority creation atomically, attributing the acting
user; ~15 call sites threaded an AuditActor.

173 workspace tests; clippy + fmt clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 22:10:13 +02:00
logaritmisk 146e0164e7 refactor(db): name audit entity_type constants for vocab/term/authority (#21)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 22:05:06 +02:00
logaritmisk 984be697ac feat: audit vocabulary/term/authority creation, attributing the acting user (#21)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 21:54:50 +02:00
logaritmisk 7181437625 feat(server): configurable DB pool size via --db-max-connections/DB_MAX_CONNECTIONS (#2)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 21:46:41 +02:00
logaritmisk 7e235ffd3e feat(server): graceful shutdown on SIGINT/SIGTERM (#1) 2026-06-04 21:42:55 +02:00
logaritmisk b0d2c247df docs(plans): tier 4 hardening batch 1 (#1 #2 #21)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 21:41:29 +02:00
logaritmisk e9a5a10524 chore: sync Cargo.lock — domain gains utoipa (tier 3 #3)
CI / web (push) Has been cancelled
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 20:26:21 +02:00
logaritmisk df113bd7ac merge: tier 3 typed-client (#3 #24 #29)
Decision #3 = Option A (utoipa::ToSchema allowed in domain, no I/O deps).
domain: ToSchema on Visibility/AuthorityKind + new DataType enum.
api: open-map fields (#24); enum value_types for visibility/data_type/kind (#29);
domain enums registered in OpenAPI; client regenerated. Frontend: dropped the
now-redundant fields/visibility casts. Wire format unchanged; schema diff additive.

domain 26 + api 41 + web 78 tests; bundle 145.5 KB gz.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 20:25:54 +02:00
logaritmisk 0ee3b970cb refactor(web): drop redundant fields/visibility casts now the client is typed (#24 #29)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 20:20:13 +02:00
logaritmisk 5a72f85989 feat(api): enum-typed visibility/data_type/kind + open-map fields in OpenAPI (#24 #29)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 20:14:30 +02:00
logaritmisk d3c33a6c5d feat(domain): derive ToSchema on Visibility/AuthorityKind; add DataType enum (#3 Option A)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 20:08:41 +02:00
logaritmisk 331a6d7f34 docs(plans): tier 3 typed-client (#3 Option A, #24, #29)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 20:06:27 +02:00
logaritmisk 0d971cda15 merge: tier 2 papercuts (#22 #18 #9 #4 #34 #31 #32 #37)
CI / web (push) Has been cancelled
Backend: add_term FK→404 (#22); log discarded errors on public 500 paths (#18);
enum↔CHECK cross-ref comments (#9); drop dead clone + harden serve smoke test (#4).
Frontend: search 503 'unavailable' vs generic error (#34); loading/error states on
terms & authorities lists (#31); authority kind-tab ARIA + dead i18n key removal
(#32); authority-kind reveal test (#37).

78 web tests; 72 backend tests; bundle 145.5 KB gz.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 17:39:35 +02:00
logaritmisk 914527edc6 fix(web): place aria-selected on the role=tab element (#32) + assert it
Per WAI-ARIA, aria-selected must be on the same element carrying role="tab".
The previous impl placed it on an inner <span> via the render-prop, making it
invisible to assistive technology. Move both role="tab" and aria-selected to
the NavLink, compute currentKind once from useParams, drop the render-prop.
Add a Vitest assertion that the selected tab has aria-selected="true" and an
unselected tab has aria-selected="false".

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 17:32:18 +02:00
logaritmisk ff513e1712 fix(web): search 503 vs error (#34); terms/authorities list error states (#31); authority-tab a11y + dead keys (#32); authority-kind test (#37) 2026-06-04 17:28:01 +02:00
logaritmisk 1a91b8a242 chore: cross-ref enum/CHECK constraints (#9); drop dead clone + harden smoke test (#4)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 17:21:33 +02:00
logaritmisk 2bce469ed2 fix(api): 404 when adding a term to a missing vocabulary (#22); log public 500s (#18)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 17:17:35 +02:00