Platform
The AI proposes.
A permissioned layer decides.
The model in MATRiQ has no tools and cannot act. It reads, and it returns validated JSON. That output is stored as a reviewable proposal — then a deterministic, permissioned layer decides whether anything gets written.
Which is why an estimator can hand it their inbox.
- AI capabilities
- 4
- Files that may call a model
- 2
- Tools the model holds
- none
01 — AI estimate intake
Forward the email. Get a parked estimate.
An estimator forwards an inbound quote request to a dedicated address, or drops a PDF, an image, an .eml or a text file. It comes back as a structured quote request: the client company, the contact, the project with a parsed street address, and one entry per requested line item — material phrase, direction, the raw quantity text, the best numeric parse, the unit, and the exact source snippet it came from.
- Capture, then judge. Every requested item in the source becomes exactly one entry. Confidence changes how a line is labelled, never whether it exists — a missing line is invisible to the reviewer and the worst possible failure.
- A malformed quantity is parsed and flagged, never silently normalised
- A material is either the exact name from your own sellable catalog or left empty and marked unidentified — never invented
- Attachments and links it didn't read are listed as ignored, not quietly skipped
- The raw email is stored before a token is spent, so a failed read still shows the email and can be re-run in place
- Extracted parties are scored against your CRM on email, phone, domain and address — and only auto-selected above a threshold
Intake
- Upload cap
- 20 MB
- Accepted
- PDF · image · .eml · text
- Auto-match threshold
- 0.82
- Exact contact email
- 0.98
- Project street address
- 0.95
- Phone · domain
- 0.90 · 0.85
- Parked draft lives
- 15 days
- Discard reasons
- 5
02 — The review gate
Nothing reaches the CRM until an estimator presses Finish.
The estimator sees the email beside the reading, resolves four rows of the who-chain — client, location, contact, project — by linking an existing record or creating one, fixes the lines, and finishes. That press is the only moment anything is written.
- A line's material and unit come from pick-lists only — canonical units and your own sellable items. Never free text.
- Finish refuses a draft that isn't awaiting review, or one with nothing parsed
- Merging into an estimate somebody already priced is refused — a rule about the data, not the route
- On finish the estimate is renumbered, flipped to draft, and every line is run through the real Smart Select engine, landing marked pending for the estimator's final pick
- Discard is never a delete. The email and the reading stay, the reason is recorded, and it's reversible
- Expired and discarded are deliberately different states: one is a backlog problem, the other is a reading worth learning from
The who-chain
- Rows to resolve
- 4
- Client · location
- link or create
- Contact · project
- link or create
- Writes before Finish
- none
03 — Every AI capability, listed
Four capabilities. One gateway. No tools.
16,000 token cap
schema-constrained
never overwrites
every 5 min · 20 rows
named document
extract, never invent
every 10 min · 15 codes
converges, then idles
04 — Records both halves share
A hauler you set up once is the same hauler everywhere.
One entity record carries three independent roles — client, vendor, hauler — so the same company can be all three without being duplicated. Locations hang off the entity, and the location is what carries the address, the map pin and the products.
- Entity types are one vocabulary shared across tenants, so a tag means the same thing everywhere
- Soft delete throughout — records leave the list, not the history
- Compliance is derived, not typed. COI and W-9 status comes from the document plus the date; what a person enters is a judgement, stamped with who and when. There is no status dropdown.
- A demand-side pipeline sits over the same records, with deals keyed on the estimate
- The hand-off from estimating into CRM is gated on the right to approve the estimate, not on a CRM permission
- Two catalogs, deliberately separate: the materials product catalog and the construction cost database are different licences
Shape of the data
- Prisma models
- 192
- Enums
- 40
- Applied migrations
- 228
- API controllers
- 81
- Application routes
- 161
05 — Permissions & provisioning
One key per module and verb. Fifteen things you can sell separately.
Permissions are atomic keys — a module and a verb — granted through role templates and enforced by a route decorator. Modules live under feature sets that are independently sellable and grantable per tenant, and enabling or disabling one is an audited act.
- Five verbs: view, edit, approve, configure, delete. "Can use it" and "can configure it" are separable.
- Eleven role templates, from Administrator and Chief Estimator through Dispatcher and Billing Clerk to Viewer
- Bid management is its own set, so a company can own construction estimating without it — or the reverse
- The materials catalog and the construction cost database are separate sets, so different people can be granted each
- Trades is its own side, so a trade contractor can own it without the GC line
- Documents is a platform module, so a tenant on the aggregates line alone still gets it
- A dispatcher cannot clear their own dispatch block. Clearing a sales order is an administrator action.
RBAC
- Verbs
- 5
- Tenant modules
- 14
- Permission keys
- 75
- Role templates
- 11
- Feature sets
- 15
- Feature groups
- 5
06 — Alerts & the record
A bell you don't mute.
One estimate on the sandbox got opened thirty times. Thirty alerts and the system is muted within a week — so every raise names the thing that happened once, and a unique index refuses the second. Nine kinds, no repeats.
- A quote request arrived, a read failed, a draft is about to expire, a client opened or downloaded, a quote has gone quiet, a quote is about to expire
- Silence is an event: seven days after a send with no open, you hear about it
- Three days before the validity date, once, never repeated
- Alerts clear when the thing they point at goes away — a bell that still says a request is waiting after it was binned is worse than no bell
- Who approved, who sent, who finalised, who cleared, who held — stamped on the record itself
- Role changes, feature provisioning and user administration write their own audit rows
Thresholds
- Alert kinds
- 9
- Silent after a send
- 7 days
- Expiry warning
- 3 days
- Repeats
- none