"""Contact folder permissions (ACLs for folder sharing). Revision ID: 0048 Revises: 0047 Create Date: 2026-07-28 """ from alembic import op import sqlalchemy as sa from sqlalchemy.dialects.postgresql import UUID as PGUUID revision = "0048" down_revision = "0047_saved_views" branch_labels = None depends_on = None def upgrade() -> None: op.create_table( "contact_folder_permissions", sa.Column("id", PGUUID(as_uuid=True), primary_key=True), sa.Column("folder_id", PGUUID(as_uuid=True), sa.ForeignKey("contact_folders.id", ondelete="CASCADE"), nullable=False), sa.Column("user_id", PGUUID(as_uuid=True), sa.ForeignKey("users.id", ondelete="CASCADE"), nullable=True), sa.Column("group_id", PGUUID(as_uuid=True), sa.ForeignKey("groups.id", ondelete="CASCADE"), nullable=True), sa.Column("tenant_id", PGUUID(as_uuid=True), sa.ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False), sa.Column("permission_level", sa.String(20), nullable=False, server_default="read"), sa.Column("inherit_to_subfolders", sa.Boolean, nullable=False, server_default="true"), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()), sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()), sa.UniqueConstraint("folder_id", "user_id", "group_id", "tenant_id", name="uq_cfp_folder_user_group_tenant"), sa.CheckConstraint( "(user_id IS NOT NULL AND group_id IS NULL) OR " "(user_id IS NULL AND group_id IS NOT NULL)", name="ck_cfp_exactly_one_principal", ), ) op.create_index("ix_cfp_folder", "contact_folder_permissions", ["folder_id"]) op.create_index("ix_cfp_user", "contact_folder_permissions", ["user_id"]) op.create_index("ix_cfp_group", "contact_folder_permissions", ["group_id"]) op.create_index("ix_cfp_tenant", "contact_folder_permissions", ["tenant_id"]) def downgrade() -> None: op.drop_index("ix_cfp_tenant", table_name="contact_folder_permissions") op.drop_index("ix_cfp_group", table_name="contact_folder_permissions") op.drop_index("ix_cfp_user", table_name="contact_folder_permissions") op.drop_index("ix_cfp_folder", table_name="contact_folder_permissions") op.drop_table("contact_folder_permissions")