Separate normal task review from AQMM review
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
"""separate normal operational review from AQMM review
|
||||
|
||||
Revision ID: 20260811_normal_review
|
||||
Revises: 20260808_task_role_eligibility
|
||||
Create Date: 2026-08-11
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
revision = "20260811_normal_review"
|
||||
down_revision = "20260808_task_role_eligibility"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
op.add_column("service_default_task_templates", sa.Column("normal_review_role", sa.String(length=30), nullable=True))
|
||||
op.add_column("firm_service_task_templates", sa.Column("normal_review_role", sa.String(length=30), nullable=True))
|
||||
|
||||
op.add_column("client_service_task_instances", sa.Column("normal_review_required", sa.Boolean(), nullable=False, server_default=sa.false()))
|
||||
op.add_column("client_service_task_instances", sa.Column("normal_review_role", sa.String(length=30), nullable=True))
|
||||
op.add_column("client_service_task_instances", sa.Column("normal_review_status", sa.String(length=30), nullable=False, server_default="not_required"))
|
||||
op.add_column("client_service_task_instances", sa.Column("normal_review_note", sa.Text(), nullable=True))
|
||||
op.add_column("client_service_task_instances", sa.Column("normal_reviewed_by_user_id", sa.Integer(), nullable=True))
|
||||
op.add_column("client_service_task_instances", sa.Column("normal_reviewed_at_utc", sa.DateTime(timezone=True), nullable=True))
|
||||
op.create_foreign_key(
|
||||
"fk_task_instance_normal_reviewed_by",
|
||||
"client_service_task_instances",
|
||||
"users",
|
||||
["normal_reviewed_by_user_id"],
|
||||
["id"],
|
||||
ondelete="SET NULL",
|
||||
)
|
||||
op.create_index("ix_task_instance_normal_review_required", "client_service_task_instances", ["normal_review_required"])
|
||||
op.create_index("ix_task_instance_normal_review_role", "client_service_task_instances", ["normal_review_role"])
|
||||
op.create_index("ix_task_instance_normal_review_status", "client_service_task_instances", ["normal_review_status"])
|
||||
op.create_index("ix_task_instance_normal_reviewed_by", "client_service_task_instances", ["normal_reviewed_by_user_id"])
|
||||
|
||||
# Preserve the old intent of requires_review while making the reviewer explicit.
|
||||
# Reviewer inference follows task hierarchy: Staff -> Manager, Manager -> Partner.
|
||||
role_case = """
|
||||
CASE
|
||||
WHEN NOT requires_review THEN NULL
|
||||
WHEN lower(coalesce(default_role_name,'')) IN ('manager','branch manager')
|
||||
AND lower(coalesce(eligible_role_names,'')) LIKE '%partner%' THEN 'partner'
|
||||
WHEN lower(coalesce(default_role_name,'')) NOT IN ('manager','branch manager','partner')
|
||||
AND (lower(coalesce(eligible_role_names,'')) LIKE '%manager%' OR lower(coalesce(eligible_role_names,'')) LIKE '%branch manager%') THEN 'manager'
|
||||
WHEN lower(coalesce(eligible_role_names,'')) LIKE '%partner%'
|
||||
AND lower(coalesce(eligible_role_names,'')) NOT LIKE '%manager%' THEN 'partner'
|
||||
ELSE 'manager'
|
||||
END
|
||||
"""
|
||||
op.execute(sa.text(f"UPDATE service_default_task_templates SET normal_review_role = {role_case} WHERE requires_review = TRUE"))
|
||||
op.execute(sa.text(f"UPDATE firm_service_task_templates SET normal_review_role = {role_case} WHERE requires_review = TRUE"))
|
||||
|
||||
# Snapshot normal-review configuration into every existing engagement task.
|
||||
op.execute(sa.text("""
|
||||
UPDATE client_service_task_instances AS t
|
||||
SET normal_review_required = f.requires_review,
|
||||
normal_review_role = f.normal_review_role
|
||||
FROM firm_service_task_templates AS f
|
||||
WHERE t.firm_task_template_id = f.id
|
||||
"""))
|
||||
|
||||
# Preserve prior generic approvals where they were already recorded in the legacy
|
||||
# manager/partner fields. Otherwise completed/submitted work becomes Pending Review;
|
||||
# unstarted work remains Not Ready. AQMM fields themselves are not changed.
|
||||
op.execute(sa.text("""
|
||||
UPDATE client_service_task_instances
|
||||
SET normal_review_status = CASE
|
||||
WHEN NOT normal_review_required THEN 'not_required'
|
||||
WHEN normal_review_role IN ('manager','manager_or_partner') AND manager_review_status = 'reviewed' THEN 'reviewed'
|
||||
WHEN normal_review_role = 'partner' AND partner_review_status = 'reviewed' THEN 'reviewed'
|
||||
WHEN rework_status = 'open' THEN 'rework_required'
|
||||
WHEN submitted_for_review_at_utc IS NOT NULL OR lower(coalesce(status,'')) = 'completed' THEN 'pending'
|
||||
ELSE 'not_ready'
|
||||
END,
|
||||
normal_review_note = CASE
|
||||
WHEN normal_review_role IN ('manager','manager_or_partner') AND manager_review_status IN ('reviewed','rework_required') THEN manager_review_note
|
||||
WHEN normal_review_role = 'partner' AND partner_review_status IN ('reviewed','rework_required') THEN partner_review_note
|
||||
ELSE NULL
|
||||
END,
|
||||
normal_reviewed_by_user_id = CASE
|
||||
WHEN normal_review_role IN ('manager','manager_or_partner') AND manager_review_status = 'reviewed' THEN manager_reviewed_by_user_id
|
||||
WHEN normal_review_role = 'partner' AND partner_review_status = 'reviewed' THEN partner_reviewed_by_user_id
|
||||
ELSE NULL
|
||||
END,
|
||||
normal_reviewed_at_utc = CASE
|
||||
WHEN normal_review_role IN ('manager','manager_or_partner') AND manager_review_status = 'reviewed' THEN manager_reviewed_at_utc
|
||||
WHEN normal_review_role = 'partner' AND partner_review_status = 'reviewed' THEN partner_reviewed_at_utc
|
||||
ELSE NULL
|
||||
END
|
||||
"""))
|
||||
|
||||
op.alter_column("client_service_task_instances", "normal_review_required", server_default=None)
|
||||
op.alter_column("client_service_task_instances", "normal_review_status", server_default=None)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_index("ix_task_instance_normal_reviewed_by", table_name="client_service_task_instances")
|
||||
op.drop_index("ix_task_instance_normal_review_status", table_name="client_service_task_instances")
|
||||
op.drop_index("ix_task_instance_normal_review_role", table_name="client_service_task_instances")
|
||||
op.drop_index("ix_task_instance_normal_review_required", table_name="client_service_task_instances")
|
||||
op.drop_constraint("fk_task_instance_normal_reviewed_by", "client_service_task_instances", type_="foreignkey")
|
||||
op.drop_column("client_service_task_instances", "normal_reviewed_at_utc")
|
||||
op.drop_column("client_service_task_instances", "normal_reviewed_by_user_id")
|
||||
op.drop_column("client_service_task_instances", "normal_review_note")
|
||||
op.drop_column("client_service_task_instances", "normal_review_status")
|
||||
op.drop_column("client_service_task_instances", "normal_review_role")
|
||||
op.drop_column("client_service_task_instances", "normal_review_required")
|
||||
op.drop_column("firm_service_task_templates", "normal_review_role")
|
||||
op.drop_column("service_default_task_templates", "normal_review_role")
|
||||
Reference in New Issue
Block a user