20260729_270_governance_responsibilities.py 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. """Add versioned and audited governance responsibility matrices."""
  2. from alembic import op
  3. revision = "20260729_270"
  4. down_revision = "20260724_260"
  5. branch_labels = None
  6. depends_on = None
  7. def upgrade() -> None:
  8. op.execute(
  9. """
  10. CREATE TABLE IF NOT EXISTS public.governance_responsibility_scopes (
  11. id UUID PRIMARY KEY,
  12. resource_type VARCHAR(40) NOT NULL
  13. CHECK (
  14. resource_type IN (
  15. 'business_domain','device_asset','device_ontology',
  16. 'device_mapping','fault_classification','quality_issue'
  17. )
  18. ),
  19. resource_uid VARCHAR(120) NOT NULL,
  20. revision INTEGER NOT NULL DEFAULT 0 CHECK (revision >= 0),
  21. updated_by UUID REFERENCES public.users(id) ON DELETE SET NULL,
  22. created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
  23. updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
  24. UNIQUE (resource_type, resource_uid)
  25. );
  26. CREATE TABLE IF NOT EXISTS public.governance_responsibility_assignments (
  27. id UUID PRIMARY KEY,
  28. scope_id UUID NOT NULL
  29. REFERENCES public.governance_responsibility_scopes(id)
  30. ON DELETE CASCADE,
  31. user_id UUID NOT NULL REFERENCES public.users(id) ON DELETE RESTRICT,
  32. responsibility_role VARCHAR(32) NOT NULL
  33. CHECK (
  34. responsibility_role IN (
  35. 'domain_owner','data_steward',
  36. 'data_architect','asset_manager'
  37. )
  38. ),
  39. raci_role VARCHAR(16) NOT NULL
  40. CHECK (
  41. raci_role IN (
  42. 'responsible','accountable','consulted','informed'
  43. )
  44. ),
  45. assigned_by UUID REFERENCES public.users(id) ON DELETE SET NULL,
  46. assigned_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
  47. UNIQUE (scope_id, user_id, responsibility_role, raci_role)
  48. );
  49. CREATE INDEX IF NOT EXISTS idx_governance_responsibility_user
  50. ON public.governance_responsibility_assignments(user_id);
  51. CREATE TABLE IF NOT EXISTS public.governance_responsibility_audit_events (
  52. id BIGSERIAL PRIMARY KEY,
  53. scope_id UUID REFERENCES public.governance_responsibility_scopes(id)
  54. ON DELETE SET NULL,
  55. resource_type VARCHAR(40) NOT NULL,
  56. resource_uid VARCHAR(120) NOT NULL,
  57. actor_uid UUID REFERENCES public.users(id) ON DELETE SET NULL,
  58. action VARCHAR(40) NOT NULL,
  59. before_state JSONB NOT NULL,
  60. after_state JSONB NOT NULL,
  61. created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
  62. );
  63. CREATE INDEX IF NOT EXISTS idx_governance_responsibility_audit_scope
  64. ON public.governance_responsibility_audit_events(
  65. resource_type, resource_uid, created_at DESC
  66. );
  67. """
  68. )
  69. def downgrade() -> None:
  70. # Responsibility history is retained during application rollback.
  71. pass