Files
govoplan-templates/src/govoplan_templates/backend/migrations/versions/a3f7c9d2e1b4_templates_baseline.py
T

136 lines
7.8 KiB
Python

"""templates baseline
Revision ID: a3f7c9d2e1b4
Revises: None
Create Date: 2026-08-02 00:00:00.000000
"""
from __future__ import annotations
from alembic import op
import sqlalchemy as sa
revision = "a3f7c9d2e1b4"
down_revision = None
branch_labels = None
depends_on = "4f2a9c8e7b6d"
def upgrade() -> None:
op.create_table(
"template_definitions",
sa.Column("id", sa.String(length=36), nullable=False),
sa.Column("tenant_id", sa.String(length=36), nullable=False),
sa.Column("scope_type", sa.String(length=20), nullable=False),
sa.Column("scope_id", sa.String(length=36), nullable=True),
sa.Column("name", sa.String(length=300), nullable=False),
sa.Column("slug", sa.String(length=160), nullable=False),
sa.Column("description", sa.Text(), nullable=True),
sa.Column("template_type", sa.String(length=40), nullable=False),
sa.Column("status", sa.String(length=30), nullable=False),
sa.Column("current_revision_id", sa.String(length=36), nullable=False),
sa.Column("current_revision", sa.Integer(), nullable=False),
sa.Column("published_revision_id", sa.String(length=36), nullable=True),
sa.Column("resource_revision", sa.Integer(), nullable=False),
sa.Column("created_by_account_id", sa.String(length=36), nullable=True),
sa.Column("updated_by_account_id", sa.String(length=36), nullable=True),
sa.Column("deleted_at", sa.DateTime(timezone=True), nullable=True),
sa.Column("metadata", 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_template_definitions")),
)
for column in ("tenant_id", "scope_type", "scope_id", "template_type", "status", "published_revision_id", "created_by_account_id", "updated_by_account_id", "deleted_at"):
op.create_index(op.f(f"ix_template_definitions_{column}"), "template_definitions", [column])
op.create_index("ix_template_definitions_tenant_status", "template_definitions", ["tenant_id", "status", "updated_at"])
op.create_index(
"uq_template_definitions_active_tenant_slug",
"template_definitions",
["tenant_id", "slug"],
unique=True,
sqlite_where=sa.text("deleted_at IS NULL AND scope_id IS NULL"),
postgresql_where=sa.text("deleted_at IS NULL AND scope_id IS NULL"),
)
op.create_index(
"uq_template_definitions_active_named_scope_slug",
"template_definitions",
["tenant_id", "scope_type", "scope_id", "slug"],
unique=True,
sqlite_where=sa.text("deleted_at IS NULL AND scope_id IS NOT NULL"),
postgresql_where=sa.text("deleted_at IS NULL AND scope_id IS NOT NULL"),
)
op.create_table(
"template_revisions",
sa.Column("id", sa.String(length=36), nullable=False),
sa.Column("tenant_id", sa.String(length=36), nullable=False),
sa.Column("template_id", sa.String(length=36), nullable=False),
sa.Column("revision", sa.Integer(), nullable=False),
sa.Column("definition_hash", sa.String(length=64), nullable=False),
sa.Column("template_type", sa.String(length=40), nullable=False),
sa.Column("usages", sa.JSON(), nullable=False),
sa.Column("locale", sa.String(length=35), nullable=False),
sa.Column("required_fields", sa.JSON(), nullable=False),
sa.Column("output_profiles", sa.JSON(), nullable=False),
sa.Column("content_text", sa.Text(), nullable=True),
sa.Column("content_html", sa.Text(), nullable=True),
sa.Column("layout", sa.JSON(), nullable=False),
sa.Column("metadata", sa.JSON(), nullable=False),
sa.Column("created_by_account_id", sa.String(length=36), nullable=True),
sa.Column("published_at", sa.DateTime(timezone=True), nullable=True),
sa.Column("published_by_account_id", sa.String(length=36), nullable=True),
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False),
sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False),
sa.ForeignKeyConstraint(["template_id"], ["template_definitions.id"], name=op.f("fk_template_revisions_template_id_template_definitions"), ondelete="CASCADE"),
sa.PrimaryKeyConstraint("id", name=op.f("pk_template_revisions")),
sa.UniqueConstraint("template_id", "revision", name="uq_template_revision_number"),
)
for column in ("tenant_id", "template_id", "definition_hash", "template_type", "locale", "created_by_account_id", "published_at", "published_by_account_id"):
op.create_index(op.f(f"ix_template_revisions_{column}"), "template_revisions", [column])
op.create_index("ix_template_revisions_tenant_template", "template_revisions", ["tenant_id", "template_id"])
op.create_index("ix_template_revisions_hash", "template_revisions", ["tenant_id", "definition_hash"])
op.create_table(
"template_renders",
sa.Column("id", sa.String(length=36), nullable=False),
sa.Column("tenant_id", sa.String(length=36), nullable=False),
sa.Column("template_id", sa.String(length=36), nullable=False),
sa.Column("revision_id", sa.String(length=36), nullable=False),
sa.Column("revision_number", sa.Integer(), nullable=False),
sa.Column("mode", sa.String(length=20), nullable=False),
sa.Column("usage", sa.String(length=80), nullable=True),
sa.Column("output_format", sa.String(length=20), nullable=False),
sa.Column("content_type", sa.String(length=100), nullable=False),
sa.Column("filename", sa.String(length=500), nullable=False),
sa.Column("idempotency_key", sa.String(length=255), nullable=True),
sa.Column("template_hash", sa.String(length=64), nullable=False),
sa.Column("input_hash", sa.String(length=64), nullable=False),
sa.Column("renderer_version", sa.String(length=40), nullable=False),
sa.Column("output_sha256", sa.String(length=64), nullable=False),
sa.Column("output_size_bytes", sa.Integer(), nullable=False),
sa.Column("item_count", sa.Integer(), nullable=False),
sa.Column("page_count", sa.Integer(), nullable=False),
sa.Column("diagnostics", sa.JSON(), nullable=False),
sa.Column("input_snapshot", sa.JSON(), nullable=False),
sa.Column("artifact_ref", sa.JSON(), nullable=True),
sa.Column("payload", sa.LargeBinary(), nullable=True),
sa.Column("created_by_account_id", sa.String(length=36), nullable=True),
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False),
sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False),
sa.ForeignKeyConstraint(["template_id"], ["template_definitions.id"], name=op.f("fk_template_renders_template_id_template_definitions"), ondelete="CASCADE"),
sa.ForeignKeyConstraint(["revision_id"], ["template_revisions.id"], name=op.f("fk_template_renders_revision_id_template_revisions"), ondelete="RESTRICT"),
sa.PrimaryKeyConstraint("id", name=op.f("pk_template_renders")),
sa.UniqueConstraint("tenant_id", "idempotency_key", name="uq_template_render_idempotency"),
)
for column in ("tenant_id", "template_id", "revision_id", "mode", "usage", "idempotency_key", "created_by_account_id"):
op.create_index(op.f(f"ix_template_renders_{column}"), "template_renders", [column])
op.create_index("ix_template_renders_tenant_template", "template_renders", ["tenant_id", "template_id", "created_at"])
op.create_index("ix_template_renders_input_hash", "template_renders", ["tenant_id", "input_hash"])
def downgrade() -> None:
op.drop_table("template_renders")
op.drop_table("template_revisions")
op.drop_table("template_definitions")