Skip to main content

AI Triage

The headline feature. Click Suggest triage on any NEW request and Claude Haiku returns a structured triage result in about a second.

What you get back

{
"category": "EMERGENCY_SAFETY",
"urgency": "EMERGENCY",
"confidence": 0.94,
"reasoning": "Headaches + nausea + yellow gas flame reads as possible CO exposure — treat as life-safety.",
"suggestedActions": [
"Call the tenant and tell them to open windows + leave the unit",
"Dispatch a licensed gas fitter within 4 hours",
"Close any rooms containing the gas heater until certified"
],
"modelVersion": "claude-haiku-4-5@prompt-v2"
}
  • Category: PLUMBING / ELECTRICAL / APPLIANCE / HEATING_COOLING / STRUCTURAL / PEST / SECURITY / GARDEN / CLEANING / EMERGENCY_SAFETY / OTHER.
  • Urgency: EMERGENCY (4h SLA) / URGENT (24h) / NORMAL (3d) / LOW (7d).
  • Confidence: 0.0 – 1.0. Below 0.7 we show a Human triage required badge — you should not just click accept.
  • Reasoning: one sentence. Shown verbatim in the review drawer so the PM sees why Claude picked what it picked.
  • Suggested actions: 2–4 items in priority order. These drive the drawer's "Next steps" list and make Claude's suggestion actionable, not just a classifier output.

The review → apply loop

  1. Click Suggest triage on a NEW request.
  2. The form pre-populates with Claude's picks (category dropdown, urgency radio). You can override either.
  3. The reasoning + actions appear below the form.
  4. Click Apply triage. The request moves to TRIAGED. The SLA clock starts based on urgency (see SLA Clock).

The form auto-syncs when a new suggestion comes in — if you re-click Suggest triage after editing, the dropdowns update to Claude's new picks.

The "Human triage required" badge

Shown when:

  • Confidence < 0.7, OR
  • The Claude call failed and the heuristic fallback was used, OR
  • The circuit breaker is open (3 consecutive Claude failures in a row).

Don't ignore it. Read the tenant text. Apply your own judgement.

Heuristic fallback

If Claude is unavailable, we fall back to a deterministic keyword-rule classifier:

  • gas / carbon monoxide / smoke / fireEMERGENCY_SAFETY, EMERGENCY
  • burst / flood / leak + ceilingPLUMBING, URGENT
  • no hot water / cold showerPLUMBING, URGENT
  • power out / no electricityELECTRICAL, URGENT
  • oven / fridge / washing machineAPPLIANCE, NORMAL
  • lock / key / break-inSECURITY, URGENT
  • …and so on. Not as nuanced, but never returns nothing.

Implementation: HeuristicTriageAssistant in backend/modules/infrastructure. Rules live as plain Java so they're code-reviewed alongside everything else.

API

POST /api/v1/maintenance-requests/{id}/suggest-triage

No body. Returns the triage JSON above. Idempotent — re-calling returns a fresh suggestion each time; nothing is written until you apply.

POST /api/v1/maintenance-requests/{id}/apply-triage
Content-Type: application/json

{
"category": "EMERGENCY_SAFETY",
"urgency": "EMERGENCY"
}

Writes the triage decision, transitions status to TRIAGED, starts the SLA timer, writes an audit-log row.

Privacy

Only the tenant's report text is sent to Anthropic for triage. No tenant name, no email, no address, no property identifier. See AI Privacy & Fallbacks for the full list of what we do and don't transmit.

See also