-- IHF Phase 6 — Cross-Framework UI Adaptation Layer -- Adds: envelope_emission_contracts, interaction_reporting_contracts, -- widget_adapter_specs, widgets.adapter_spec_id, hubs.api_key -- Seeds: v1.0 contracts CREATE TABLE envelope_emission_contracts ( id UUID DEFAULT uuid_generate_v4() PRIMARY KEY NOT NULL, contract_version TEXT NOT NULL UNIQUE, required_attributes JSONB NOT NULL, optional_attributes JSONB NOT NULL DEFAULT '[]', validation_rules JSONB NOT NULL DEFAULT '{}', description TEXT, status TEXT NOT NULL DEFAULT 'active', created_at TIMESTAMP WITH TIME ZONE DEFAULT now() NOT NULL ); CREATE INDEX envelope_emission_contracts_status_idx ON envelope_emission_contracts (status); CREATE TABLE interaction_reporting_contracts ( id UUID DEFAULT uuid_generate_v4() PRIMARY KEY NOT NULL, contract_version TEXT NOT NULL UNIQUE, endpoint_path TEXT NOT NULL, accepted_event_types JSONB NOT NULL, required_fields JSONB NOT NULL, auth_scheme TEXT NOT NULL DEFAULT 'bearer', description TEXT, status TEXT NOT NULL DEFAULT 'active', created_at TIMESTAMP WITH TIME ZONE DEFAULT now() NOT NULL ); CREATE INDEX interaction_reporting_contracts_status_idx ON interaction_reporting_contracts (status); CREATE TABLE widget_adapter_specs ( id UUID DEFAULT uuid_generate_v4() PRIMARY KEY NOT NULL, name TEXT NOT NULL UNIQUE, framework TEXT NOT NULL, version TEXT NOT NULL, envelope_contract_id UUID REFERENCES envelope_emission_contracts(id), reporting_contract_id UUID REFERENCES interaction_reporting_contracts(id), status TEXT NOT NULL DEFAULT 'draft', notes TEXT, created_at TIMESTAMP WITH TIME ZONE DEFAULT now() NOT NULL, updated_at TIMESTAMP WITH TIME ZONE DEFAULT now() NOT NULL ); CREATE INDEX widget_adapter_specs_framework_idx ON widget_adapter_specs (framework); CREATE INDEX widget_adapter_specs_status_idx ON widget_adapter_specs (status); ALTER TABLE widgets ADD COLUMN adapter_spec_id UUID REFERENCES widget_adapter_specs(id); CREATE INDEX widgets_adapter_spec_id_idx ON widgets (adapter_spec_id); ALTER TABLE hubs ADD COLUMN api_key TEXT; -- Seed: v1.0 EnvelopeEmissionContract INSERT INTO envelope_emission_contracts ( contract_version, required_attributes, optional_attributes, validation_rules, description, status ) VALUES ( '1.0', '["data-widget-id", "data-view-context", "data-hub-id"]', '["data-policy-scope", "data-widget-version"]', '{"data-widget-id": "uuid", "data-hub-id": "uuid"}', 'Canonical IHF widget envelope contract v1.0. Requires widget identity, view context, and hub attribution on every rendered widget element.', 'active' ); -- Seed: v1.0 InteractionReportingContract INSERT INTO interaction_reporting_contracts ( contract_version, endpoint_path, accepted_event_types, required_fields, auth_scheme, description, status ) VALUES ( '1.0', '/api/v1/interaction-events', '["clicked", "viewed", "submitted", "dismissed", "errored"]', '["widget_id", "hub_id", "event_type", "occurred_at"]', 'bearer', 'Canonical IHF interaction reporting contract v1.0. External adapters POST events to this endpoint using a hub-scoped bearer token.', 'active' );