Skip to main content

End-to-end flows

In one line: the five journeys that make up almost everything HIGHFIELD does — report, quote+approve+schedule, work+complete+close, escalate, and admin Q&A — each as a diagram plus the steps in order.

What it is

This page is the fastest way to understand the product. Each flow has a short intro a PM can read, a diagram, and a numbered step list with file:line for developers.

(a) Tenant reports an issue → ticket created → vendor assigned

A tenant emails or chats to report a problem. Alex usually asks one or two clarifying questions first (and always offers — optionally — a photo), then logs a single ticket and confirms it's in hand. A suitable contractor is matched and contacted.

  1. The sender's identity is established (preprocessor injects it, or get_user_context runs) — src/index.ts:110-119.
  2. Unless the opener is already complete or an emergency, Alex asks 1–2 specific questions and folds in an optional photo invite, in one message, and does not create a ticket yet (src/index.ts:248-250).
  3. On the tenant's reply, Alex calls create_maintenance_ticket exactly once — multi-issue emails go on one ticket (src/index.ts:246) — and only claims a ticket exists after a real ticketId returns (src/index.ts:380).
  4. Alex replies warmly: reflect the issue back, confirm it's logged, give a short "what happens next." No urgency/severity language (src/index.ts:389-427).
  5. A vendor is matched and contacted; status moves reported → vendor_contacted. (Emergencies skip the clarifying round and create immediately — src/index.ts:251,272-276.)

(b) Vendor quotes → finance approval (if over threshold) → tenant confirms visit time → lock-in

The contractor gives a price and at least two possible visit times. If the price is over the threshold, an approver must reply YES to an approval email (the tenant never hears about cost). In parallel, the tenant picks a time from a menu. When both gates clear, the visit is locked in.

  1. Vendor submits cost via submit_quote; status → quoted (src/skills/vendor.skill.ts:66).
  2. Vendor must give 2+ visit options; Alex sends the tenant a numbered menu via offer_visit_slots — the only tool that contacts the tenant about times (src/skills/vendor.skill.ts:77, src/index.ts:308-313).
  3. Cost gate: over the threshold (default €500, src/utils/constants.ts:146) → status pending_approval; an approver replies YES/NO to the approval email, recorded automatically by the finance-approval / inbound-email path — the agent has no tool for this and the tenant is never told (src/index.ts:517-524). Within threshold → auto-approved.
  4. Time gate: the tenant picks an option; Alex calls confirm_visit_time with the chosen number (src/index.ts:179-184).
  5. When both gates are clear, the visit locks in; the contractor is cleared and the tenant gets confirmation. Once locked in it stays settled (src/index.ts:185).

(c) Vendor does work → completes with photos/invoice → tenant feedback → close

The contractor starts work, then completes the job by sending photos and an invoice. A day or so later the tenant is asked how it went; if they're happy the ticket closes, if not it's escalated.

  1. Vendor start_workin_progress (src/skills/vendor.skill.ts:69).
  2. Vendor complete_job requires photos + invoice; the invoice is validated against the ticket (src/skills/vendor.skill.ts:70,90-97). Status → completed. The vendor's completion is final — the tenant is never asked to confirm completion (src/index.ts:267-270).
  3. The hourly completion-feedback job later emails the tenant a feedback request (completion-feedback.job.ts:39).
  4. On a satisfied reply, Alex records feedback and close_ticketclosed; on a dissatisfied reply, Alex escalates instead and does not close (src/index.ts:187-193).

(d) Escalation when something stalls

If a vendor goes quiet, a tenant disputes something, an issue worsens, or an SLA is breached, the agent (or a background timer) raises an escalation that emails the admin team. The admin replies with an instruction, which the agent relays.

  1. Escalations are raised either by the agent (escalate_ticket — vendor no-response, dispute, worsening issue, unhandled scenario; src/index.ts:150-157,255) or automatically by the escalation-check job every 4 hours for stuck/SLA-breaching tickets (escalation.job.ts:30-35).
  2. An escalation email goes to the admin team.
  3. The admin replies with an instruction; the agent actions it via admin_resolve_escalation (notify_tenant / notify_vendor / both / resolve) — src/index.ts:526-531.
  4. Messages relayed to the tenant stay free of cost/approval detail; the agent confirms back to the admin in one terse line. A routine reschedule is not an escalation — it's relayed to the contractor via relay_tenant_reschedule (src/index.ts:159-166).

(e) Admin asks a question and gets an answer

A property manager emails a question like "how many open tickets in the Tribeca building, and what's driving the electrical ones?" The agent pulls the data once, reports the exact numbers, and explains what they point to — no chit-chat, no process narration.

  1. The admin-mode preprocessor (priority 15) flags user.isAdmin = true when the sender email matches a configured approver address, unlocking the admin skill (src/index.ts:496-497, src/skills/admin.skill.ts:18-20).
  2. Alex understands the question, then makes one admin_query_tickets call with the filters that fit (issue type, building, vendor, tenant) and includeList:true — never fanning out multiple calls (src/skills/admin.skill.ts:23-29).
  3. Counts are reported verbatim from the result's aggregates block — never estimated or rounded (src/skills/admin.skill.ts:30-33).
  4. The reply leads with the bottom line, gives exact numbers, and explains (hedged, grounded in the tickets' own text) what they point to — formatted as email-safe Markdown with status emojis. The agent never narrates process or mentions "admin mode" (src/index.ts:505, src/skills/admin.skill.ts:48-49).