feat(v1.1.2-docs): migrations + shared DocsService trait + TriggerEvent::Docs

Migrations 0013_docs.sql + 0014_docs_triggers.sql land the docs table
(JSONB body + GIN-on-jsonb_path_ops index, PK keyed on (app_id,
collection, id) for cross-app isolation) and widen the triggers.kind
and outbox.source_kind CHECK constraints to include 'docs', plus the
docs_trigger_details detail table mirroring kv_trigger_details.

picloud-shared grows the DocsService trait + DocRow/DocsListPage/
DocsError + NoopDocsService, the TriggerEvent::Docs variant with the
prev_data change-data-capture surface, the DocsEventOp enum, the docs
field on the Services bundle, and the SDK_VERSION bump 1.2 -> 1.3.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
MechaCat02
2026-06-02 19:54:56 +02:00
parent 28a3bbd37f
commit 3af8cc38c9
7 changed files with 408 additions and 8 deletions

View File

@@ -0,0 +1,36 @@
-- v1.1.2: Extend the triggers framework to recognise `docs` as the
-- second concrete kind (after `kv` in v1.1.1).
--
-- Two CHECK constraints widen (no narrowing — both lists strictly
-- gain `'docs'`); one new detail table mirrors `kv_trigger_details`'s
-- shape with `DocsEventOp` ops instead of `KvEventOp`. Dispatcher
-- routing is generic across kinds — the same code path that handles
-- `Kv | DeadLetter` outbox rows now also handles `Docs` (single match
-- arm extension on the Rust side; no migration needed).
-- Extend triggers.kind to include 'docs'. Constraint is in-line on the
-- column so Postgres auto-named it `triggers_kind_check`. Dropping the
-- old and adding the widened constraint is safe — no existing rows
-- carry a value outside the new set.
ALTER TABLE triggers DROP CONSTRAINT triggers_kind_check;
ALTER TABLE triggers ADD CONSTRAINT triggers_kind_check
CHECK (kind IN ('kv', 'dead_letter', 'docs'));
-- Extend outbox.source_kind to include 'docs'. Same shape as above;
-- v1.1.1's existing source_kinds ('http', 'kv', 'dead_letter') stay.
ALTER TABLE outbox DROP CONSTRAINT outbox_source_kind_check;
ALTER TABLE outbox ADD CONSTRAINT outbox_source_kind_check
CHECK (source_kind IN ('http', 'kv', 'dead_letter', 'docs'));
-- One row per docs trigger. Same shape as `kv_trigger_details`:
-- collection_glob — "*" matches all, "foo*" prefix-matches, "foo"
-- exact-matches (Rust-side via collection_matches).
-- ops — subset of {create, update, delete}. Empty array
-- means "any op" (matches every docs mutation in
-- the collection). The admin endpoint rejects
-- empty collection_glob; ops can be empty.
CREATE TABLE docs_trigger_details (
trigger_id UUID PRIMARY KEY REFERENCES triggers(id) ON DELETE CASCADE,
collection_glob TEXT NOT NULL,
ops TEXT[] NOT NULL
);