Fascicoli+Tassonomia+permessi
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
"""
|
||||
Migrazione 0017: Tassonomia di Classificazione Multi-livello (Feature N2).
|
||||
|
||||
Estende la tabella `labels` con:
|
||||
- parent_id: FK self-referenziale (nullable) per struttura ad albero
|
||||
- description: testo descrittivo opzionale
|
||||
|
||||
Struttura tassonomica:
|
||||
Livello 0 (radice) = Ambito (Area Aziendale) — parent_id IS NULL
|
||||
Livello 1 = Processo — parent_id = ID Ambito
|
||||
Livello 2 (foglia) = Classificazione — parent_id = ID Processo
|
||||
|
||||
I vincoli di unicità vengono sostituiti con indici parziali per supportare
|
||||
nomi identici a diversi livelli dell'albero.
|
||||
"""
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.dialects import postgresql
|
||||
|
||||
revision = "0017"
|
||||
down_revision = "0016"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# ── Aggiunge parent_id (FK self-referenziale nullable) ─────────────────────
|
||||
op.add_column(
|
||||
"labels",
|
||||
sa.Column(
|
||||
"parent_id",
|
||||
postgresql.UUID(as_uuid=True),
|
||||
nullable=True,
|
||||
),
|
||||
)
|
||||
op.create_foreign_key(
|
||||
"fk_labels_parent",
|
||||
"labels",
|
||||
"labels",
|
||||
["parent_id"],
|
||||
["id"],
|
||||
ondelete="CASCADE",
|
||||
)
|
||||
|
||||
# ── Aggiunge description ────────────────────────────────────────────────────
|
||||
op.add_column(
|
||||
"labels",
|
||||
sa.Column("description", sa.Text(), nullable=True),
|
||||
)
|
||||
|
||||
# ── Indice su parent_id per query gerarchiche ───────────────────────────────
|
||||
op.create_index("idx_labels_parent", "labels", ["parent_id"])
|
||||
|
||||
# ── Sostituisce il vincolo di unicità con indici parziali ───────────────────
|
||||
# Il vecchio vincolo (tenant_id, name) non supporta nomi uguali a livelli diversi
|
||||
op.drop_constraint("uq_label_name_tenant", "labels")
|
||||
|
||||
# Nodi radice: nome unico per tenant (parent_id IS NULL)
|
||||
op.execute(
|
||||
"CREATE UNIQUE INDEX uq_label_name_root "
|
||||
"ON labels (tenant_id, name) WHERE parent_id IS NULL"
|
||||
)
|
||||
# Nodi non-radice: nome unico per (tenant, parent) — stesso nome ammesso sotto parent diversi
|
||||
op.execute(
|
||||
"CREATE UNIQUE INDEX uq_label_name_parent "
|
||||
"ON labels (tenant_id, name, parent_id) WHERE parent_id IS NOT NULL"
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.execute("DROP INDEX IF EXISTS uq_label_name_parent")
|
||||
op.execute("DROP INDEX IF EXISTS uq_label_name_root")
|
||||
op.create_unique_constraint("uq_label_name_tenant", "labels", ["tenant_id", "name"])
|
||||
op.drop_index("idx_labels_parent", table_name="labels")
|
||||
op.drop_constraint("fk_labels_parent", "labels", type_="foreignkey")
|
||||
op.drop_column("labels", "description")
|
||||
op.drop_column("labels", "parent_id")
|
||||
Reference in New Issue
Block a user