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.
- The sender's identity is established (preprocessor injects it, or
get_user_contextruns) —src/index.ts:110-119. - 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). - On the tenant's reply, Alex calls
create_maintenance_ticketexactly once — multi-issue emails go on one ticket (src/index.ts:246) — and only claims a ticket exists after a realticketIdreturns (src/index.ts:380). - 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). - 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.
- Vendor submits cost via
submit_quote; status →quoted(src/skills/vendor.skill.ts:66). - 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). - Cost gate: over the threshold (default €500,
src/utils/constants.ts:146) → statuspending_approval; an approver replies YES/NO to the approval email, recorded automatically by thefinance-approval/inbound-emailpath — the agent has no tool for this and the tenant is never told (src/index.ts:517-524). Within threshold → auto-approved. - Time gate: the tenant picks an option; Alex calls
confirm_visit_timewith the chosen number (src/index.ts:179-184). - 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.
- Vendor
start_work→in_progress(src/skills/vendor.skill.ts:69). - Vendor
complete_jobrequires 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). - The hourly
completion-feedbackjob later emails the tenant a feedback request (completion-feedback.job.ts:39). - On a satisfied reply, Alex records feedback and
close_ticket→closed; 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.
- 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 theescalation-checkjob every 4 hours for stuck/SLA-breaching tickets (escalation.job.ts:30-35). - An escalation email goes to the admin team.
- 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. - 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.
- The admin-mode preprocessor (priority 15) flags
user.isAdmin = truewhen the sender email matches a configured approver address, unlocking theadminskill (src/index.ts:496-497,src/skills/admin.skill.ts:18-20). - Alex understands the question, then makes one
admin_query_ticketscall with the filters that fit (issue type, building, vendor, tenant) andincludeList:true— never fanning out multiple calls (src/skills/admin.skill.ts:23-29). - Counts are reported verbatim from the result's
aggregatesblock — never estimated or rounded (src/skills/admin.skill.ts:30-33). - 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).