Skip to content

Production Smoke Test

Run this checklist after any deployment (schema, API, or frontend) and periodically as an operational health pass. Work against production with a known-good agent account; use disposable data where the checklist creates anything (training sessions are safe to create and abort; report creation should use clearly-marked test fixtures or the demo environment).

1. Authentication

  • [ ] GET / returns DPS API Online from the production ingress.
  • [ ] /login completes the Discord OAuth round-trip; you land on /dashboard with your identity.
  • [ ] GET /auth/me returns your agent, permission flags, supervisor flag, and admin capabilities consistent with your record.
  • [ ] Sign out works; protected pages redirect to /login.
  • [ ] (Regression) a demo ingress cookie does not authenticate on production.

2. Report creation

  • [ ] Create a report through the bot path (or a clearance-2+ session) with a unique test report_id; the response includes the full report with the initial timeline row ("Report created").
  • [ ] Duplicate creation of the same report_id returns 409.
  • [ ] Invalid status / missing field / non-http(s) evidence_url each return 400.
  • [ ] The report appears in GET /reports and in the paginated list.

3. Investigation claim

  • [ ] An unassigned Open case is claimable; claim returns the updated report with your identity as assigned_agent.
  • [ ] A second claim attempt returns 409 (ALREADY_CLAIMED).
  • [ ] A non-assigned agent (below supervisor rank) gets 403 on case mutations for that report.

4. Action completion

  • [ ] investigate moves the case to Under Investigation and creates a pending_actions row; the queue pickups (GET /actions/next/operator or /supervisor) return it.
  • [ ] POST /actions/<id>/complete with {"result": "success"} returns 200; a second completion returns 409.
  • [ ] Notes/evidence can be added while under investigation (201), and are rejected outside investigation for browser sessions (409).

5. Requeue / failure

  • [ ] Completing an action with result=failed marks it failed; requeue (POST /actions/<id>/requeue) resets it to pending.
  • [ ] Requeueing a non-failed action returns 409.
  • [ ] The queue list (/actions/pending/operator?status=failed) surfaces attempts and result_note.

6. Audit / event creation

  • [ ] Each mutation above produced timeline rows; GET /audit shows them with resolved by_name and no raw user IDs in display text.
  • [ ] Search, event filter, sort, and pagination work on /audit.
  • [ ] Supervisor events are hidden (or shown) according to the caller's rank; supervisor counts are zeroed for non-supervisors.
  • [ ] events rows exist for the mutations (query via the API's database role) and are append-only (no UPDATE/DELETE grants).

7. Evidence viewing

  • [ ] Evidence with an http(s) URL renders in the docket and the Evidence workspace; the lightbox opens with the sanitized URL.
  • [ ] A stored non-http(s) URL (if any legacy row exists) renders as a fallback, never executes.
  • [ ] Discord profile images render from the stored snapshots.

8. Deletion and audit verification

  • [ ] DELETE /reports/<test_id> without a reason → 400.
  • [ ] With a reason: 200; the report is gone from lists; the timeline row and the canonical report.deleted event remain; the admin audit trail has the pre-image + reason.
  • [ ] Deleting a report you lack clearance for → 403.

9. Agent permissions

  • [ ] Agent list/detail respects view_agents.
  • [ ] Admin agents tab is gated by the allowlist + admin_agents; self-modification is blocked (403); rank/clearance changes by a non-Director are blocked (403); a Director's change produces an audit row with reason + before/after.
  • [ ] /admin/health, /admin/queue, /admin/audit render for an allowed admin; /admin/access and /admin/reports require Director rank.

10. Training

  • [ ] /training/me returns the correct role.
  • [ ] A trainer creates a session for an onboarding trainee; start, pause, resume, end, and abort transitions all work and record SESSION_* events.
  • [ ] Trainee role is locked to their own active session; trainer controls reject non-trainers and non-owner trainers (403); the API key is rejected on training routes (403).
  • [ ] Grading (score/result/feedback) completes the session; the trainee sees released feedback only.

11. Realtime behavior

  • [ ] A trainee browser joined to the session channel receives the trainer's scenario activation without a page refresh.
  • [ ] The Realtime status badge reaches connected; a forced reconnect reconciles state via an authoritative GET.
  • [ ] Presence reflects the online participant.
  • [ ] Broadcast failure (simulate by blocking the broadcast endpoint) does not fail the underlying mutation — state is consistent after refresh.

Escalation

Any failure above that involves data loss, unauthorized access, or audit missingness is an incident — follow Incident response.