Roofing · AI automation
Roofing leads that know an emergency when they read one
Web leads sit in one inbox and get answered in the order they arrived. In a storm week, the leaking ceiling waits behind the gutter quote.
Every roofing lead is read for urgency, matched to a job, scored with its reasons and routed to a crew, with each step logged.
This is a concept build. Ridgewell Roofing is a fictional business. The code is real: open the demo and try the steps below.
The everyday problem
Every lead is read, scored with its reasons and routed in seconds.
The hard part
- An emergency typed casually
A phrase may carry up to two filler words, so 'water IS pouring' still matches 'water pouring'.
- 'Roof' appears in every roofing service
Every service is scored. The longest match wins, and declared keywords beat words guessed from a name.
- A score nobody can explain
The 0-100 score lists a written reason for every point it adds or takes away.
- Every crew already full
The lead is held in the office queue with its score, not dropped.
- Two people book one window at once
A unique index lets only one booking win. The other visitor is asked to pick again, and their lead is kept.
How it runs
How a roofing lead moves from message to crew board.
Sample run- Step 1: Lead arrives. Booking form or a finished chat.
- Step 2: Read urgency. The company's own emergency words; up to two filler words allowed.If this fails: No emergency words: routine, still scored.
- Step 3: Match the service. Longest match wins; declared keywords first.If this fails: No match: lead kept for the office to sort.
- Step 4: Score 0-100. A reason for every point added or taken away.
- Step 5: Pick a crew. Right skill and ZIP preferred; the least loaded wins.If this fails: Nobody free: held in the office queue.
- Step 6: Hold the window. Booking form only; protected by a database unique index.If this fails: Window just taken: visitor picks another, lead kept.
- Step 7: Office crew board. The intake steps in the audit log.
Tap “On fail” to see what happens when a step breaks.
Edge cases we handled
| When | What the system does | Try it |
|---|---|---|
| A customer writes 'water IS pouring through the ceiling'. | Read as an emergency. The chat skips the time-slot step. | water is pouring through the ceiling |
| A customer writes 'my roof is leaking'. | Matched to leak repair, not a roof replacement. | my roof is leaking |
| Two visitors pick the same window at once. | The second is told somebody just took it, and the lead is kept. | No phrase to try |
| Every crew is at capacity. | Held for the office queue, and logged. | No phrase to try |
| The ZIP is outside the service area. | The score says so, and the chat ends with a call-back request, not a booking. | No phrase to try |
Guardrails and hand-off
Guardrails
- Emergency words come from each company's own knowledge file.
- The database, not a check in code, decides who gets a window.
- The estimator shows a $0 service as free, never scaled into a price.
- Estimates are ranges, never a firm price.
When a person takes over
Emergencies skip slot picking and are logged on the emergency route for the office. When no crew is free, the lead waits in the office queue with its score and reasons.
Not in this build yet
We would rather you hear it from us.
- Confirmation, follow-up and review steps are logged only. No text or email goes out, and each log line says so.
- Crew load is fixed in the demo data.
- There is no routing by time of day.
- The crew board has no login on the demo, so we never link to it.
Try it yourself
Type:
water is pouring through the ceilingExpect: Read as an emergency. The chat skips the time-slot step.
Type:
my roof is leakingExpect: Matched to leak repair, not a new roof.
Open the chat on the demo site. The chat button appears once you have scrolled a little, or after about 20 seconds. Please don't type real personal details.
Built with
- TypeScript
- Next.js
- React
- Node.js