| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- """Add generic semantic governance, field mappings and publication audit."""
- from alembic import op
- revision = "20260731_390"
- down_revision = "20260730_380"
- branch_labels = None
- depends_on = None
- def upgrade() -> None:
- op.execute(
- """
- CREATE TABLE public.semantic_assets (
- uid UUID PRIMARY KEY,
- asset_kind VARCHAR(30) NOT NULL CHECK (
- asset_kind IN ('business_term','code_set','metric')
- ),
- code VARCHAR(120) NOT NULL,
- name VARCHAR(300) NOT NULL,
- owner_uid UUID NOT NULL REFERENCES public.users(id),
- business_domain_uid UUID NOT NULL,
- status VARCHAR(20) NOT NULL CHECK (
- status IN (
- 'draft','in_review','approved','published',
- 'superseded','retired'
- )
- ),
- current_version INTEGER NOT NULL CHECK (current_version > 0),
- created_by UUID NOT NULL REFERENCES public.users(id),
- created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
- updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
- UNIQUE (asset_kind, code)
- );
- CREATE TABLE public.semantic_asset_versions (
- uid UUID PRIMARY KEY,
- asset_uid UUID NOT NULL REFERENCES public.semantic_assets(uid),
- version INTEGER NOT NULL CHECK (version > 0),
- status VARCHAR(20) NOT NULL CHECK (
- status IN (
- 'draft','in_review','approved','published',
- 'superseded','retired'
- )
- ),
- content_hash CHAR(64) NOT NULL,
- definition JSONB NOT NULL,
- change_reason VARCHAR(1000) NOT NULL,
- created_by UUID NOT NULL REFERENCES public.users(id),
- rollback_from_version INTEGER,
- created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
- published_at TIMESTAMPTZ,
- UNIQUE (asset_uid, version),
- CHECK (jsonb_typeof(definition) = 'object'),
- CHECK (
- rollback_from_version IS NULL
- OR rollback_from_version > 0
- )
- );
- CREATE TABLE public.semantic_asset_reviews (
- uid UUID PRIMARY KEY,
- asset_uid UUID NOT NULL REFERENCES public.semantic_assets(uid),
- version INTEGER NOT NULL CHECK (version > 0),
- decision VARCHAR(20) NOT NULL
- CHECK (decision IN ('approve','reject')),
- reason VARCHAR(1000) NOT NULL,
- reviewer_uid UUID NOT NULL REFERENCES public.users(id),
- created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
- UNIQUE (asset_uid, version),
- FOREIGN KEY (asset_uid, version)
- REFERENCES public.semantic_asset_versions(asset_uid, version)
- );
- CREATE TABLE public.semantic_asset_links (
- uid UUID PRIMARY KEY,
- asset_uid UUID NOT NULL REFERENCES public.semantic_assets(uid),
- version INTEGER NOT NULL CHECK (version > 0),
- link_type VARCHAR(30) NOT NULL CHECK (
- link_type IN ('asset','data_element','standard','code_value')
- ),
- target_type VARCHAR(60) NOT NULL,
- target_uid VARCHAR(200) NOT NULL,
- target_key VARCHAR(200),
- metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
- created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
- FOREIGN KEY (asset_uid, version)
- REFERENCES public.semantic_asset_versions(asset_uid, version),
- UNIQUE (
- asset_uid, version, link_type, target_type,
- target_uid, target_key
- ),
- CHECK (jsonb_typeof(metadata) = 'object')
- );
- CREATE TABLE public.data_element_field_mappings (
- uid UUID PRIMARY KEY,
- asset_uid UUID NOT NULL
- REFERENCES public.active_metadata_assets(uid),
- field_name VARCHAR(200) NOT NULL,
- data_element_uid UUID NOT NULL REFERENCES public.data_elements(uid),
- data_element_version INTEGER NOT NULL CHECK (
- data_element_version > 0
- ),
- owner_uid UUID NOT NULL REFERENCES public.users(id),
- status VARCHAR(20) NOT NULL
- CHECK (status IN ('published','retired')),
- evidence JSONB NOT NULL DEFAULT '{}'::jsonb,
- created_by UUID NOT NULL REFERENCES public.users(id),
- created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
- updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
- UNIQUE (asset_uid, field_name, data_element_uid),
- CHECK (jsonb_typeof(evidence) = 'object')
- );
- CREATE TABLE public.semantic_publication_audits (
- uid UUID PRIMARY KEY,
- target_type VARCHAR(40) NOT NULL CHECK (
- target_type IN (
- 'semantic_asset','data_standard','field_mapping'
- )
- ),
- target_uid UUID NOT NULL,
- target_version INTEGER NOT NULL CHECK (target_version > 0),
- action VARCHAR(40) NOT NULL CHECK (
- action IN (
- 'created','revised','submitted','approved','rejected',
- 'published','rolled_back','mapped','retired'
- )
- ),
- actor_uid UUID NOT NULL REFERENCES public.users(id),
- detail JSONB NOT NULL DEFAULT '{}'::jsonb,
- created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
- CHECK (jsonb_typeof(detail) = 'object')
- );
- CREATE INDEX idx_semantic_assets_kind_status
- ON public.semantic_assets(asset_kind, status, updated_at DESC);
- CREATE INDEX idx_semantic_versions_asset
- ON public.semantic_asset_versions(asset_uid, version DESC);
- CREATE INDEX idx_semantic_links_target
- ON public.semantic_asset_links(target_type, target_uid, target_key);
- CREATE UNIQUE INDEX uq_published_physical_field_mapping
- ON public.data_element_field_mappings(asset_uid, field_name)
- WHERE status = 'published';
- CREATE INDEX idx_field_mappings_element
- ON public.data_element_field_mappings(
- data_element_uid, status, updated_at DESC
- );
- CREATE INDEX idx_semantic_audits_target
- ON public.semantic_publication_audits(
- target_type, target_uid, target_version
- );
- """
- )
- def downgrade() -> None:
- raise RuntimeError(
- "semantic governance history is append-only; "
- "downgrade requires an approved archival migration"
- )
|