-- IHF Phase 10 — Hub Registry and Widget Marketplace -- IHUB-WP-0011-T01: widget_patterns, widget_pattern_versions, pattern_adoptions, -- governance_templates, governance_template_clones -- -- GAAF constraints: -- widget_patterns.widget_type FKs to widget_type_registry(name) -- governance_templates.categories is JSONB; validated at controller layer -- No HubRegistry table — hub registry is a view over existing tables -- widget_patterns: reusable widget definitions tied to registered types CREATE TABLE widget_patterns ( id UUID DEFAULT uuid_generate_v4() PRIMARY KEY NOT NULL, hub_id UUID NOT NULL REFERENCES hubs(id), name TEXT NOT NULL, description TEXT, widget_type TEXT NOT NULL REFERENCES widget_type_registry(name), is_cross_hub BOOLEAN NOT NULL DEFAULT FALSE, is_published BOOLEAN NOT NULL DEFAULT FALSE, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() NOT NULL, updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() NOT NULL ); CREATE INDEX widget_patterns_hub_id_idx ON widget_patterns (hub_id); CREATE INDEX widget_patterns_widget_type_idx ON widget_patterns (widget_type); CREATE INDEX widget_patterns_is_published_idx ON widget_patterns (is_published); -- widget_pattern_versions: explicit version history CREATE TABLE widget_pattern_versions ( id UUID DEFAULT uuid_generate_v4() PRIMARY KEY NOT NULL, widget_pattern_id UUID NOT NULL REFERENCES widget_patterns(id) ON DELETE CASCADE, version_number INTEGER NOT NULL, definition JSONB NOT NULL, changelog TEXT, published_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() NOT NULL, UNIQUE (widget_pattern_id, version_number) ); CREATE INDEX widget_pattern_versions_pattern_idx ON widget_pattern_versions (widget_pattern_id); -- pattern_adoptions: which hubs have adopted which patterns CREATE TABLE pattern_adoptions ( id UUID DEFAULT uuid_generate_v4() PRIMARY KEY NOT NULL, widget_pattern_id UUID NOT NULL REFERENCES widget_patterns(id), adopting_hub_id UUID NOT NULL REFERENCES hubs(id), pinned_version_id UUID REFERENCES widget_pattern_versions(id), is_version_pinned BOOLEAN NOT NULL DEFAULT FALSE, is_anonymous BOOLEAN NOT NULL DEFAULT FALSE, adopted_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() NOT NULL, UNIQUE (widget_pattern_id, adopting_hub_id) ); CREATE INDEX pattern_adoptions_pattern_idx ON pattern_adoptions (widget_pattern_id); CREATE INDEX pattern_adoptions_hub_idx ON pattern_adoptions (adopting_hub_id); -- governance_templates: requirement distillation and decision templates -- categories: JSONB array of annotation_category_registry names -- validated at the controller layer (array FK not expressible in SQL) CREATE TABLE governance_templates ( id UUID DEFAULT uuid_generate_v4() PRIMARY KEY NOT NULL, hub_id UUID NOT NULL REFERENCES hubs(id), name TEXT NOT NULL, description TEXT, categories JSONB NOT NULL DEFAULT '[]', template_body JSONB NOT NULL, is_published BOOLEAN NOT NULL DEFAULT FALSE, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() NOT NULL, updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() NOT NULL ); CREATE INDEX governance_templates_hub_id_idx ON governance_templates (hub_id); CREATE INDEX governance_templates_is_published_idx ON governance_templates (is_published); -- governance_template_clones: adoption record for governance templates CREATE TABLE governance_template_clones ( id UUID DEFAULT uuid_generate_v4() PRIMARY KEY NOT NULL, governance_template_id UUID NOT NULL REFERENCES governance_templates(id), cloning_hub_id UUID NOT NULL REFERENCES hubs(id), cloned_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() NOT NULL, UNIQUE (governance_template_id, cloning_hub_id) ); CREATE INDEX governance_template_clones_template_idx ON governance_template_clones (governance_template_id); CREATE INDEX governance_template_clones_hub_idx ON governance_template_clones (cloning_hub_id);