Commit Graph
94 Commits
Author SHA1 Message Date
logaritmiskandClaude Sonnet 4.6 8b929c7180 refactor(api): descriptive closure params; exhaustive FieldError match; field-endpoint auth tests
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 22:16:50 +02:00
logaritmiskandClaude Sonnet 4.6 b6a30c3995 feat(api): admin set flexible fields + field-definition listing
- GET /api/admin/field-definitions (ViewInternal) — lists all registered
  field definitions with key, data_type, vocabulary_id, authority_kind,
  required, group, and localized labels
- PUT /api/admin/objects/{id}/fields (EditCatalogue) — replaces an
  object's flexible-field values with replace semantics; validates every
  key against the registry (UnknownField → 422, TypeMismatch → 422,
  Unresolved → 422, ObjectNotFound → 404, Db → 500)
- FieldDefinitionView DTO added; both handlers registered in OpenAPI

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 22:09:43 +02:00
logaritmiskandClaude Sonnet 4.6 34e5754815 refactor(api): read object visibility inside update tx; breathing-room nits
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 22:05:54 +02:00
logaritmiskandClaude Sonnet 4.6 3f4da46b78 feat(api): admin object create/update/delete (EditCatalogue, audited as user)
POST /api/admin/objects (draft|internal only; public rejected 422),
PUT /api/admin/objects/{id} (preserves visibility; 204/404),
DELETE /api/admin/objects/{id} (204/404). Every write records
AuditActor::User(<session-user-uuid>). Tests: lifecycle, public-rejection,
unauthenticated-rejection.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 21:59:14 +02:00
logaritmiskandClaude Sonnet 4.6 1888e185f7 refactor(api): share Pagination across admin/public; cover get-by-id auth
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 21:53:21 +02:00
logaritmiskandClaude Sonnet 4.6 0055616099 feat(api): admin object read surface (paginated list + get, ViewInternal)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 21:45:53 +02:00
logaritmisk 3dc621b6dd docs(plans): admin CRUD — object lifecycle + vocab/authority management 2026-06-02 19:02:47 +02:00
logaritmisk 807ac1a9f8 chore: sync Cargo.lock with auth dependencies 2026-06-02 15:21:03 +02:00
logaritmisk 5cfee93037 merge: authentication (email/password) — sessions, extractors, admin surface, CLI bootstrap 2026-06-02 15:20:36 +02:00
logaritmisk 369eee4098 fix(server): --session-cookie-secure flag; scope+char-count password; invalid-email test 2026-06-02 15:16:46 +02:00
logaritmiskandClaude Sonnet 4.6 dbff95c2a9 feat(server): create-user CLI + session-store migration on startup
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 15:07:58 +02:00
logaritmisk 642f709bbe fix(api): drop redundant dev-deps; fix server AppState for cookie_secure; add logout + illegal-transition tests 2026-06-02 15:04:07 +02:00
logaritmiskandClaude Sonnet 4.6 5135aeee6c feat(api): admin auth surface (login/logout/me/users/publish) on tower-sessions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 14:54:03 +02:00
logaritmisk 4e7288731a harden(auth): distinguish session-store failure (500) from absent session (401); exhaustive marker + verify_dummy tests 2026-06-02 14:48:40 +02:00
logaritmiskandClaude Sonnet 4.6 992526ef77 feat(auth): argon2id hashing + AuthUser/Authorized<Cap> session extractors
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 14:45:13 +02:00
logaritmisk bea9b6b39a harden(db): case-insensitive email unique index + dup-email test; list_users pagination TODO; from_db note 2026-06-02 14:42:04 +02:00
logaritmiskandClaude Sonnet 4.6 f8ec2d7cf1 feat(db): users table + repository (create/by_id/by_email/list), audited
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 14:37:43 +02:00
logaritmisk 9597a42eeb fix(domain): make Editor capability policy fail-closed (exhaustive match) 2026-06-02 14:32:13 +02:00
logaritmiskandClaude Sonnet 4.6 74b2cf65ed feat(domain): user identity (UserId, Email), Role/Capability policy
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 14:29:04 +02:00
logaritmisk 1ed9798a1f docs(plans): authentication (email/password) — sessions, extractors, CLI bootstrap 2026-06-02 14:26:19 +02:00
logaritmisk 6cd01f9b97 merge: publishing — visibility transitions, PublicView & public read API 2026-06-02 14:04:32 +02:00
logaritmisk 1b48f082ee chore: sync Cargo.lock after dropping api's uuid dep 2026-06-02 14:04:32 +02:00
logaritmisk 720c7ddbbf chore(api): drop unused uuid dep + redundant domain dev-dep; test internal exclusion + note list/count race 2026-06-02 13:55:01 +02:00
logaritmisk 3c4ada202f feat(api): public read API (PublicView projection, paginated list + get, OpenAPI) 2026-06-02 13:48:17 +02:00
logaritmiskandClaude Sonnet 4.6 b948cae269 refactor(db): share update path so set_visibility avoids a redundant fetch; tie public-visibility const to the enum; test internal exclusion
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 13:35:36 +02:00
logaritmiskandClaude Sonnet 4.6 14cdd2a04a feat(db): audited stepwise set_visibility + public-only object readers
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 13:24:29 +02:00
logaritmisk 5e2ebbc8d9 test(domain): assert IllegalTransition Display message 2026-06-02 13:14:37 +02:00
logaritmiskandClaude Sonnet 4.6 59400062ae feat(domain): stepwise Visibility state machine (transition_to + IllegalTransition)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 13:11:01 +02:00
logaritmisk 5ea1febb91 docs(plans): publishing — visibility transitions, PublicView, public read API 2026-06-02 12:50:31 +02:00
logaritmisk f0e00fba40 merge: search (Meilisearch full-text over catalogue objects) 2026-06-02 12:35:37 +02:00
logaritmisk fac4b703ff docs(search): document eventual-consistency model; drop stale Task 2 note 2026-06-02 12:15:18 +02:00
logaritmisk 4bafac397a docs(search): note why reindex test references db crate migrations 2026-06-02 12:12:12 +02:00
logaritmiskandClaude Sonnet 4.6 7b91989411 feat(search): build documents resolving term/authority labels; reindex_all
Implements build_document in the search crate: resolves Term and Authority
flexible-field values to their human-readable labels so reindex_all produces
documents that Meilisearch can match on label text, not raw UUIDs.
Adds integration test covering the full reindex→search round-trip.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 12:08:07 +02:00
logaritmiskandClaude Sonnet 4.6 b8d198f150 fix(search): surface failed Meilisearch tasks; make ensure_index idempotent
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 11:50:58 +02:00
logaritmiskandClaude Sonnet 4.6 dc903989f7 feat(search): add Meilisearch-backed SearchClient (index, search, remove)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 11:43:53 +02:00
logaritmiskandClaude Opus 4.8 851181d91d docs: add Plan 6 (Meilisearch search) implementation plan
search crate (SearchClient adapter) indexing core + flexible fields with
term/authority resolved to labels; reindex_all; on-write sync deferred to API.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 11:39:55 +02:00
logaritmisk 5ee9fd88f1 polish(db): clearer maker label; assert group_key and vocabularies in seed tests 2026-06-02 11:25:10 +02:00
logaritmiskandClaude Sonnet 4.6 adc7c61ee2 feat(db): seed a representative Spectrum cataloguing field set (idempotent)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 11:20:35 +02:00
logaritmiskandClaude Opus 4.8 91a9eb2964 docs: add Spectrum cataloguing seed plan
Idempotent seed of a representative subset: 3 vocabularies + 12 descriptive field
definitions with term/authority bindings. Empty vocabularies; wiring deferred.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 11:17:56 +02:00
logaritmisk f30ce9d9dc docs(db): note deferred date-format validation (#11) at the Date field arm 2026-06-02 11:12:00 +02:00
logaritmiskandClaude Sonnet 4.6 45c1d1b123 test(db): cover authority-kind, cross-vocabulary, localized text, replace/remove, no-op, missing object
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 11:07:43 +02:00
logaritmiskandClaude Sonnet 4.6 c94fd1638c docs(db): document set_object_fields replace semantics and required-field deferral
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 11:04:45 +02:00
logaritmiskandClaude Sonnet 4.6 2b0056c038 feat(db): set_object_fields with registry validation and audited diffs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 10:59:23 +02:00
logaritmiskandClaude Opus 4.8 2aaf98794f feat(db): add object.fields jsonb column, read it into CatalogueObject
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 10:54:49 +02:00
logaritmiskandClaude Opus 4.8 7b0f804461 docs: add Plan 5 (Object flexible-field values) implementation plan
object.fields jsonb + set_object_fields with registry validation (type +
term/authority resolution) + audited per-field diffs; typed FieldError.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 10:52:38 +02:00
logaritmisk f4152b2102 test(db): cover any-kind authority, scalar, zero-label, and list ordering for field definitions 2026-06-02 10:27:06 +02:00
logaritmiskandClaude Sonnet 4.6 66ad67ca77 feat(db): add field-definition registry repository
Implements create_field_definition, field_definition_by_key, and
list_field_definitions in db::fields, with TDD integration tests
covering text, term, and authority field type round-trips.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 10:21:39 +02:00
logaritmiskandClaude Sonnet 4.6 cbed662c18 feat(db): add field_definition tables
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 10:16:30 +02:00
logaritmisk 6e27288f43 fix(domain): make FieldType::from_parts a strict inverse; reject stray bindings 2026-06-02 10:15:07 +02:00
logaritmiskandClaude Sonnet 4.6 2242ff5ef1 feat(domain): add field definition types (FieldType, FieldDefinition)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 10:11:28 +02:00
logaritmiskandClaude Opus 4.8 da2db11a30 docs: add Plan 4 (Field-definition registry) implementation plan
Type-driven FieldType enum carrying binding; field_definition + labels tables with
a CHECK enforcing term<->vocabulary; create/read/list repository.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 10:09:46 +02:00
logaritmiskandClaude Sonnet 4.6 2938649d62 fix(db): skip UPDATE and audit on no-op object update (keep updated_at consistent)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 09:40:27 +02:00
logaritmisk a690c60ec6 refactor(db): delete_object via rows_affected; test update/delete-missing and field clearing 2026-06-02 09:36:44 +02:00
logaritmiskandClaude Sonnet 4.6 9e1c88b294 feat(db): add catalogue object update/delete with audited field diffs
update_object records only changed fields as audit diffs and skips the
audit entry for no-op updates; delete_object records a Deleted entry.
Both operations are atomic on the caller's connection.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 09:32:16 +02:00
logaritmiskandClaude Sonnet 4.6 616a6f05c6 refactor(db): DRY object SELECT columns, consistent date json; test date + all-none round-trip
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 09:29:40 +02:00
logaritmiskandClaude Sonnet 4.6 e0c0187f29 feat(db): add catalogue object create/read/list with audit on create
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 09:24:03 +02:00
logaritmisk 95357f01dd feat(db): non-empty CHECK constraints on object text columns 2026-06-02 09:21:08 +02:00
logaritmiskandClaude Sonnet 4.6 c1dda280e2 feat(db): add object table
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 09:18:03 +02:00
logaritmisk bf332ac0ae test(domain): pin Visibility serde output to as_str 2026-06-02 09:16:53 +02:00
logaritmisk 266f914b88 feat(domain): add catalogue object types (Visibility, ObjectInput, CatalogueObject) 2026-06-02 09:13:54 +02:00
logaritmiskandClaude Opus 4.8 ed608c6e37 docs: add Plan 3 (Catalogue core) implementation plan
Typed inventory-minimum object record + CRUD; first consumer of the audit spine
(create/update/delete record audit entries with field-level diffs in the write tx).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 09:12:41 +02:00
logaritmisk 7782bd764a test(db): zero-label authority round-trip; doc the labels-json constant
Also fix pre-existing clippy::explicit_auto_deref in all db test files
(&mut *tx → &mut tx across authority.rs and vocab.rs).
2026-06-02 09:01:06 +02:00
logaritmiskandClaude Sonnet 4.6 6e45baa8d4 feat(db): add authority repository with multilingual labels
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 08:55:50 +02:00
logaritmisk 345073b130 test(db): cover zero-label term and duplicate vocabulary key; use try_get in vocabulary_by_key 2026-06-02 08:52:58 +02:00
logaritmiskandClaude Sonnet 4.6 5dc07ddf4c feat(db): add vocabulary/term repository with multilingual labels
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 08:48:51 +02:00
logaritmisk cc1fbf5b7d feat(db): RESTRICT vocabulary deletes; non-empty label/lang constraints 2026-06-02 08:46:34 +02:00
logaritmiskandClaude Sonnet 4.6 93d54d7783 feat(db): add vocabulary, term, and authority tables
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 08:43:23 +02:00
logaritmiskandClaude Sonnet 4.6 d5ed2a261f feat(domain): restore must_use message; test TermRef accessors
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 08:42:14 +02:00
logaritmisk 8cf737d8a9 feat(domain): id macro + vocabulary/authority/label value types 2026-06-02 08:38:39 +02:00
logaritmiskandClaude Opus 4.8 42e0a5f5f1 docs: add Plan 2 (Vocabularies & authorities) implementation plan
Unified authority table + normalized multilingual label tables; vocab/authority
repositories; TermRef/AuthorityRef validated refs; id_newtype! macro.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 08:36:03 +02:00
logaritmisk cc26c96a82 chore: update Cargo.lock for audit-spine dependencies 2026-06-02 08:02:09 +02:00
logaritmisk 86a3a8a47c test(db): assert audit_log mutations fail via the immutability trigger 2026-06-02 08:01:28 +02:00
logaritmiskandClaude Sonnet 4.6 45aea6b702 test(db): enforce audit_log immutability and transactional atomicity
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 07:58:10 +02:00
logaritmiskandClaude Sonnet 4.6 c67b588188 test(db): cover delete/empty-changes/empty-history; clarify map_row naming
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 07:56:05 +02:00
logaritmiskandClaude Sonnet 4.6 87b016a56c feat(db): add append-only audit repository (record, history_for)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 07:52:16 +02:00
logaritmisk 01c42837d1 feat(db): also reject TRUNCATE on audit_log (statement-level trigger) 2026-06-02 07:49:47 +02:00
logaritmiskandClaude Sonnet 4.6 152fc30116 feat(db): schema bootstrap with append-only audit_log table
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 07:46:39 +02:00
logaritmiskandClaude Sonnet 4.6 4c6f77b999 test(domain): pin audit serde contracts; loosen time version; note null caveat
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 07:44:21 +02:00
logaritmiskandClaude Sonnet 4.6 0447284d43 feat(domain): add audit value types
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 07:40:02 +02:00
logaritmiskandClaude Opus 4.8 d3f5e73dad docs: add Plan 1 (Audit spine) implementation plan
Append-only immutable audit log: domain value types, schema-bootstrap migration
+ immutability trigger, transaction-capable record/history_for repository.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 07:38:08 +02:00
logaritmisk 19c7bdc3ae feat(server): wire config, database, and HTTP serving 2026-06-02 01:04:04 +02:00
logaritmisk b8cea49427 test(api): assert readiness status field on happy path 2026-06-02 01:02:22 +02:00
logaritmiskandClaude Sonnet 4.6 b9acc03761 feat(api): add health probes, OpenAPI doc, and router
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 00:58:29 +02:00
logaritmisk 8da3eefdce feat(db): add Db handle with pool connect and readiness ping 2026-06-02 00:54:17 +02:00
logaritmiskandClaude Sonnet 4.6 db6183405e chore: add local Postgres, justfile, and env example
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 00:51:26 +02:00
logaritmiskandClaude Sonnet 4.6 67057e2ee3 test(server): isolate config tests from ambient env via temp-env
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 00:50:12 +02:00
logaritmiskandClaude Sonnet 4.6 08e5f797f8 feat(server): add clap-derive Config (args + env)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 00:46:31 +02:00
logaritmisk b9b99c0332 refactor(domain): delegate OrgId Display, rename to_uuid, mark new must_use 2026-06-02 00:44:49 +02:00
logaritmiskandClaude Sonnet 4.6 8ae9de12c0 feat(domain): add OrgId newtype
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 00:41:32 +02:00
logaritmisk b97c950f77 chore: replace placeholder package with role-named workspace 2026-06-02 00:38:53 +02:00
logaritmiskandClaude Opus 4.8 87f06d1f2d docs: add placeholder README
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 00:35:01 +02:00
logaritmiskandClaude Opus 4.8 caa12f5366 docs: add Plan 0 (Foundation) implementation plan
Bite-sized TDD plan: role-named workspace, clap-derive config, sqlx Db handle,
axum health probes + config-driven OpenAPI, server wiring, local dev tooling.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 00:29:25 +02:00
logaritmiskandClaude Opus 4.8 8f67503f45 docs: add project vision, MVP architecture spec, and reference material
- docs/VISION.md: product vision + feature catalogue (MVP / post-MVP / later)
- docs/specs/2026-06-02-mvp-architecture.md: MVP architecture + 16-entry decision log
- reference/: Spectrum 5.0 cataloguing + Riksantikvarieämbetet source material (build-time reference)
- CLAUDE.md: project guidance for Claude Code

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 00:24:53 +02:00
logaritmisk 283e27fa06 initial commit 2026-06-01 21:37:20 +02:00