94 lines
3.5 KiB
Python
94 lines
3.5 KiB
Python
|
|
"""Workspace tenant integrity constraints.
|
||
|
|
|
||
|
|
Plan 4.3: Add tenant-bound foreign keys to workspace child tables.
|
||
|
|
|
||
|
|
- workspaces: UNIQUE (tenant_id, id)
|
||
|
|
- workspace_modules: FK (tenant_id, workspace_id) → workspaces (tenant_id, id)
|
||
|
|
- workspace_widgets: FK (tenant_id, workspace_id) → workspaces (tenant_id, id)
|
||
|
|
- workspace_users: FK (tenant_id, workspace_id) → workspaces (tenant_id, id)
|
||
|
|
- workspace_users: FK (tenant_id, user_id) → user_tenants (tenant_id, user_id)
|
||
|
|
|
||
|
|
Revision ID: 0096
|
||
|
|
Revises: 0095
|
||
|
|
"""
|
||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from alembic import op
|
||
|
|
|
||
|
|
revision = "0096"
|
||
|
|
down_revision = "0095"
|
||
|
|
branch_labels = None
|
||
|
|
depends_on = None
|
||
|
|
|
||
|
|
|
||
|
|
def upgrade() -> None:
|
||
|
|
# 1. Add UNIQUE (tenant_id, id) on workspaces
|
||
|
|
op.execute(
|
||
|
|
"CREATE UNIQUE INDEX IF NOT EXISTS uq_workspaces_tenant_id "
|
||
|
|
"ON workspaces (tenant_id, id)"
|
||
|
|
)
|
||
|
|
|
||
|
|
# 2. Drop existing FKs on workspace_modules (workspace_id → workspaces.id)
|
||
|
|
# and replace with tenant-bound FK
|
||
|
|
op.execute("ALTER TABLE workspace_modules DROP CONSTRAINT IF EXISTS workspace_modules_workspace_id_fkey")
|
||
|
|
op.execute(
|
||
|
|
"ALTER TABLE workspace_modules "
|
||
|
|
"ADD CONSTRAINT fk_wm_tenant_workspace "
|
||
|
|
"FOREIGN KEY (tenant_id, workspace_id) "
|
||
|
|
"REFERENCES workspaces (tenant_id, id) ON DELETE CASCADE"
|
||
|
|
)
|
||
|
|
|
||
|
|
# 3. Drop existing FK on workspace_widgets and replace with tenant-bound FK
|
||
|
|
op.execute("ALTER TABLE workspace_widgets DROP CONSTRAINT IF EXISTS workspace_widgets_workspace_id_fkey")
|
||
|
|
op.execute(
|
||
|
|
"ALTER TABLE workspace_widgets "
|
||
|
|
"ADD CONSTRAINT fk_ww_tenant_workspace "
|
||
|
|
"FOREIGN KEY (tenant_id, workspace_id) "
|
||
|
|
"REFERENCES workspaces (tenant_id, id) ON DELETE CASCADE"
|
||
|
|
)
|
||
|
|
|
||
|
|
# 4. Drop existing FK on workspace_users and replace with tenant-bound FK
|
||
|
|
op.execute("ALTER TABLE workspace_users DROP CONSTRAINT IF EXISTS workspace_users_workspace_id_fkey")
|
||
|
|
op.execute(
|
||
|
|
"ALTER TABLE workspace_users "
|
||
|
|
"ADD CONSTRAINT fk_wu_tenant_workspace "
|
||
|
|
"FOREIGN KEY (tenant_id, workspace_id) "
|
||
|
|
"REFERENCES workspaces (tenant_id, id) ON DELETE CASCADE"
|
||
|
|
)
|
||
|
|
|
||
|
|
# 5. Add FK on workspace_users (tenant_id, user_id) → user_tenants (tenant_id, user_id)
|
||
|
|
op.execute(
|
||
|
|
"ALTER TABLE workspace_users "
|
||
|
|
"ADD CONSTRAINT fk_wu_tenant_user "
|
||
|
|
"FOREIGN KEY (tenant_id, user_id) "
|
||
|
|
"REFERENCES user_tenants (tenant_id, user_id) ON DELETE CASCADE"
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
def downgrade() -> None:
|
||
|
|
# Remove tenant-bound FKs, restore simple FKs
|
||
|
|
op.execute("ALTER TABLE workspace_users DROP CONSTRAINT IF EXISTS fk_wu_tenant_user")
|
||
|
|
op.execute("ALTER TABLE workspace_users DROP CONSTRAINT IF EXISTS fk_wu_tenant_workspace")
|
||
|
|
op.execute(
|
||
|
|
"ALTER TABLE workspace_users "
|
||
|
|
"ADD CONSTRAINT workspace_users_workspace_id_fkey "
|
||
|
|
"FOREIGN KEY (workspace_id) REFERENCES workspaces (id) ON DELETE CASCADE"
|
||
|
|
)
|
||
|
|
|
||
|
|
op.execute("ALTER TABLE workspace_widgets DROP CONSTRAINT IF EXISTS fk_ww_tenant_workspace")
|
||
|
|
op.execute(
|
||
|
|
"ALTER TABLE workspace_widgets "
|
||
|
|
"ADD CONSTRAINT workspace_widgets_workspace_id_fkey "
|
||
|
|
"FOREIGN KEY (workspace_id) REFERENCES workspaces (id) ON DELETE CASCADE"
|
||
|
|
)
|
||
|
|
|
||
|
|
op.execute("ALTER TABLE workspace_modules DROP CONSTRAINT IF EXISTS fk_wm_tenant_workspace")
|
||
|
|
op.execute(
|
||
|
|
"ALTER TABLE workspace_modules "
|
||
|
|
"ADD CONSTRAINT workspace_modules_workspace_id_fkey "
|
||
|
|
"FOREIGN KEY (workspace_id) REFERENCES workspaces (id) ON DELETE CASCADE"
|
||
|
|
)
|
||
|
|
|
||
|
|
op.execute("DROP INDEX IF EXISTS uq_workspaces_tenant_id")
|