feat: implement governed reporting vertical
This commit is contained in:
@@ -0,0 +1 @@
|
||||
"""Reporting Alembic revisions."""
|
||||
@@ -0,0 +1 @@
|
||||
"""Reporting migration versions."""
|
||||
+477
@@ -0,0 +1,477 @@
|
||||
"""v0.1.14 governed Reporting baseline.
|
||||
|
||||
Revision ID: e5b2c9d4f7a1
|
||||
Revises: None
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
revision = "e5b2c9d4f7a1"
|
||||
down_revision = None
|
||||
branch_labels = None
|
||||
depends_on = "4f2a9c8e7b6d"
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
op.create_table(
|
||||
"reporting_definition_identities",
|
||||
sa.Column("id", sa.String(length=36), nullable=False),
|
||||
sa.Column("tenant_id", sa.String(length=36), nullable=False),
|
||||
sa.Column("definition_kind", sa.String(length=40), nullable=False),
|
||||
sa.Column("definition_id", sa.String(length=255), nullable=False),
|
||||
sa.Column("definition_key", sa.String(length=120), nullable=False),
|
||||
sa.Column("created_by", sa.String(length=255), nullable=True),
|
||||
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False),
|
||||
sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False),
|
||||
sa.PrimaryKeyConstraint("id", name=op.f("pk_reporting_definition_identities")),
|
||||
sa.UniqueConstraint(
|
||||
"tenant_id",
|
||||
"definition_kind",
|
||||
"definition_id",
|
||||
name="uq_reporting_definition_identity",
|
||||
),
|
||||
sa.UniqueConstraint(
|
||||
"tenant_id",
|
||||
"definition_kind",
|
||||
"definition_key",
|
||||
name="uq_reporting_definition_key",
|
||||
),
|
||||
)
|
||||
_indexes(
|
||||
"reporting_definition_identities",
|
||||
"tenant_id",
|
||||
"definition_kind",
|
||||
"definition_id",
|
||||
"definition_key",
|
||||
"created_by",
|
||||
)
|
||||
op.create_index(
|
||||
"ix_reporting_definition_catalog",
|
||||
"reporting_definition_identities",
|
||||
["tenant_id", "definition_kind", "definition_key"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
op.create_table(
|
||||
"reporting_definition_revisions",
|
||||
sa.Column("id", sa.String(length=36), nullable=False),
|
||||
sa.Column("tenant_id", sa.String(length=36), nullable=False),
|
||||
sa.Column("identity_id", sa.String(length=36), nullable=False),
|
||||
sa.Column("definition_kind", sa.String(length=40), nullable=False),
|
||||
sa.Column("definition_id", sa.String(length=255), nullable=False),
|
||||
sa.Column("definition_key", sa.String(length=120), nullable=False),
|
||||
sa.Column("revision", sa.Integer(), nullable=False),
|
||||
sa.Column("previous_revision_id", sa.String(length=36), nullable=True),
|
||||
sa.Column("parent_kind", sa.String(length=40), nullable=True),
|
||||
sa.Column("parent_id", sa.String(length=255), nullable=True),
|
||||
sa.Column("parent_revision", sa.Integer(), nullable=True),
|
||||
sa.Column("name", sa.String(length=500), nullable=False),
|
||||
sa.Column("description", sa.Text(), nullable=True),
|
||||
sa.Column("status", sa.String(length=30), nullable=False),
|
||||
sa.Column("visibility", sa.String(length=30), nullable=False),
|
||||
sa.Column("content_hash", sa.String(length=64), nullable=False),
|
||||
sa.Column("change_reason", sa.String(length=1000), nullable=False),
|
||||
sa.Column("idempotency_key", sa.String(length=255), nullable=False),
|
||||
sa.Column("request_sha256", sa.String(length=64), nullable=False),
|
||||
sa.Column("event_id", sa.String(length=36), nullable=False),
|
||||
sa.Column("recorded_at", sa.DateTime(timezone=True), nullable=False),
|
||||
sa.Column("superseded_at", sa.DateTime(timezone=True), nullable=True),
|
||||
sa.Column("payload", sa.JSON(), nullable=False),
|
||||
sa.Column("changed_by", sa.String(length=255), nullable=True),
|
||||
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False),
|
||||
sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False),
|
||||
sa.ForeignKeyConstraint(
|
||||
["identity_id"],
|
||||
["reporting_definition_identities.id"],
|
||||
name=op.f(
|
||||
"fk_reporting_definition_revisions_identity_id_reporting_definition_identities"
|
||||
),
|
||||
ondelete="RESTRICT",
|
||||
),
|
||||
sa.ForeignKeyConstraint(
|
||||
["previous_revision_id"],
|
||||
["reporting_definition_revisions.id"],
|
||||
name=op.f(
|
||||
"fk_reporting_definition_revisions_previous_revision_id_reporting_definition_revisions"
|
||||
),
|
||||
ondelete="RESTRICT",
|
||||
),
|
||||
sa.PrimaryKeyConstraint("id", name=op.f("pk_reporting_definition_revisions")),
|
||||
sa.UniqueConstraint(
|
||||
"tenant_id",
|
||||
"definition_kind",
|
||||
"definition_id",
|
||||
"revision",
|
||||
name="uq_reporting_definition_revision",
|
||||
),
|
||||
sa.UniqueConstraint(
|
||||
"tenant_id",
|
||||
"idempotency_key",
|
||||
name="uq_reporting_definition_idempotency",
|
||||
),
|
||||
sa.UniqueConstraint(
|
||||
"tenant_id",
|
||||
"event_id",
|
||||
name="uq_reporting_definition_event",
|
||||
),
|
||||
)
|
||||
_indexes(
|
||||
"reporting_definition_revisions",
|
||||
"tenant_id",
|
||||
"identity_id",
|
||||
"definition_kind",
|
||||
"definition_id",
|
||||
"definition_key",
|
||||
"previous_revision_id",
|
||||
"parent_kind",
|
||||
"parent_id",
|
||||
"status",
|
||||
"visibility",
|
||||
"content_hash",
|
||||
"event_id",
|
||||
"recorded_at",
|
||||
"superseded_at",
|
||||
"changed_by",
|
||||
)
|
||||
op.create_index(
|
||||
"ix_reporting_definition_current",
|
||||
"reporting_definition_revisions",
|
||||
["tenant_id", "definition_kind", "definition_id", "superseded_at"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_reporting_definition_parent",
|
||||
"reporting_definition_revisions",
|
||||
["tenant_id", "parent_kind", "parent_id", "parent_revision"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_reporting_definition_list",
|
||||
"reporting_definition_revisions",
|
||||
["tenant_id", "definition_kind", "status", "recorded_at"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
op.create_table(
|
||||
"reporting_definition_grants",
|
||||
sa.Column("id", sa.String(length=36), nullable=False),
|
||||
sa.Column("tenant_id", sa.String(length=36), nullable=False),
|
||||
sa.Column("definition_kind", sa.String(length=40), nullable=False),
|
||||
sa.Column("definition_id", sa.String(length=255), nullable=False),
|
||||
sa.Column("subject_kind", sa.String(length=40), nullable=False),
|
||||
sa.Column("subject_id", sa.String(length=255), nullable=False),
|
||||
sa.Column("permissions", sa.JSON(), nullable=False),
|
||||
sa.Column("active", sa.Boolean(), nullable=False),
|
||||
sa.Column("source_revision", sa.Integer(), nullable=False),
|
||||
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False),
|
||||
sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False),
|
||||
sa.PrimaryKeyConstraint("id", name=op.f("pk_reporting_definition_grants")),
|
||||
sa.UniqueConstraint(
|
||||
"tenant_id",
|
||||
"definition_kind",
|
||||
"definition_id",
|
||||
"subject_kind",
|
||||
"subject_id",
|
||||
name="uq_reporting_definition_grant",
|
||||
),
|
||||
)
|
||||
_indexes(
|
||||
"reporting_definition_grants",
|
||||
"tenant_id",
|
||||
"definition_kind",
|
||||
"definition_id",
|
||||
"subject_kind",
|
||||
"subject_id",
|
||||
"active",
|
||||
)
|
||||
op.create_index(
|
||||
"ix_reporting_definition_grant_subject",
|
||||
"reporting_definition_grants",
|
||||
["tenant_id", "subject_kind", "subject_id", "active"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_reporting_definition_grant_object",
|
||||
"reporting_definition_grants",
|
||||
["tenant_id", "definition_kind", "definition_id", "active"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
op.create_table(
|
||||
"reporting_executions",
|
||||
sa.Column("id", sa.String(length=36), nullable=False),
|
||||
sa.Column("tenant_id", sa.String(length=36), nullable=False),
|
||||
sa.Column("execution_id", sa.String(length=36), nullable=False),
|
||||
sa.Column("report_id", sa.String(length=255), nullable=False),
|
||||
sa.Column("report_revision", sa.Integer(), nullable=False),
|
||||
sa.Column("semantic_model_id", sa.String(length=255), nullable=False),
|
||||
sa.Column("semantic_model_revision", sa.Integer(), nullable=False),
|
||||
sa.Column("dataset_id", sa.String(length=255), nullable=False),
|
||||
sa.Column("dataset_revision", sa.Integer(), nullable=False),
|
||||
sa.Column("status", sa.String(length=30), nullable=False),
|
||||
sa.Column("idempotency_key", sa.String(length=255), nullable=False),
|
||||
sa.Column("request_sha256", sa.String(length=64), nullable=False),
|
||||
sa.Column("parameters", sa.JSON(), nullable=False),
|
||||
sa.Column("query", sa.JSON(), nullable=False),
|
||||
sa.Column("source_fingerprints", sa.JSON(), nullable=False),
|
||||
sa.Column("definition_hashes", sa.JSON(), nullable=False),
|
||||
sa.Column("output_hash", sa.String(length=64), nullable=True),
|
||||
sa.Column("executor_version", sa.String(length=255), nullable=True),
|
||||
sa.Column("result_schema", sa.JSON(), nullable=False),
|
||||
sa.Column("result_rows", sa.JSON(), nullable=False),
|
||||
sa.Column("total_rows", sa.Integer(), nullable=False),
|
||||
sa.Column("truncated", sa.Boolean(), nullable=False),
|
||||
sa.Column("diagnostics", sa.JSON(), nullable=False),
|
||||
sa.Column("provenance", sa.JSON(), nullable=False),
|
||||
sa.Column("started_at", sa.DateTime(timezone=True), nullable=False),
|
||||
sa.Column("finished_at", sa.DateTime(timezone=True), nullable=True),
|
||||
sa.Column("actor_id", sa.String(length=255), nullable=True),
|
||||
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False),
|
||||
sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False),
|
||||
sa.PrimaryKeyConstraint("id", name=op.f("pk_reporting_executions")),
|
||||
sa.UniqueConstraint("tenant_id", "execution_id", name="uq_reporting_execution"),
|
||||
sa.UniqueConstraint(
|
||||
"tenant_id",
|
||||
"idempotency_key",
|
||||
name="uq_reporting_execution_idempotency",
|
||||
),
|
||||
)
|
||||
_indexes(
|
||||
"reporting_executions",
|
||||
"tenant_id",
|
||||
"execution_id",
|
||||
"report_id",
|
||||
"semantic_model_id",
|
||||
"dataset_id",
|
||||
"status",
|
||||
"output_hash",
|
||||
"started_at",
|
||||
"finished_at",
|
||||
"actor_id",
|
||||
)
|
||||
op.create_index(
|
||||
"ix_reporting_execution_history",
|
||||
"reporting_executions",
|
||||
["tenant_id", "report_id", "started_at"],
|
||||
unique=False,
|
||||
)
|
||||
op.create_index(
|
||||
"ix_reporting_execution_status",
|
||||
"reporting_executions",
|
||||
["tenant_id", "status", "started_at"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
op.create_table(
|
||||
"reporting_saved_views",
|
||||
sa.Column("id", sa.String(length=36), nullable=False),
|
||||
sa.Column("tenant_id", sa.String(length=36), nullable=False),
|
||||
sa.Column("view_id", sa.String(length=36), nullable=False),
|
||||
sa.Column("report_id", sa.String(length=255), nullable=False),
|
||||
sa.Column("report_revision", sa.Integer(), nullable=False),
|
||||
sa.Column("owner_kind", sa.String(length=40), nullable=False),
|
||||
sa.Column("owner_id", sa.String(length=255), nullable=False),
|
||||
sa.Column("name", sa.String(length=500), nullable=False),
|
||||
sa.Column("revision", sa.Integer(), nullable=False),
|
||||
sa.Column("state", sa.JSON(), nullable=False),
|
||||
sa.Column("shared", sa.Boolean(), nullable=False),
|
||||
sa.Column("access", sa.JSON(), nullable=False),
|
||||
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False),
|
||||
sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False),
|
||||
sa.PrimaryKeyConstraint("id", name=op.f("pk_reporting_saved_views")),
|
||||
sa.UniqueConstraint("tenant_id", "view_id", name="uq_reporting_saved_view"),
|
||||
)
|
||||
_indexes(
|
||||
"reporting_saved_views",
|
||||
"tenant_id",
|
||||
"view_id",
|
||||
"report_id",
|
||||
"owner_kind",
|
||||
"owner_id",
|
||||
"shared",
|
||||
)
|
||||
op.create_index(
|
||||
"ix_reporting_saved_view_catalog",
|
||||
"reporting_saved_views",
|
||||
["tenant_id", "report_id", "owner_id", "shared"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
op.create_table(
|
||||
"reporting_schedules",
|
||||
sa.Column("id", sa.String(length=36), nullable=False),
|
||||
sa.Column("tenant_id", sa.String(length=36), nullable=False),
|
||||
sa.Column("schedule_id", sa.String(length=36), nullable=False),
|
||||
sa.Column("report_id", sa.String(length=255), nullable=False),
|
||||
sa.Column("report_revision", sa.Integer(), nullable=False),
|
||||
sa.Column("name", sa.String(length=500), nullable=False),
|
||||
sa.Column("revision", sa.Integer(), nullable=False),
|
||||
sa.Column("trigger_kind", sa.String(length=30), nullable=False),
|
||||
sa.Column("trigger_config", sa.JSON(), nullable=False),
|
||||
sa.Column("parameters", sa.JSON(), nullable=False),
|
||||
sa.Column("query", sa.JSON(), nullable=False),
|
||||
sa.Column("publication_target", sa.JSON(), nullable=False),
|
||||
sa.Column("enabled", sa.Boolean(), nullable=False),
|
||||
sa.Column("next_run_at", sa.DateTime(timezone=True), nullable=True),
|
||||
sa.Column("last_run_at", sa.DateTime(timezone=True), nullable=True),
|
||||
sa.Column("last_execution_id", sa.String(length=36), nullable=True),
|
||||
sa.Column("created_by", sa.String(length=255), nullable=True),
|
||||
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False),
|
||||
sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False),
|
||||
sa.PrimaryKeyConstraint("id", name=op.f("pk_reporting_schedules")),
|
||||
sa.UniqueConstraint("tenant_id", "schedule_id", name="uq_reporting_schedule"),
|
||||
)
|
||||
_indexes(
|
||||
"reporting_schedules",
|
||||
"tenant_id",
|
||||
"schedule_id",
|
||||
"report_id",
|
||||
"enabled",
|
||||
"next_run_at",
|
||||
)
|
||||
op.create_index(
|
||||
"ix_reporting_schedule_due",
|
||||
"reporting_schedules",
|
||||
["enabled", "next_run_at", "tenant_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
op.create_table(
|
||||
"reporting_publications",
|
||||
sa.Column("id", sa.String(length=36), nullable=False),
|
||||
sa.Column("tenant_id", sa.String(length=36), nullable=False),
|
||||
sa.Column("publication_id", sa.String(length=36), nullable=False),
|
||||
sa.Column("execution_id", sa.String(length=36), nullable=False),
|
||||
sa.Column("target_capability", sa.String(length=255), nullable=False),
|
||||
sa.Column("target_ref", sa.String(length=1000), nullable=True),
|
||||
sa.Column("format", sa.String(length=30), nullable=False),
|
||||
sa.Column("status", sa.String(length=30), nullable=False),
|
||||
sa.Column("idempotency_key", sa.String(length=255), nullable=False),
|
||||
sa.Column("evidence", sa.JSON(), nullable=False),
|
||||
sa.Column("error", sa.Text(), nullable=True),
|
||||
sa.Column("completed_at", sa.DateTime(timezone=True), nullable=True),
|
||||
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False),
|
||||
sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False),
|
||||
sa.PrimaryKeyConstraint("id", name=op.f("pk_reporting_publications")),
|
||||
sa.UniqueConstraint(
|
||||
"tenant_id", "publication_id", name="uq_reporting_publication"
|
||||
),
|
||||
sa.UniqueConstraint(
|
||||
"tenant_id",
|
||||
"idempotency_key",
|
||||
name="uq_reporting_publication_idempotency",
|
||||
),
|
||||
)
|
||||
_indexes(
|
||||
"reporting_publications",
|
||||
"tenant_id",
|
||||
"publication_id",
|
||||
"execution_id",
|
||||
"status",
|
||||
)
|
||||
op.create_index(
|
||||
"ix_reporting_publication_history",
|
||||
"reporting_publications",
|
||||
["tenant_id", "execution_id", "created_at"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
op.create_table(
|
||||
"reporting_quality_results",
|
||||
sa.Column("id", sa.String(length=36), nullable=False),
|
||||
sa.Column("tenant_id", sa.String(length=36), nullable=False),
|
||||
sa.Column("result_id", sa.String(length=36), nullable=False),
|
||||
sa.Column("quality_plan_id", sa.String(length=255), nullable=False),
|
||||
sa.Column("quality_plan_revision", sa.Integer(), nullable=False),
|
||||
sa.Column("dataset_id", sa.String(length=255), nullable=False),
|
||||
sa.Column("dataset_revision", sa.Integer(), nullable=False),
|
||||
sa.Column("status", sa.String(length=30), nullable=False),
|
||||
sa.Column("output_hash", sa.String(length=64), nullable=False),
|
||||
sa.Column("assertions", sa.JSON(), nullable=False),
|
||||
sa.Column("source_fingerprints", sa.JSON(), nullable=False),
|
||||
sa.Column("evaluated_at", sa.DateTime(timezone=True), nullable=False),
|
||||
sa.Column("actor_id", sa.String(length=255), nullable=True),
|
||||
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False),
|
||||
sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False),
|
||||
sa.PrimaryKeyConstraint("id", name=op.f("pk_reporting_quality_results")),
|
||||
sa.UniqueConstraint(
|
||||
"tenant_id", "result_id", name="uq_reporting_quality_result"
|
||||
),
|
||||
)
|
||||
_indexes(
|
||||
"reporting_quality_results",
|
||||
"tenant_id",
|
||||
"result_id",
|
||||
"quality_plan_id",
|
||||
"dataset_id",
|
||||
"status",
|
||||
"output_hash",
|
||||
"evaluated_at",
|
||||
)
|
||||
op.create_index(
|
||||
"ix_reporting_quality_history",
|
||||
"reporting_quality_results",
|
||||
["tenant_id", "quality_plan_id", "evaluated_at"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
op.create_table(
|
||||
"reporting_import_assessments",
|
||||
sa.Column("id", sa.String(length=36), nullable=False),
|
||||
sa.Column("tenant_id", sa.String(length=36), nullable=False),
|
||||
sa.Column("assessment_id", sa.String(length=36), nullable=False),
|
||||
sa.Column("source_system", sa.String(length=255), nullable=False),
|
||||
sa.Column("source_id", sa.String(length=500), nullable=False),
|
||||
sa.Column("source_fingerprint", sa.String(length=64), nullable=False),
|
||||
sa.Column("mapping_report", sa.JSON(), nullable=False),
|
||||
sa.Column("status", sa.String(length=30), nullable=False),
|
||||
sa.Column("accepted_approximations", sa.JSON(), nullable=False),
|
||||
sa.Column("assessed_by", sa.String(length=255), nullable=True),
|
||||
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False),
|
||||
sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False),
|
||||
sa.PrimaryKeyConstraint("id", name=op.f("pk_reporting_import_assessments")),
|
||||
sa.UniqueConstraint(
|
||||
"tenant_id",
|
||||
"assessment_id",
|
||||
name="uq_reporting_import_assessment",
|
||||
),
|
||||
)
|
||||
_indexes(
|
||||
"reporting_import_assessments",
|
||||
"tenant_id",
|
||||
"assessment_id",
|
||||
"source_system",
|
||||
"status",
|
||||
)
|
||||
op.create_index(
|
||||
"ix_reporting_import_history",
|
||||
"reporting_import_assessments",
|
||||
["tenant_id", "source_system", "created_at"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_table("reporting_import_assessments")
|
||||
op.drop_table("reporting_quality_results")
|
||||
op.drop_table("reporting_publications")
|
||||
op.drop_table("reporting_schedules")
|
||||
op.drop_table("reporting_saved_views")
|
||||
op.drop_table("reporting_definition_grants")
|
||||
op.drop_table("reporting_executions")
|
||||
op.drop_table("reporting_definition_revisions")
|
||||
op.drop_table("reporting_definition_identities")
|
||||
|
||||
|
||||
def _indexes(table: str, *columns: str) -> None:
|
||||
for column in columns:
|
||||
op.create_index(
|
||||
op.f(f"ix_{table}_{column}"),
|
||||
table,
|
||||
[column],
|
||||
unique=False,
|
||||
)
|
||||
Reference in New Issue
Block a user