feat(modules): group-docs schema + kind-generalized registry (§11.6 docs C1)
Data layer for extending shared group collections from KV to docs. KV behavior
unchanged (callers pass kind="kv").
- 0054_group_docs.sql: widen the group_collections kind CHECK to ('kv','docs')
and add the group-keyed group_docs store (clone of docs/0013, keyed by
group_id, CASCADE on group delete) + its (group_id,collection) and data GIN
indexes.
- group_collection_repo: thread a `kind` parameter through list_for_owner,
resolve_owning_group, insert/delete_collection_tx; add list_all_for_owner ->
(name,kind) for the kind-aware diff (D4). Relocate the injectable
GroupCollectionResolver trait + Postgres impl here (now shared by kv+docs;
resolve takes kind) — was in group_kv_service.
- group_docs_repo: a near-clone of docs_repo keyed by group_id; find reuses the
generalized build_find_query.
- docs_repo: generalize build_find_query(table, owner_col, owner_id, …) — both
are compile-time literals (no injection); app docs passes ("docs","app_id"),
group docs ("group_docs","group_id"). row_to_doc/build_find_query are now
pub(crate) for reuse.
Schema snapshot re-blessed (55 migrations).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -231,6 +231,14 @@ table: group_collections
|
||||
created_at: timestamp with time zone NOT NULL default=now()
|
||||
updated_at: timestamp with time zone NOT NULL default=now()
|
||||
|
||||
table: group_docs
|
||||
group_id: uuid NOT NULL
|
||||
collection: text NOT NULL
|
||||
id: uuid NOT NULL
|
||||
data: jsonb NOT NULL
|
||||
created_at: timestamp with time zone NOT NULL default=now()
|
||||
updated_at: timestamp with time zone NOT NULL default=now()
|
||||
|
||||
table: group_kv_entries
|
||||
group_id: uuid NOT NULL
|
||||
collection: text NOT NULL
|
||||
@@ -509,6 +517,11 @@ indexes on group_collections:
|
||||
group_collections_group_uidx: public.group_collections USING btree (group_id, lower(name), kind) WHERE (group_id IS NOT NULL)
|
||||
group_collections_pkey: public.group_collections USING btree (id)
|
||||
|
||||
indexes on group_docs:
|
||||
group_docs_pkey: public.group_docs USING btree (group_id, collection, id)
|
||||
idx_group_docs_data_gin: public.group_docs USING gin (data jsonb_path_ops)
|
||||
idx_group_docs_group_collection: public.group_docs USING btree (group_id, collection)
|
||||
|
||||
indexes on group_kv_entries:
|
||||
group_kv_entries_pkey: public.group_kv_entries USING btree (group_id, collection, key)
|
||||
idx_group_kv_entries_group_collection: public.group_kv_entries USING btree (group_id, collection)
|
||||
@@ -714,12 +727,16 @@ constraints on files_trigger_details:
|
||||
[PRIMARY KEY] files_trigger_details_pkey: PRIMARY KEY (trigger_id)
|
||||
|
||||
constraints on group_collections:
|
||||
[CHECK] group_collections_kind_check: CHECK ((kind = 'kv'::text))
|
||||
[CHECK] group_collections_kind_check: CHECK ((kind = ANY (ARRAY['kv'::text, 'docs'::text])))
|
||||
[CHECK] group_collections_owner_exactly_one: CHECK (((group_id IS NULL) <> (app_id IS NULL)))
|
||||
[FOREIGN KEY] group_collections_app_id_fkey: FOREIGN KEY (app_id) REFERENCES apps(id) ON DELETE CASCADE
|
||||
[FOREIGN KEY] group_collections_group_id_fkey: FOREIGN KEY (group_id) REFERENCES groups(id) ON DELETE CASCADE
|
||||
[PRIMARY KEY] group_collections_pkey: PRIMARY KEY (id)
|
||||
|
||||
constraints on group_docs:
|
||||
[FOREIGN KEY] group_docs_group_id_fkey: FOREIGN KEY (group_id) REFERENCES groups(id) ON DELETE CASCADE
|
||||
[PRIMARY KEY] group_docs_pkey: PRIMARY KEY (group_id, collection, id)
|
||||
|
||||
constraints on group_kv_entries:
|
||||
[FOREIGN KEY] group_kv_entries_group_id_fkey: FOREIGN KEY (group_id) REFERENCES groups(id) ON DELETE CASCADE
|
||||
[PRIMARY KEY] group_kv_entries_pkey: PRIMARY KEY (group_id, collection, key)
|
||||
@@ -863,3 +880,4 @@ constraints on vars:
|
||||
0051: extension points
|
||||
0052: group collections
|
||||
0053: group kv entries
|
||||
0054: group docs
|
||||
|
||||
Reference in New Issue
Block a user