Quality Air OS is the company's operating system: dispatch, sales, estimating, billing, inventory, fleet, HR, training, and the customer portal — one codebase, one database, one set of rules. This page is its living blueprint: every department drawn brick by brick, what it does, who can touch it, and how the internals fit together. It grows with the build.
Sidebar modules at full access
22
Web surfaces on one deploy
5
Access tiers (T0–T9)
11
Dispatch boards
8
Commits (Jun 5 → Sep 23)
636
AI providers live in production
2 of 7
One building, five doors
Five surfaces on one deploy
Everything below is a single application and a single database. Which door you walk through is decided by the web address — and every door opens onto only its own rooms. An address the system doesn't recognize gets a dead-end login page, never the office.
One codebase · one database
host-routed, fails closed
Office consoleoffice.qualityairhvac.comThe full command center — every department below. The old admin. address still works as an alias.Owner, admins, office, strategy, sales, CSR
Field apptechnician.qualityairhvac.comNative app: iPhone on the App Store (1.3), Android through Google Play closed testing or the direct APK. Not a PWA.Technicians, laborers & field managers
Client portalclientlogin.qualityairhvac.comRead-only project window + service requests. No invoices, payments, or booking.Invited customers only
Training hubtraining.qualityairhvac.comServes the training area only: courses and the interactive 24V controls lab.Learners (techs + managers)
About OSaboutos.qualityairhvac.comThe living blueprint of the whole system. Public and static.Leadership — this page
How it's built
The architecture, layer by layer
From the screens down to the database, each layer has one owner and one job. The security layer is the important one: the database itself enforces who sees what, so the rules hold even against a mistake in the screens.
Surfaces
Five host-routed web surfaces on one Next.js deploy — unknown hosts fail closed to a dead-end login, never the office app. The field app is that same technician surface wrapped as a native iPhone and Android app. A separate QA Sales Pro iPad app is in development against the office API and is not released.
Office consoleField app (iPhone + Android)Client portalTraining hubAbout OSQA Sales Pro iPad (in development)
Application
Next.js App Router on Vercel. Server components joined to live data; realtime boards re-render on database change.
Server renderingRealtime boardsPrint-to-PDF surfacesEdge middleware guard
Data & security
Supabase Postgres. Row-level security is the real enforcement — the database itself refuses what a role shouldn't see, so the rules hold even against a UI mistake.
Row-level security11-tier role enumAudit trailsFrozen snapshots for documents
AI layer
A task-routed model gateway: each job type names a preferred model, with a fallback chain behind it. The code knows seven providers, but production holds keys for two — Claude and Gemini — so every task routed to OpenAI or Groq falls back to Gemini today. That includes the estimator's builder, which the code routes to GPT-4o. A local-model lane is coded but nothing calls it.
Claude (sales chat, concierge, curriculum, CFO analyst)Gemini (estimator team, documents, voice, bookkeeper — in production today)OpenAI · Groq · Together · OpenRouter (routed in code, no production key)Ollama (coded, unused)
Integrations
The outside world, wired in. Supplier bills are set up to post to QuickBooks on their own (an administrator can pause that with a server setting); invoices and journal entries still cross on a person's button. The QuickBooks company guard is armed in production.
Every person in the company — and every customer — holds exactly one tier. The tier decides which surfaces exist for them, which departments appear, and which rows of data the database will even return. A pay rate, for example, can be changed only by the Super Admin (T0) — the database itself refuses anyone else.
T0Super AdminEverything, incl. Team & Access (grants tiers, sets pay rates), writing the Assembly workbench, and the correction desk — can also be dispatched to jobs
T1Admin (Owner)Full office nav; HR, System, Agents; reads the Assembly workbench without writing it. Team & Access is T0's alone
T2Office ManagerOffice operations incl. full Finance and crew changes on the schedule; no HR or system admin
T3Strategy ManagerDashboard, search, Finance (read-only), Help — the numbers view
T8Sales Team MemberSales only, scoped to their own deals
T9Customer Service RepDispatch scheduling (can drag on the Company Wide Schedule, can't change crew), no financials, no Dashboard
Brick by brick
Every department, fully drawn
Each card is one department of the OS: what it does today, who can open it, the path work takes through it, and — held to the same honesty rule as the in-app guides — what is deliberately not built yet.
Command
Dashboard & Search
/dashboard · /searchOffice T0–T2 + Strategy T3
The morning command brief: pending approvals, today's jobs, 30-day revenue, system health, and a live schedule board. Beside it, one fuzzy search box that looks across customers, projects, work orders, vendors, parts, and the company Google Drive at the same time — and, before you type anything, shows what you opened recently.
Approvals, today's jobs, and 30-day revenue at a glance; Awaiting Authorization and Punchlist Pending cards appear only when something is waiting
A Website Leads card, first in the row for the office tiers (T0–T2): the same waiting count as the Dispatch → Website leads badge, one query behind both, with an arrow into the queue
The Company Wide Schedule embedded at the bottom — office tiers (T0–T2) can drag a job to a new day or technician right there; everyone else who opens the Dashboard sees it read-only. The CSR (T9) can't open the Dashboard and drags on the same board inside Dispatch instead
One search box across five record types — customers, projects, work orders, vendors, parts — plus Google Drive
Recents before you type: the work orders, invoices, customers, projects, and vendor bills you opened lately. The Search page also shows a live drop-down as you type
System-overview walkthrough video for onboarding
Not built yet — said plainly
Invoices are not a search type — they only show up in recents, after you have opened one
Project results in search are listed but not clickable yet — a known defect
The Today's Schedule card actually lists the next four upcoming jobs, not strictly today's — a known defect
data: work_orders · invoices · approval_queue
Operations
Dispatch
/dispatch (+ ahs, preventive-maintenance, subcontractor [Projects], phdc, eca, leads, requests, new) · /authorizationsOffice + Field Manager; Sales Manager & CSR see the board (CSR schedules, no financials). PHDC, ECA, Website leads, Portal requests, and New job are office-only (T0–T2)
The heart of daily operations. Eight boards — Residential kanban, AHS warranty authorizations, Preventive Maintenance cycles, Projects timeline, PHDC city work, ECA agency work, Website-lead triage, and customer Portal requests. The six scheduling boards each have a Day, Week, and Month view; the Website-lead and Portal-request queues are not schedules and have none. The business day is 8 AM to 4 PM, and every job books into a day and a 2, 4, or 8-hour block sized by the service type. A job can carry a crew — one lead technician plus helpers — and every card now leads with what kind of visit it is.
Eight work-stream boards with drag-and-drop scheduling — ECA agency work now routes to a board of its own
Cards lead with the service type and an Open button (the WO number left the card face); Week and Day views lead with the service type too, while Month shows only dots and counts. Each pipeline has its own types — Residential: Service Call, Part Installation, System Installation, Estimate, Maintenance, Return Call; AHS: Service Call, Recall, Part Installation, System Installation, System Cleaning; PM: Maintenance Visit; Projects and ECA: Service Call, System Installation, Estimate, Assessment, Return Call
PHDC work-order types — Assessment, Installation, Service Repair, Service Call — are required when a PHDC job is created, show as a badge, filter the PHDC board, and stay editable by the office until the field starts the job. An old job with none reads Unspecified
Crew: a job has one lead and can carry extra technicians. The Crew panel in the schedule preview adds or removes them — office tiers (T0–T2) only; the CSR can reschedule but not change crew — and the crew locks once the field has started. Crew members see the job read-only in their field app
An amber Action required · Ready for office panel on the PHDC and ECA boards counts completed project jobs still awaiting billing
Awaiting Authorization (/authorizations) lists every job handed back for a parts decision, by department, with Authorize & raise PO; AHS jobs link to the AHS desk, and a job with no part says it needs a return visit. The sidebar item appears only while something is waiting
New job (office only) books any of six pipelines, creating the customer and property if needed; AHS takes an 8–9-digit dispatch number, and Projects, PHDC, and ECA create or link their project
The Company Wide Schedule: every department's schedule on one calendar with click-to-preview, pinned above the six scheduling boards (not Website leads or Portal requests) and on the dashboard — the scheduling tiers (T0, T1, T2, T9) can drag a job to another day or technician on its Day → By tech view; everyone else reads it
Three views on each of the six scheduling boards — Residential, AHS, PM, Projects, PHDC, ECA (the Website-lead and Portal-request queues are not schedules): Day (by technician row, 8 AM–4 PM), the new read-only Week grid (seven Sunday-first columns), and the Month load grid
Residential kanban runs five lanes, including Needs Authorization for jobs waiting on a parts decision
Five desk states carry a job: open, booked, field, authorizing, completed. `booked` now keeps both the crew and the slot editable — only the service type settles (except PHDC's work-order type, which the office can still change until the field starts); `authorizing` (a job handed back for a decision) locks the crew and the type but still lets the office re-slot the return visit
The AHS board runs eight lanes — Unassigned, Dispatched, Diagnosed, Needs Authorization, Awaiting Autho Approval, Authorized, Completed, Exceptions — so a job waiting on us is never mixed in with a job waiting on AHS. The office submits; only the Super Admin approves or denies; booking the return visit re-dispatches the same work order rather than opening a second one
Super-admin correction desk on the work-order page: T0 alone can set any lead, time, or status with no 8–4 window and no 2-hour mark, for straightening out imported rows. A blank field is left alone, and every change is written into the job's history. It does not override the field lock, the reopen PIN, or the truck gate
Website enquiries land in a triage queue — humans promote real ones to work orders, bots never reach the board; QA Concierge chats arrive tagged with type and urgency, and its sales enquiries route themselves to the pipeline
Lead promotion asks which pipeline (Residential, AHS, PM, PHDC, ECA), prefills the form, and writes nothing until a person confirms
The city boards (PHDC, ECA) file their own project container inline, and intake can mint one for the PHDC, ECA, and Projects lanes without leaving the form
The PHDC board offers only PHDC's stages — Scheduled, In Progress, Punch List, Complete, Invoiced, Paid — and opens on the Scheduled queue; its Move stage picker has no Bid, Awarded, or Lost, and the server refuses those three for a PHDC project. ECA keeps the full list and opens on Awarded
The work-order page is a desk: an 8-stage pipeline rail with interrupts drawn on the current rung, plus Overview, Activity, Parts & POs, Documents, and Finance tabs — then an Invoice jump that opens the counterpart bill at `/billing/{id}` when one exists (hidden when it does not; it is not a sixth in-page tab)
City jobs that the technician completes stay on the PHDC or ECA board so the office can invoice them; completing in the field mints the counterpart invoice. The board shows job number and resident, not Unknown customer, and never mints a retail QUALITY AIR person for a PHDC resident
Office-only 12-check verification panel on every work order — advisory today (it reports, it does not block completion), and legacy completed jobs are labelled never verified
Field lock: the office owns a job until the technician taps En route — then assignment, type, and slot freeze at the database itself
Admin close-out override: a job the technician is still holding cannot be completed by the office at all — the completed and closed options leave the status control. Only a T0/T1 admin can close it, through a control that requires close-out notes of at least 20 characters, written onto the job as its tech notes and stamped as a management close. The counterpart invoice graduates into the billing queue exactly as it does for a technician-closed job, and the technician is shown a Closed for you by management notice in the field app naming the job, who closed it, why, and the reminder that close-out times are read downstream
Reopening a completed job takes a manager's personal 4-digit PIN
Labor cost (technician day rates) visible to office tiers only
Boards refresh themselves in realtime when the data changes
A job's life
Enquirywebsite / phone / AHS
Triagehuman review
Work orderbooked into a slot
Field visitnative app
Signed closeoutsignature + 10–30s video (app)
Invoicepriced; QuickBooks by button
Not built yet — said plainly
Job alerts to technicians' phones are built but not live. Booking, rescheduling, or adding crew queues an alert, and evening reminders cover unfinished jobs — but iPhone delivery needs field app 1.5, which is not released, and Android has no push credentials configured, so no technician receives an alert today
The office verification checklist reports but does not enforce: it blocks neither completing a job nor billing it, and it lives only in the app — a direct write or an offline replay never meets it. Two of its checks — parts logged or none, and crew confirmed — cannot pass yet. Making it a database gate is a later phase
No decline button on a part request — authorizing raises the purchase order, but refusing one is a conversation outside the app today
A PHDC Installation books a 2-hour slot by fallback rather than a longer block — a known defect
The Preventive Maintenance reminder queue computes a due date only; it contacts nobody
A deal closed in Sales cannot be handed to installation yet (see Sales) — the office creates the install job here, in Dispatch
The AHS desk now stamps write-once submitted and authorized timestamps, but nothing reads them back: there is no turnaround or duration report yet. The clock is being kept; nobody is reporting on it
The correction desk has no confirmation step, its reason field is optional, and there is no undo. It writes what you typed, straight into the record — the job history is the only trail back
data: work_orders · work_order_events · ahs_authorization_requests · service_agreementswired to: Realtime · Apple push (built, not live)
A Monday-style pipeline board: nine stages across four phases (Lead → Sales Team → Closing → Scheduling), with the legal stage moves enforced by the database itself. Every deal carries a Slack-style thread where stage changes, assignments, and scheduling log themselves automatically.
Drag-and-drop pipeline; illegal stage jumps refused at the database layer
Per-deal thread with auto-logged events and team messages
AI sales-estimate chatbox grounded on spec catalogs — it can never see costs or markup
Sales reps see only their own portfolio (row-level security, not UI filtering)
Printable customer estimate and signed closeout documents
Send Client Portal sign-up straight from a sold deal — the customer record, project container, and magic-link invite are created in one motion
A contract panel on the deal, clearly marked Under Development by Dev — every contract it produces is a draft labelled not a legal contract
Deal flow
Lead
Sales teamestimate + visits
Closingcustomer signs
Schedulinginstall job booked by the office
Closeout reviewmanager gate
Not built yet — said plainly
A closed deal cannot be handed to installation from Sales today. Send to installation needs a live signed contract and recorded deposits, and no contract wording has been approved yet — so every contract is a draft and the handoff stays blocked. The office creates the install job in Dispatch by hand
QA Sales Pro, the iPad app for sales visits, is in development and not released: it signs in against the office, shows the rep's day, walks a deal through estimate, signature, and deposit, and hands off through the same gate. Deposits are recorded only — there is no payment processor — and the contract and deposit tables it needs are not confirmed in production
data: sales_orders · sales_order_events · sales_estimates · sales_notificationswired to: Claude (sales chat) · Resend (invites & notifications)
Revenue
Estimator
/estimatorOffice T0–T2
A conversational estimate builder run by a four-agent AI team, each in its own colored bubble: Parts Scout extracts the equipment, Price Analyst reports what Quality Air actually paid last (it cannot invent a number), Estimate Builder writes the lines, and Margin Reviewer checks every line against the company's pricing standards.
Chat-built estimates priced from real ingested cost history and HR day rates
Voice dictation — talk the estimate in, with a live level meter
Vendor quote PDF upload: AI reads the quote, you review the extraction, it lands in quoted-price history
Margin & markup as deterministic commands that reprice the whole estimate
Prints to Quality Air's real customer estimate template
The estimator team
Parts Scoutwhat's on the job
Price Analystwhat we last paid
Estimate Builderwrites the lines
Margin Reviewercompany pricing standards
Not built yet — said plainly
The code routes the Estimate Builder to GPT-4o, but production has no OpenAI key, so today the builder falls back to Gemini like the rest of the team. Prices don't depend on the model — they come from cost history and deterministic commands
data: estimates · estimate_line_items · vendor_quoteswired to: Gemini (the whole team, PDF extraction, and voice in production)
Relationships
All Customers & Home Warranty
/customers · /warranty/ahsOffice + Field Manager (customers); office only (warranty)
All Customers is the master directory — mirrored from QuickBooks and extended by the OS — where each customer is a hub holding their properties, equipment, projects, work orders, quotes, invoices, and service agreements. Beside it, the home-warranty ledger: AHS claims keyed to the 8–9-digit dispatch number, with scorecards, budget periods, and a per-customer document cabinet.
Customer hub: every property, unit, visit, and dollar in one place
Directory search hits the database — name, phone, email, property address, equipment — not a 50-row window
Quick intake replaced Add customer (and its AHS warranty customer tick): the office tiers (T0–T2) choose Residential, AHS, PHDC, or ECA and get the same project that database's own Create Project form makes, then land on it. It never creates a work order and has no general contractor option. Residential adopts a returning customer only on an exact phone or email match with a name that agrees, and files new customers in QuickBooks; PHDC and ECA require the agency's job number and open an existing project with that number instead of duplicating it
One project per retail customer: every direct-customer job files into that customer's single Residential project, created at intake if none exists. The customer-only create actions are gone — every customer has a project
Portal invites issued from the customer page (invite-only, magic link)
AHS dispatch number enforced one-per-work-order by the database
The AHS authorization desk in Dispatch splits the waiting: the office submits a request, only the Super Admin approves or denies it, and the return visit re-dispatches the same work order
Warranty scorecards and budget-period tracking per partner
QuickBooks files four books: PHDC and ECA jobs as sub-customers of their agency parent; AHS claims as Jobs of the AHS book; retail as Jobs of QUALITY AIR. The writer finds a DisplayName first and never auto-renames. A PHDC resident is never minted as a retail QUALITY AIR person. City customer pushes not before 3 August 2026; OS customer pushes not before 18 August 2026
Not built yet — said plainly
Quick intake recognizes a returning Residential customer only by an exact phone or email match with a name that agrees. A differently formatted number creates a second record, and on a match only a new street is added — the other details typed are not written onto the existing customer
Quick intake's AHS choice doesn't look for an existing project first, same as the AHS board form it mirrors
Home Warranty has only AHS wired — Add partner says coming soon — and there is no connection to AHS's own portal: claims are tracked here by hand
Three books that keep commercial work honest: the GC contractor book (contract value, retention held, receivables, insurance expirations), the separate municipal cabinets for PHDC and ECA city work, and the project book that rolls every crew visit, document, and purchase order up into cost, margin, and retention per project.
Contractor pipeline with COI/insurance expiry tracking
City contracts — ECA / PHDC in the sidebar, formerly City Contracts — kept structurally separate from GC work. The add-a-program form is hidden now that PHDC and ECA are both set up
City display names compose as job number and resident; the job number is editable on the project without reopening the work order. On PHDC it is labelled Work Order # — PHDC's own number for the job, not Quality Air's internal WO-00000001 number; ECA keeps City job #. Reopen PIN is a personal 4-digit manager PIN, not the job number
PHDC has no Bid, Awarded, or Lost stage: every door that creates a PHDC project starts it at Scheduled, and the server refuses those three stages for PHDC. ECA still starts at Awarded with the full lifecycle
A PHDC project file has no Project detail section — no type, stage editor, contract or cost fields, retention, invoiced/paid, square footage, unit count, or dates to edit there — and its summary cards drop Contract, Margin, and AR outstanding, keeping only the cost cards. Customer & site carries the name, Work Order #, phone, address, and scope; the phone is a Phone: line in the project's notes, required on the PHDC create forms, which also drop type and dollar fields
The PHDC cabinet puts Create Project, the Projects list, and the filing cabinet on the left, and on the right a read-only project preview — stage, Work Order #, customer, phone, address, linked work orders, scope, Open project — that follows whichever row was last hovered, focused, or tapped, above a Profile & compliance panel that starts collapsed. The ECA cabinet keeps its original layout
Per-project rollups: cost, margin, retention, AR
The project container is the customer's truth; the work order is the job's truth — every dollar attaches to both
Container lanes now cover AHS, Residential, and Preventive Maintenance — PM visits file into a container like every other lane
Two project books on a general contractor's page: Projects, carrying contract, invoiced, and paid money; and Un-Started Projects, awarded but with nothing recorded against them yet. A project created inline from intake starts in the un-started book and moves across once money is recorded
Three voices on every project file. Tech notes is a read-only roll-up of what the field wrote, attributed to the technician — there is deliberately no form here, because the office does not speak in the field's voice. Management notes is the staff thread (T0–T3, technicians excluded) where pinned notes lead. The Developer's note is written by the Super Admin and read by staff: why this record looks the way it does. A database trigger stops office staff editing a technician's note — with narrow exceptions: the owner's (T0) correction desk, a management close-out (which adds a line marked as from management), and a technician newly made the job's lead
The same three note surfaces sit on the assembly workbench, so an imported record carries its explanation with it
Super-admin project delete: T0 alone, and it refuses any project still carrying work orders, invoices, vendor bills, journal lines, estimates, or documents. When it does go, it is permanent and not recoverable
Not built yet — said plainly
Preventive Maintenance visits generate daily from service agreements, but nothing bills them yet: dedicated PM billing is not built
Notes are append-only by convention, not by construction: the app simply offers no edit control, and only the Super Admin gets a Delete button. The database still allows any staff row to edit or delete a note through the API, so "a correction is a new note" is a house rule the screen enforces, not a guarantee the data layer makes
The T0-only rule on project delete is enforced in the app, not in the database. And deleting a project takes its notes with it — the explanation goes when the record does
Finance is Quality Air's own double-entry general ledger — a 56-account HVAC chart, an immutable journal where mistakes are corrected by reversal rather than edit, and P&L, balance sheet, trial balance, and cash flow drawn from our own book. QuickBooks is downstream: kept fed until it can be retired, with a readiness panel that says how close that is. Outbound money is customer invoices priced at company standards ($125/$165 service calls, free estimates), now organised by the database the job belongs to. Inbound is supplier bills read out of Gmail by AI — and since 30 July they are set up to post to QuickBooks on their own rather than waiting for a person to approve each one. An administrator can pause that with a server setting (it isn't a button in the app); while it's paused, bills wait to be recorded by hand.
Billing by database (since 22 Sep): customer invoices filter by All, Residential, PHDC, ECA, AHS, or Other/unassigned, each with a count; Residential splits Service & installation from Preventative maintenance. Tiles for To prepare, Awaiting payment, and Paid; vendor bills live on their own page
Invoice numbers start at 7000, clear of QuickBooks' own run (which ended at i5330). A number is assigned once, when the invoice first goes to QuickBooks, and never reused — until then the invoice shows a provisional INV-xxxxxxxx label
Send to QuickBooks is a button on an approved invoice. Mark sent changes the status only — no email goes out. Payments (card, check, cash, ACH, financing, other) are recorded here
Supplier bills are set up to post to QuickBooks automatically as they arrive, with a retry sweep every four hours: Gmail ingest → PDF archived → Gemini reads the lines → the bill posts. Sales tax lands as its own line, freight as Freight In, discounts itemised. A bill from an unmatched vendor or with a zero total is held back
An administrator can pause that with a server setting (it isn't a button in the app); while it's paused, the Vendor bills page shows a banner reading Automatic recording in QuickBooks is paused…, rows show a Recording paused chip, and bills wait to be recorded by hand
Automatic ledger posting: approved invoices, customer payments, supplier bills, and supplier-bill payments each reach the ledger automatically, at the latest in the daily finance run
The Approval Gate: agent-prepared actions (collections drafts and the like) wait in a queue for an authorized person — enforced in the database
Period and fiscal-year close with locks — a closed period refuses new entries
A/R aging that trusts QuickBooks's own balances and excludes settled invoices, + A/P aging
Bank statement import (CSV/OFX) with coding rules and reconciliation
Job profitability per work order; P&L by job type and period — two P&Ls exist on purpose: one read from the QuickBooks mirror, one from our own ledger
PA/Philadelphia sales-tax liability accounting; fixed assets with straight-line depreciation
Journal-entry push to QuickBooks, per-entry or bulk — a human button, gated on full account mapping and a company guard that is armed in production
The old QuickBooks mirror screens remain as the tie-out comparison; the mirror refreshes every 3 hours, with a heartbeat check on the same beat
Full transaction explorer with saved views
Vendor directory with every original invoice PDF archived (read-only — no create or edit forms)
City jobs mint a counterpart invoice when the technician completes the visit — they are no longer kept off that path
PHDC invoices pick from the HIPPO catalog only: official unit price, quantity editable, generate-from-logged-work hidden. Retail, AHS, and ECA stay off that pairing
A supplier bill's path
Gmailinvoice PDF arrives
AI parseGemini reads lines
Vendor billtax, freight, discount lines
QuickBooksposts on its own · every 4 h
Our ledgerdaily posting run
Not built yet — said plainly
Invoices carrying sales tax are refused by the QuickBooks push, and recorded payments are not pushed to QuickBooks at all
Mark sent does not email the customer — invoices are delivered outside the app
Dedicated Preventive Maintenance billing is not built; the PM filter only separates the invoices that exist
The daily finance run posts pending journal entries 500 at a time, so historical totals can still be catching up
Reconcile tidies local records only — it writes nothing to QuickBooks
AHS jobs bill $0. An AHS work order's invoice is raised at zero and stays there — skipping the $125/$165 service-call fee is correct (AHS pays the claim, not the homeowner), but nothing copies the authorized claim amount onto the invoice, and the generate-from-logged-work automation deliberately refuses to run on AHS invoices. Customer upcharge has the same gap. Someone has to add the lines by hand
That $0 then propagates: the ledger skips a zero invoice, so an AHS job produces no journal entry and never reaches the statements or the QuickBooks push — and because the unposted-work summary also filters out $0 invoices, the missing revenue isn't flagged as missing either. The authorized amount itself is real and tracked; it drives Finance → AHS Control and its budget-band metrics. It just never becomes revenue
No posting engine yet for payroll, credit memos, or AHS claims — those take hand journal entries today
/warehouse (+ purchasing) · /vehicles · /pricebookOffice (vehicles also Field Manager)
Physical stock across the warehouse and every van, with technician replenishment requests and transfers. Purchasing runs the purchase-order queue — draft to issued to received — born from authorized field part requests. The truck roster gives each vehicle its maintenance history, fuel log, insurance policy link, and cost-per-mile. And seven price books — the company flat-rate catalog, the live PHDC HIPPO catalog (888 specs; PHDC invoices pick from it), the R.E. Michel catalog, and four books of real purchase history read out of supplier invoices to the penny — plus four manufacturer spec catalogs beside them.
Warehouse + van stock, transfers, counts, reorder points
Purchasing: the PO queue from draft → issued → received, with the open commitment visible; vendor by link or free text — and honestly, Issue to vendor records the state, it does not email the vendor or push anything to QuickBooks. There is no blank New PO: every PO starts from an authorized part request
Dollar backlog: parts read off supplier invoices, drawn down onto jobs
Truck check-ins, maintenance programs, insurance linked to real policies; fuel-card statements import as CSV. There is no GPS or telematics
SupplyHouse history to 2019, TOSOT, DN Supply counter tickets, Associated Refrigeration (586 invoices, 2024–2026) — actual paid prices — beside the R.E. Michel catalog
PHDC HIPPO catalog: 888 specs across 16 categories, scraped 18 August 2026 from the live contractor portal — not the printed 2025 PDF. PHDC revises rates without reissuing a book, so re-scrape before a large job. PHDC invoices attach those specs; the book is no longer reference-only on the bill
/hr (+ employee pages)Admin only (T0/T1) — holds pay and personal data; the Office Manager (T2) can't open it
The employee book: profiles, day rates, document cabinets, a company-history timeline on every file, and each person's training record. The careers pipeline receives applications from the public website and emails a level-matched knowledge exam about half an hour later — graded server-side, one submission per application, the applicant never sees the score — landing results in an applications queue for review.
Employee directory with pay data gated at the database layer, not just the UI — only the Super Admin (T0) can change a day rate
Field role (technician, laborer, field manager, 1099 contractor) is stored apart from the access tier and decides who owes the daily truck check-in — laborers don't pick a truck and can't lead a job. Changing it directly is T0-only in the database, but T1 and T2 can still change it through the HR employee forms (T2 only for non-management roles)
Subcontractor vendor records: trade, COI, license, rates by work stream
Careers: application → level-matched exam emailed ~30 min later (no timer on the exam itself) → graded server-side into the queue
All-tier employee intake — one door for hiring every role from laborer to sales manager, with privileged roles gated to admins
Employee dashboards show exam, training, and lab results together
Built like a safety document, because it is one. Course material is drafted by an AI author that may only draw on approved sources and refuses safety topics outright, deferring to a qualified human. Everything passes three independent review gates enforced in the database: an author cannot review their own work, an approval is bound to the exact words it was given, published material is frozen, and history cannot be edited — even by the system itself. Honestly told: the gates are built, but publishing a course to learners is not wired yet.
AI course authoring bound to licensed/public sources only
Three independent, database-enforced review gates before release
Learner hub at the training address with the interactive 24V controls lab — wire it, energize it, meter it. Every reading is computed on the server, so the page never holds the answer
The lab refuses to let you move a wire on a live circuit — that reflex is the training
A lab can never record itself as permission to do real work — that field is pinned shut
Material's path to a learner
Approved sources
AI authorrefuses safety topics
Gate 1 · 2 · 3independent reviews
Frozen publishgate built · not wired yet
Learner hubcourses + lab
Not built yet — said plainly
Course publishing is not wired: material can pass the review gates, but no course reaches learners through them yet
Only the 24V Controls lab is live; the Airflow and Split-System labs are in the production queue
Practice attempts write rows only when a published lab spec exists. Scored-evidence recording is deliberately still closed until its own tests pass — the lab coaches, it cannot yet manufacture evidence about anyone. The credential counters read zero because nothing issues credentials yet
Lab Builder and Video Lesson Builder in the studio are screens without working back ends yet
data: training_courses · training_course_versions · training_reviews · training_lab_resultswired to: Claude (curriculum author)
Field
Field App
technician host — /jobs · /van · /truck · /guide · /teamTechnicians T4B/T5, Field Manager T4A (T0/T1 also get the field-manager view)
The technician's whole day in a phone-first native app — a Capacitor shell, not a PWA. The iPhone app, Quality Air Field Technician, is on the App Store at version 1.3; Android installs through Google Play closed testing (invited testers) or the direct APK from the technician address. One phone column at every width, behind its own download cover. Assigned jobs with routing and contact buttons, daily truck check-in, one-tap arrival, camera photos, part requests in the tech's own words, and a closeout that captures the customer's signature plus a 10–30 second walkthrough video recorded in the app. A browser tab cannot record the video. The app's Help tab carries its own eleven field-only guides.
Native app only: iPhone from the App Store (1.3), Android from Google Play closed testing or the APK at the technician address. A browser tab and Add to Home Screen are not a field surface; the PWA is retired
One active job at a time: starting a visit claims it for the lead and the crew, and none of them can start another until it is completed or handed over with Technician Complete — a paused job still counts as active. Tapping En route always needs signal and a synced outbox
Offline, within limits: notes, photos, and closeout queue in a basement and sync on reconnect, with a solid-red Offline chip and a keep-working banner. Opening any screen needs signal — the app loads the live site and keeps no page cache, so even a screen opened earlier won't reload offline — and tapping En route always needs signal and a synced outbox
Daily check-in: one truck pick (A1/B1/C1) — or Used personal vehicle — at the top of My Jobs each morning; jobs can't move forward without it, the database enforces it, and every job start auto-records the day's truck. Laborers are exempt and can't lead a job
Arriving is starting: one tap moves the job to In Progress, unlocks notes, parts, and photos, and stamps arrival and start together
Photos straight from the camera, several per job, without duplicate uploads
Part is needed: the tech describes the part in their own words and keeps the job to finish the visit — completing it moves the job to Needs Authorization, no invoice is raised, and the office decides
Crew jobs: a technician added as crew sees that job read-only beside their own
Truck tab: weekly check-in (odometer, fuel, condition — the only mileage collected) plus fault reports
Job detail: route, call, text, notes, photos, equipment, parts — cost is hidden; techs never see prices
Closeout: notes always; for non-estimate jobs, parts-or-none, the 10–30 second video, and a signature or a reason there isn't one; a photo for installs, maintenance, and cleaning; AHS jobs add nameplate, model, and serial. Clips archive to Google Drive before the 90-day reclaim
If an admin closes a job the tech still holds, the tech sees a Closed for you by management notice
Tech notes of three characters are enough; the database stops office staff editing them (the owner's correction desk, a management close-out line, and a newly made lead are the exceptions)
Van stock view with one-tap replenishment requests — the parts picker searches by part number, not just by name
Crew/Me toggle and a per-technician page — current job, stats, van stock
Field managers get the crew day board
Password invites and resets open a set-password page, and recovery works from the phone
Not built yet — said plainly
Job alerts are built but not live: the iPhone version with push (1.5) is not released, and Android has no push credentials configured
The download page still says the iPhone app is awaiting Apple, although 1.3 is released — a configuration slip
data: work_orders · work_order_crew · work_order_signatures · job_photos · stock_requestswired to: Google Drive (closeout-video archive) · Apple push (built, not live)
Customers
Client Portal
clientlogin host — /portalInvited customers only (T6), magic-link sign-in
A private, read-only window onto the customer's own project: plain-language status, the visit timeline, photos and documents — shown only once the office marks them visible. The database itself guarantees one customer can never see another's work. The single write path is submitting a service request.
Invite-only by standing rule — no self-signup exists
Office controls visibility of every photo and document
Service-request submission — the portal's one write path. Requests land on the Dispatch → Portal requests board, where the office acknowledges, turns one into a work order or links it to one, schedules, or closes it; the customer's status chip follows the actual booking automatically
Not built yet — said plainly
No invoices, payments, or self-booking in the portal — a customer can ask for service but not pay or pick a slot
Where years of imported QuickBooks history get compiled into the operating record. The reconciliation gate stages imported customers, invoices, and projects, matches them, and publishes to the main system. The assembly workbench then mints work orders from historic invoices — a queue, a project cockpit, and an evidence tray — so every dollar ever earned lands on the visit that earned it.
Three matching gates connect staged QuickBooks data before anything goes live
Mint work orders from historical invoices with evidence attached
PHDC / ECA agency pipeline boards
Ongoing AHS work-order backfill enriches the record job by job
The Admin (Owner) can now read the workbench: the whole screen renders, the controls are disabled, and a "Read-only — viewing as owner" badge says why. Writing it is still the Super Admin's alone — all twelve of its actions check that on the server. T2 and below are still turned away at the door
The three project note surfaces — tech, management, developer — sit on the workbench too, so an imported record carries its explanation
A roster of fourteen named background agents — billing prep, communications, routing, inventory, marketing and more — governed by one principle enforced in the database: automation prepares, a person approves. The roster is a fixed display list, and the page itself labels its activity as demo. The automation that actually runs today: the maintenance crew, which inspects the data every morning, auto-fixes what is safe, and escalates the rest to the Activity Rail; the QA Concierge, which interviews website visitors and files enquiries on its own; the estimator team; the Gmail vendor-bill ingest; and the daily finance run (early morning) — Controller, Bookkeeper, and Collections — with a CFO analyst you can ask on demand.
Scheduled jobs: QuickBooks sync and a QuickBooks heartbeat every 3 hours (the sync is time-budgeted and resumable — it carries unfinished work into the next run); supplier-bill push and customer push every 4 hours; PHDC item sync every 2 hours; daily maintenance scan, PM-visit generation, Gmail vendor-bill ingest, closeout-video archive to Drive and the matching storage clean-up; careers exams every 10 minutes; and a technician-alerts worker every minute that stands idle while alerts are switched off
Daily finance run, before office hours: posts pending journal entries (500 a run), then the team works — the Controller runs deterministic checks with no AI model at all, the Bookkeeper (Gemini in production) suggests bank codings but never posts, and Collections drafts dunning into the approval queue and sends nothing. The CFO analyst (Claude) is not part of that run; it answers questions on demand over deterministic report calls
Hermes — the read-only staff assistant that knows the business, grounded on the live database and company Drive
Approval Gate on every agent action that would touch the real world
Not built yet — said plainly
Most of the fourteen roster entries still await their release wave — the workers running live today (maintenance crew, concierge, estimator, finance run) grew up beside that plan, not out of it
RingCentral is connected for read-only account discovery only; no calls or messages flow through it yet (planned as the CSR agent's channel)
Several operator jobs have no schedule and run only by hand — PHDC invoice refresh, QuickBooks bill repair, freight scan, charge backfill, and the Gmail backlog
data: agent_activity · approval_queuewired to: QuickBooks · Gmail · Google Drive · Resend
Governance
System, Help & Governance
/system (+ imports, sops) · /help · /departmentsSystem: admin (Team & Access T0 only). Help: every desktop tier — T0–T3, Sales T7/T8, CSR T9 — plus the Field Manager T4A (techs get their own Help tab in the field app)
Team & Access is where the Super Admin (T0) grants tiers — the same ladder the database enforces; not even the owner's T1 seat can open it. Integrations health shows Gmail and QuickBooks status with one-click reconnect. The Help Center is the in-app operating manual: tier-filtered guides for every module, with a CI test that fails the build if a module ships without documentation.
User & tier administration with an audit trail — T0 only
Invite and password-reset emails open a set-password page, so a new person always chooses a password instead of being signed straight in
Integration health + reconnect without a developer
Import Conflicts: jobs pulled from the old dispatch system stage in a conflict queue instead of being trusted — a match ladder (dispatch id → AHS # → PHDC # → address+date), side-by-side review with conflict chips, and the office ticks which facts to take. Matched rows still only enrich what is already there
An unmatched import row can now become a work order: pick the board it belongs on, optionally confirm creating a new customer, and the queue resolves the customer by address, then email, then name plus postal code — never on a name alone. It can create the customer, the property, an AHS claim for AHS jobs, and the city-project link in the same motion
Every entity picker in the system is a type-ahead — 61 of them, from the customer field to the account to the part. Short fixed lists (job type, status) stay plain dropdowns on purpose. A stored value that has fallen off the list now reads "Set — no longer on this list" instead of showing you an empty box
Sales SOPs: six read-only playbooks (growth roadmap → compliance) rendered from version-controlled documents — readable by admins, the office manager, and the whole sales division
Not built yet — said plainly
System → Audit Logs screen not built yet
Import Conflicts admits only T0/T1 today — T2 admission is a known gap. There is still no in-app "pull from Dispatch" button either: the rows have to arrive before the queue can settle them
A type-ahead on most pickers filters what the screen already loaded, in the browser — it is not a search of every record in the database. Some screens cap that list (intake loads 200 customers), so a name outside the loaded set will not appear no matter how you spell it. The Customers directory search box is the exception: it queries the database
Marketing module is a placeholder shell — every figure reads a dash; real lead handling lives in Dispatch → Website leads
From a baseline app to a connected command system with a live data spine and an automation layer. Jun 5 → Sep 23 · 636 commits through 23 Sep 2026, on 53 days with commits.
Jun 5–6
Foundation
The live app and its core: dispatch board, sales, contractor projects, customers, and the role-aware shell.
Jun 23
Roles + Help Center
Tiered access (office, staff, field) and the in-app Help Center with contextual guides and a coverage test that keeps documentation in lockstep with the build.
Jun 24–25
Costing, Drive & the QuickBooks pipeline
Technician day-rate labor costing, Google Drive document sync, work-order numbers and crew rates, and the vendor-bill → QuickBooks groundwork.
Jun 26
The data spine — 53 ships in one day
QuickBooks connected read-only (3,000+ customers, the full ledger), the reconciliation gate, the AHS lane, smart fuzzy search, and Hermes — the read-only assistant that knows the business.
Jun 27
Automation & reliability
A background maintenance crew that inspects the data, auto-fixes safe issues, and escalates the rest to the Activity Rail.
Jul 2–3
The assembly workbench & real rates
Every dollar QuickBooks imported now gets compiled into the visit that earned it. Quality Air's real pricing standards went in behind it — $125 residential and $165 commercial service calls, free estimates, parts at cost ×2.5 — plus a Return Call type that charges the customer nothing. Dark mode landed the same day.
Jul 6–7
Trucks, supplier bills & the money loop
Each truck grew its maintenance history and insurance link. Supplier invoices ran a two-step approval into QuickBooks, folding true cost into each job's margin — an approval step retired on 30 July, when bills began posting on their own. An integrations screen shows Gmail and QuickBooks health.
Jul 10
The clock comes to dispatch
A real day timeline — 8am to 6pm by technician row, jobs booked into slots sized by the work. New projects file themselves into the right lane automatically.
Jul 15
Website leads & the full schedule
Website enquiries land in a triage queue — the office promotes the real ones and bots never reach dispatch. The board gained a month load grid showing every stream at once.
Jul 17–18
The client portal & a signed close-out
Customers can be invited to a private, read-only portal that follows their own project. Technicians close jobs through a checklist that captures a signature on the glass and works with no signal. Both surfaces got their own web addresses.
Jul 19
Vendor intelligence — years of purchasing, priced
The pricebook grew from three books to six: SupplyHouse orders back to 2019 at the price actually paid, TOSOT equipment, DN Supply counter tickets read line by line. 200+ historical vendor bills archived with their original PDFs. The estimator team went live the same day.
Jul 20
Training — built like a safety document
A governed training platform where AI-drafted material must pass three independent, database-enforced review gates; a working interactive 24V lab that refuses unsafe moves; and rules that hold even against the system itself — an author cannot review their own work, and an approval is bound to the exact words it was given. Release and evidence recording were left deliberately closed until their own tests pass. The same day, walkthrough videos landed on the dashboard and the estimator.
Jul 22–23
The global board, exact money & a lab that can't be cheated
Dispatch and the dashboard gained the Global Board — every department's schedule on one read-only calendar in the animated brand frame, with click-to-preview on any job. The estimator learned margin and markup as deterministic commands, exact-cents precision, and voice dictation with a live level meter. The pricebook grew its seventh book, Associated Refrigeration — 586 real invoices covering 2024 through 2026 — beside new searchable spec catalogs for Goodman, Bryant, Lennox, and Williamson. And the training lab was rebuilt server-authoritative: every meter reading is computed on the server against a hidden fault, so the browser never holds the answer.
Jul 24
The sales division
Three new roles joined the ladder — Sales Manager, Sales Team, and CSR — with a nine-stage pipeline board whose stage moves the database enforces, per-deal threads, an AI sales chatbox that never sees costs, and a printable signed closeout. Reps see only their own portfolio; the rule lives in the database, not the interface.
Jul 24
Careers, quotes & five front doors
The careers pipeline went live: an application from the website triggers a level-matched knowledge exam, emailed about half an hour later and graded server-side into an HR queue — applicants never see the answer key or their score. Employee files gained a company-history timeline. The estimator learned to read vendor quote PDFs into quoted-price history. The client portal became a small app of its own — home, visits, equipment, service requests, account — so customers can ask for service onto the office's board. And the system's fifth web address went up: this page, the About OS, the living blueprint of everything here.
Jul 24
The concierge takes the front door
The QA Concierge replaced the website's contact form: an AI assistant that interviews the visitor, then files the enquiry itself — sales enquiries become Lead-stage deals in the pipeline with the transcript attached and the sales managers notified; service enquiries wait in the triage queue for a person. A finished conversation is never dropped, even when the AI cannot classify it. The same day, six sales SOPs — growth roadmap through Philadelphia compliance — went in as read-only, version-controlled playbooks under System.
Jul 25
Our own books
Finance became Quality Air's own double-entry general ledger: a 56-account HVAC chart, an immutable journal corrected only by reversal, period close with locks, bank import and reconciliation, job profitability, and financial statements drawn from our own book. QuickBooks moved downstream — kept fed by a human-button push until it can be retired. Honestly told: the historical catch-up is still running, and payroll, credit memos, and AHS claims still post by hand.
Jul 26
The field takes command
The technician app got its own front door, a truck gate (pick A1, B1, or C1 before starting — the database insists), and one-tap arrival that starts the job. The office owns a job until the tech taps En route, then the booking freezes. A part request in the tech's own words now runs Needs Authorization → purchase order in Warehouse Purchasing. The work order became a desk — pipeline rail, five tabs, advisory verification — Dispatch gained the ECA board and the Company Wide Schedule, and old dispatch.me pulls now settle in an Import Conflicts queue instead of being trusted.
Jul 27
Every list searches, and the day is eight hours
Every picker in the system became a type-ahead — two letters find the address, the part number, or the account, in any order. City work orders can file their own project from the picker or the board. The dispatch day is 8 AM to 4 PM, enforced on the server rather than only in the dropdown, and a job dragged onto a technician’s row books the slot and names the lead in one motion.
Jul 27
The record learns to explain itself
A project file grew three voices: the field's notes rolled up read-only and attributed, a management thread where pinned notes lead, and a developer's note saying why this record looks the way it does — with the database itself refusing office staff edits to what a technician wrote. The AHS board became an eight-lane authorization desk that separates a job waiting on us from one waiting on AHS. The imports queue stopped only reconciling and learned to create the work order, the customer, the property, and the claim. A super-admin correction desk went on the work order for straightening out imported rows — no confirmation, no undo, every change in the job history. Alongside them: a week view on every board, an 8 AM–4 PM day, a drag that actually moves the job, a type-ahead on every picker, and two project books on a contractor's page — the work in play, and the work merely awarded.
Jul 30 – Aug 3
Supplier bills post themselves
The approval step came out of the supplier-bill path: a bill read out of Gmail is now set up to post to QuickBooks on its own, with a four-hour retry sweep, and an administrator can pause that with a server setting (not a button in the app), leaving bills to be recorded by hand. Bills from an unmatched vendor or with a zero total are still held. Within days the parser stopped lumping everything into one remainder — sales tax lands as its own line, freight as Freight In, discounts itemised — and the push stopped depending on Gmail's health.
Jul 30 – Aug 7
The field becomes a real app
The technician surface left the browser. A Capacitor Android app — download the APK from the technician address — replaced Chrome and Add to Home Screen; the PWA was later retired because it cannot record the closeout video. Daily truck check-in sits at the top of My Jobs. Close-out is a signature plus a 10–30 second walkthrough recorded in the app; clips archive to Google Drive before the 90-day reclaim. Cost left the technician screen. Tech notes of three characters are enough, and office staff still cannot edit them.
Aug 3–18
Four QuickBooks books, and city jobs that can be billed
QuickBooks customers stopped being invented. PHDC and ECA jobs file as sub-customers of their agency parent; AHS claims as Jobs of the AHS book; retail as Jobs of QUALITY AIR. The writer finds a DisplayName first and never auto-renames. A PHDC resident is never minted as a retail QUALITY AIR person. City jobs show as job number and resident. Completing a city job in the field mints a counterpart invoice and keeps the card on the PHDC or ECA board so the office can price it. Customer directory search hits the database, not a 50-row window.
Aug 18–19
PHDC prices the invoice
The PHDC price book was rebuilt from the live HIPPO contractor portal — 888 specs across 16 categories, scraped 18 August 2026 — because PHDC revises rates without reissuing a PDF. PHDC invoices now pick from that book and only that book: official unit price, quantity editable, generate-from-logged-work hidden. Retail, AHS, and ECA stay off that path. The work-order desk gained an Invoice jump to the counterpart bill. Honesty still: AHS invoices raise at $0, and nothing copies the authorized claim onto the bill.
Aug 19–24
Real invoice numbers, recents, and a management close
Every direct-customer job started filing into a project container at intake. Invoices got real numbers — starting at 7000, clear of QuickBooks' own run, assigned once when the invoice first goes to QuickBooks and never reused. Search learned recents: before you type, it shows the work orders, invoices, customers, projects, and vendor bills you opened lately, with a live drop-down as you type. A T0/T1 admin can now close a job a technician is still holding, with written notes, and the tech is told who closed it and why. Customers became All Customers in the sidebar, the field app got a public privacy policy, and the three-hourly QuickBooks sync learned to checkpoint and say where it stopped.
Sep 3
Field app 1.3, and a Sales Pro prototype
The technician app reached version 1.3 — a closeout-video gate, outbox ordering fixes, and a real release build — and the technician landing page began pointing people to the app stores. A first prototype of QA Sales Pro, an iPad app for sales visits, went up for internal testing beside it.
Sep 10
ECA / PHDC, and PHDC gets its own shape
City Contracts became ECA / PHDC in the sidebar, and the add-a-program form left the page now that both programs are set up. PHDC stopped pretending to bid: its stages run Scheduled through Paid, every door starts a new PHDC file at Scheduled, and the server refuses Bid, Awarded, or Lost for it. PHDC's job number reads Work Order # — PHDC's own number, not our WO-00000001 — everywhere PHDC shows it: board cards, cabinet rows, stat cards, and search boxes no longer say ID or identifier. A PHDC project file dropped its Project detail section; Customer & site carries the Work Order #, a phone, the address, and the scope, and the PHDC create forms require the phone. The PHDC cabinet puts the work on the left and, on the right, a project preview that follows whichever row you hover, focus, or tap, above a Profile & compliance panel that now starts collapsed. ECA is unchanged.
Sep 10
One intake, four databases
Quick intake replaced Add customer on All Customers, and the AHS warranty customer tick went with it. The office tiers choose Residential, AHS, PHDC, or ECA, fill in only what that database's own Create Project form asks for, and land on the new project — the same project that form makes. Residential matches a returning customer on exact phone, then email, when the name agrees too, and opens their one Residential container; PHDC starts at Scheduled with its Work Order # and phone required; ECA requires its job # and starts at Awarded, as does AHS. PHDC and ECA open an existing project with the same job number instead of filing a twin. It never creates a work order, and general contractor projects still start from Contractors. The Dashboard gained a Website Leads card with the same waiting count as the Dispatch badge. Honesty still: the phone or email match is exact, and the AHS choice doesn't check for an existing project first.
Sep 10–14
The iPhone app, one project per customer, and a password of your own
The field app got its iPhone build and an App Store listing — Quality Air Field Technician — and a public support page for both stores; iPhone version 1.3 is released there. Every customer must now have a project: the customer-only create actions came out. Invite and password-reset emails stopped signing people straight in and now open a set-password page. QA Sales Pro grew its first real slice — sign-in, My Day, a deal-bound flow, signature, deposits, and a handoff gate — and the web deal gained a contract panel. Honestly told: that panel is marked Under Development by Dev, no contract wording is approved, every contract is a draft, so a closed deal still cannot be handed to installation, and the iPad app is not released.
Sep 21–23
Service types, crews, and billing by database
PHDC work orders now carry a required type — Assessment, Installation, Service Repair, or Service Call — shown as a badge, filterable on the PHDC board, and editable by the office until the field starts. Every board card and the schedule preview lead with the service type, and the card opens with an Open button. The PHDC and ECA boards gained an amber Action required panel counting completed jobs waiting on billing. The schedule preview gained a Crew panel so the office can add or remove helpers on an existing job; crew see it read-only in the field app. Technicians can shoot photos straight from the camera, several per job. The field app now allows one active job at a time, and laborers no longer owe a truck check-in. Job alerts were built — booking, rescheduling, crew changes, and evening reminders — but are not live: the iPhone version that carries them (1.5) is not released and Android has no push credentials. Billing was reorganised by database — Residential, PHDC, ECA, AHS, Other — with vendor bills on their own page. On 23 September the office console moved to office.qualityairhvac.com, with the old admin address kept as an alias, and the field app got its own Help tab of field-only guides.