no-mistakes(review): Make Cancelled reachable from all active states; wire phone PATCH; exclude cancelled from CEO resolution avg
This commit is contained in:
@@ -54,6 +54,7 @@ class TicketUpdate(BaseModel):
|
||||
category_id: int | None = None
|
||||
priority: str | None = None
|
||||
reporter: str | None = None
|
||||
phone: str | None = None
|
||||
reported_via: str | None = None
|
||||
description: str | None = None
|
||||
assigned_to: int | None = None
|
||||
|
||||
@@ -18,7 +18,7 @@ from app.services.sla import compute_sla_deadline
|
||||
# ── Status Transition Map ────────────────────────────────────────────
|
||||
# Keys: current status → list of valid next statuses
|
||||
VALID_TRANSITIONS: dict[str, list[str]] = {
|
||||
"New": ["Logged"],
|
||||
"New": ["Logged", "Cancelled"],
|
||||
"Logged": ["Triage", "Closed", "Cancelled"],
|
||||
"Triage": ["Assigned", "Escalated", "Cancelled"],
|
||||
"Assigned": ["Accepted", "Triage", "Cancelled"],
|
||||
@@ -28,11 +28,11 @@ VALID_TRANSITIONS: dict[str, list[str]] = {
|
||||
"In Progress": ["Waiting Parts", "Escalated", "Completed", "Cancelled"],
|
||||
"Waiting Parts": ["In Progress", "Escalated", "Cancelled"],
|
||||
"Escalated": ["Triage", "In Progress", "Completed", "Closed", "Cancelled"],
|
||||
"Completed": ["On-Field Verification", "In Progress"],
|
||||
"On-Field Verification": ["Wahab Review", "Completed", "Closed"],
|
||||
"Wahab Review": ["Closed", "On-Field Verification"],
|
||||
"Completed": ["On-Field Verification", "In Progress", "Cancelled"],
|
||||
"On-Field Verification": ["Wahab Review", "Completed", "Closed", "Cancelled"],
|
||||
"Wahab Review": ["Closed", "On-Field Verification", "Cancelled"],
|
||||
"Closed": ["Reopened"],
|
||||
"Reopened": ["Triage", "Logged"],
|
||||
"Reopened": ["Triage", "Logged", "Cancelled"],
|
||||
# Terminal: cancelled tickets cannot resume work.
|
||||
"Cancelled": [],
|
||||
}
|
||||
|
||||
@@ -288,7 +288,7 @@
|
||||
},
|
||||
|
||||
calcAvgResolution(all) {
|
||||
const closed = all.filter(t => ['Closed', 'Completed', 'Cancelled'].includes(t.status) && t.created_at && t.updated_at);
|
||||
const closed = all.filter(t => ['Closed', 'Completed'].includes(t.status) && t.created_at && t.updated_at);
|
||||
if (!closed.length) return '—';
|
||||
const avgHrs = closed.reduce((sum, t) => {
|
||||
const diff = (new Date(t.updated_at) - new Date(t.created_at)) / (1000 * 60 * 60);
|
||||
|
||||
@@ -60,7 +60,11 @@ async def test_cancelled_reachable_from_active_states(client):
|
||||
"""Logged/Triage/In Progress → Cancelled are all valid transitions."""
|
||||
from app.services.ticket import VALID_TRANSITIONS
|
||||
|
||||
for state in ("Logged", "Triage", "Assigned", "Accepted", "In Progress", "Escalated"):
|
||||
for state in (
|
||||
"New", "Logged", "Triage", "Assigned", "Accepted", "Travelling", "On Site",
|
||||
"In Progress", "Waiting Parts", "Escalated", "On-Field Verification",
|
||||
"Wahab Review", "Reopened",
|
||||
):
|
||||
assert "Cancelled" in VALID_TRANSITIONS[state], f"{state} should allow Cancelled"
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user