diff --git a/README.md b/README.md index 31193cb..e0af2f6 100644 --- a/README.md +++ b/README.md @@ -185,7 +185,7 @@ Free-tier dynos sleep after 15 min of inactivity. The frontend warms the backend | RMAs | `GET/POST/PUT /rmas` | | AI | `POST /ai/suggest` | -Status changes on tickets automatically append a row to `ticket_history`. +Ticket creation and every status change automatically append a row to `ticket_history` (creation is logged with `old_status = null`). Full OpenAPI spec available at `http://localhost:8000/docs` when the backend is running. diff --git a/backend/main.py b/backend/main.py index a434e29..723e6db 100644 --- a/backend/main.py +++ b/backend/main.py @@ -225,10 +225,23 @@ def get_ticket(id: str): @app.post("/tickets") def create_ticket(t: Ticket): - return db_post( - "tickets", - clean_empty_strings(model_data(t), "customer_id", "device_id", "assigned_user_id"), - ) + data = clean_empty_strings(model_data(t), "customer_id", "device_id", "assigned_user_id") + result = db_post("tickets", data) + # Record the initial status so the audit trail starts at creation + # (old_status=None), matching the history rows in the seed data. + # Supabase returns the inserted rows because of Prefer: return=representation. + created = result[0] if isinstance(result, list) and result else result + if isinstance(created, dict) and created.get("id"): + db_post( + "ticket_history", + { + "ticket_id": created["id"], + "old_status": None, + "new_status": created.get("status", data["status"]), + "changed_by": "Agent", + }, + ) + return result @app.put("/tickets/{id}") diff --git a/backend/test_main.py b/backend/test_main.py index ebd5e80..e032bf7 100644 --- a/backend/test_main.py +++ b/backend/test_main.py @@ -438,6 +438,42 @@ def fake_get(table, params=""): ) in posts +def test_create_ticket_records_initial_status_history(client, monkeypatch): + test_client, main = client + posts = [] + + def fake_post(table, data): + posts.append((table, data)) + if table == "tickets": + return [{"id": "t9", **data, "status": "In Progress"}] + return [data] + + monkeypatch.setattr(main, "db_post", fake_post) + + res = test_client.post("/tickets", json={"title": "VPN down", "status": "In Progress"}) + + assert res.status_code == 200 + assert res.json()[0]["id"] == "t9" + assert [table for table, _ in posts] == ["tickets", "ticket_history"] + assert posts[1][1] == { + "ticket_id": "t9", + "old_status": None, + "new_status": "In Progress", + "changed_by": "Agent", + } + + +def test_create_ticket_skips_history_when_insert_returns_no_row(client, monkeypatch): + test_client, main = client + posts = [] + monkeypatch.setattr(main, "db_post", lambda table, data: posts.append(table) or []) + + res = test_client.post("/tickets", json={"title": "VPN down"}) + + assert res.status_code == 200 + assert posts == ["tickets"] + + def test_ticket_routes_convert_blank_relationship_ids_to_null(client, monkeypatch): test_client, main = client calls = [] diff --git a/frontend/src/pages/Tickets.jsx b/frontend/src/pages/Tickets.jsx index cabc416..7119f2d 100644 --- a/frontend/src/pages/Tickets.jsx +++ b/frontend/src/pages/Tickets.jsx @@ -206,7 +206,7 @@ export default function Tickets() {
Loading history…
: history.length === 0 ?No history yet
: history.map(h => (