set_visibility now gates the transition to Public: every field definition
with required=true must have a value on the object (typed inventory-minimum
columns are already NOT NULL, so only flexible required fields are checked).
Missing values yield VisibilityError::MissingRequiredFields(keys); the admin
publish endpoint maps it to 422. The gate runs in db so every caller is
protected and the check is atomic with the transition.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Wire best-effort Meilisearch index sync into the admin write paths
(create/update/delete/set_fields/set_visibility). Adds
SearchClient::sync_object (reindex if the object exists, remove if gone —
one uniform path), an optional AppState.search client, and a reindex
helper that logs failures via tracing without failing the committed
write. Server gains MEILI_URL/MEILI_MASTER_KEY/MEILI_INDEX config;
search stays disabled (no-op) when unset. reindex_all remains the
recovery path.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
GET/POST /api/admin/vocabularies and GET/POST /api/admin/vocabularies/{id}/terms;
reads gated on ViewInternal, writes on EditCatalogue; labels round-trip verified.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 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>
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>