"""附件表(任务 / 工单 / 知识共用) Revision ID: 0005 Revises: 0004 """ from __future__ import annotations import sqlalchemy as sa from sqlalchemy.dialects.postgresql import UUID as PgUUID from alembic import op revision = "0005" down_revision = "0004" branch_labels = None depends_on = None def upgrade() -> None: op.create_table( "attachment", sa.Column("id", PgUUID(as_uuid=True), primary_key=True), sa.Column( "workspace_id", PgUUID(as_uuid=True), sa.ForeignKey("workspace.id", ondelete="CASCADE"), nullable=False, ), sa.Column( "item_id", PgUUID(as_uuid=True), sa.ForeignKey("item.id", ondelete="CASCADE"), nullable=False, ), sa.Column( "uploader_id", PgUUID(as_uuid=True), sa.ForeignKey("app_user.id", ondelete="RESTRICT"), nullable=False, ), sa.Column("filename", sa.String(255), nullable=False), sa.Column("content_type", sa.String(120), nullable=False), sa.Column("size_bytes", sa.BigInteger(), nullable=False), sa.Column("sha256", sa.String(64), nullable=False), sa.Column("storage_key", sa.String(255), nullable=False, unique=True), sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False), sa.CheckConstraint("size_bytes >= 0", name="ck_attachment_size"), ) op.create_index( "ix_attachment_ws_item", "attachment", ["workspace_id", "item_id", "created_at"] ) for statement in ( "ALTER TABLE attachment ENABLE ROW LEVEL SECURITY", "CREATE POLICY attachment_isolation ON attachment " "USING (workspace_id = app_ws_id()) WITH CHECK (workspace_id = app_ws_id())", "GRANT SELECT, INSERT, UPDATE, DELETE ON attachment TO dadao_app", ): op.execute(statement) def downgrade() -> None: op.execute("DROP POLICY IF EXISTS attachment_isolation ON attachment") op.drop_index("ix_attachment_ws_item", table_name="attachment") op.drop_table("attachment")