feat(shared-collections): admit 'topic' and 'queue' collection kinds (D2/D3)
Widen the group_collections kind allow-list (migration 0064) + the manifest CollectionKind enum + apply_service COLLECTION_KINDS to include 'topic' (D2, storeless publish namespace) and 'queue' (D3, group-keyed durable queue — store lands in 0065). Foundation shared by both milestones; routes through the existing owner-generic reconcile + resolve_owning_group path. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,17 @@
|
|||||||
|
-- §11.6 (cont., v1.2 Hierarchies): admit 'topic' and 'queue' as shared-
|
||||||
|
-- collection kinds.
|
||||||
|
--
|
||||||
|
-- D2 (shared topics) + D3 (shared queues) extend the group shared-collection
|
||||||
|
-- machinery from data stores (kv/docs/files) to the two event/messaging kinds.
|
||||||
|
-- A shared TOPIC is storeless — it is a group-scoped publish NAMESPACE watched
|
||||||
|
-- by `shared = true` group pubsub triggers (no per-kind storage table). A shared
|
||||||
|
-- QUEUE gets its group-keyed message store in 0065 (D3). This migration only
|
||||||
|
-- widens the marker allow-list; both kinds route through the same owner-generic
|
||||||
|
-- reconcile + `resolve_owning_group` path as the data kinds.
|
||||||
|
|
||||||
|
-- Widen the marker kind allow-list (auto-named `group_collections_kind_check`,
|
||||||
|
-- an inline column CHECK), matching 0054/0055.
|
||||||
|
ALTER TABLE group_collections
|
||||||
|
DROP CONSTRAINT group_collections_kind_check,
|
||||||
|
ADD CONSTRAINT group_collections_kind_check
|
||||||
|
CHECK (kind IN ('kv', 'docs', 'files', 'topic', 'queue'));
|
||||||
@@ -119,7 +119,7 @@ fn default_collection_kind() -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The shared-collection kinds the apply engine accepts.
|
/// The shared-collection kinds the apply engine accepts.
|
||||||
const COLLECTION_KINDS: &[&str] = &["kv", "docs", "files"];
|
const COLLECTION_KINDS: &[&str] = &["kv", "docs", "files", "topic", "queue"];
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
pub struct BundleScript {
|
pub struct BundleScript {
|
||||||
|
|||||||
@@ -769,7 +769,7 @@ constraints on files_trigger_details:
|
|||||||
[PRIMARY KEY] files_trigger_details_pkey: PRIMARY KEY (trigger_id)
|
[PRIMARY KEY] files_trigger_details_pkey: PRIMARY KEY (trigger_id)
|
||||||
|
|
||||||
constraints on group_collections:
|
constraints on group_collections:
|
||||||
[CHECK] group_collections_kind_check: CHECK ((kind = ANY (ARRAY['kv'::text, 'docs'::text, 'files'::text])))
|
[CHECK] group_collections_kind_check: CHECK ((kind = ANY (ARRAY['kv'::text, 'docs'::text, 'files'::text, 'topic'::text, 'queue'::text])))
|
||||||
[CHECK] group_collections_owner_exactly_one: CHECK (((group_id IS NULL) <> (app_id IS NULL)))
|
[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_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
|
[FOREIGN KEY] group_collections_group_id_fkey: FOREIGN KEY (group_id) REFERENCES groups(id) ON DELETE CASCADE
|
||||||
@@ -948,3 +948,4 @@ constraints on vars:
|
|||||||
0061: shared triggers
|
0061: shared triggers
|
||||||
0062: materialized triggers
|
0062: materialized triggers
|
||||||
0063: materialized unique
|
0063: materialized unique
|
||||||
|
0064: shared topic queue kinds
|
||||||
|
|||||||
@@ -270,6 +270,12 @@ pub enum CollectionKind {
|
|||||||
Kv,
|
Kv,
|
||||||
Docs,
|
Docs,
|
||||||
Files,
|
Files,
|
||||||
|
/// §11.6 D2: a storeless group-scoped publish namespace, watched by
|
||||||
|
/// `shared = true` group pubsub triggers.
|
||||||
|
Topic,
|
||||||
|
/// §11.6 D3: a group-keyed durable queue with competing per-descendant
|
||||||
|
/// consumers.
|
||||||
|
Queue,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CollectionKind {
|
impl CollectionKind {
|
||||||
@@ -279,6 +285,8 @@ impl CollectionKind {
|
|||||||
Self::Kv => "kv",
|
Self::Kv => "kv",
|
||||||
Self::Docs => "docs",
|
Self::Docs => "docs",
|
||||||
Self::Files => "files",
|
Self::Files => "files",
|
||||||
|
Self::Topic => "topic",
|
||||||
|
Self::Queue => "queue",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user