Projects / Roofing CRM Job Management
Rebuilding a roofing CRM's Job module into an operational command center
We built Priority Roofing a CRM from scratch then reworked its plain Job Details record into a structured workflow teams could actually run a job from.
- Company
- Priority Roofing (USA)
- Timeline
- Jun 2025 - 3 weeks
- Team
- Developers, Stakeholders, Tester, Product Designer

A roofing business running on spreadsheets it had outgrown
Priority Roofing ran on two disconnected systems. Customer and job information lived in QuickBooks, while every job action and service (material orders, materials, crew details, crew and office fees, PM assignments, invoices) ran through a stack of Excel sheets. We built the CRM to tie them together, but the Job Details module shipped as a plain record. Reworking it into something teams could actually run a job from is what this project covers.

“We use the CRM to say a job exists. Everything that actually moves the job forward is in spreadsheets.”
Job data had no single home
It wasn't a missing feature. Every detail that should belong together was split across separate sheets, updated by hand, and prone to drifting out of sync, so seeing one job whole meant opening many files and trusting someone's memory.
- 01Job data scattered across 5+ spreadsheet tabs with no single source of truth.
- 02Manual updates led to errors, records drifted out of sync across files.
- 03No structural way to link a job to its crew, materials, invoices, and customer.


Mapping the workflow before opening a design tool
I mapped the existing Excel system end-to-end, every sheet of job actions and services, the data it held, and how teams moved between them. Customer and job records sat in QuickBooks; everything that moved a job lived in at least five disconnected sheets, with no structure or links back to the job.
What a single job required across the spreadsheet system
How people actually worked, not what was documented
Stakeholder walkthroughs with every role surfaced the workarounds and mental shortcuts. Three findings shaped everything that followed.
STAKEHOLDER SESSION
3 roles · 9 questions
I sat with each role and walked their actual day rather than a documented process, anchoring every session on a few core questions about how work really moved.
Sales Reps
First contact → handoff
- Once you close a deal, how do you know it actually moved forward?
- What do you check before telling a homeowner what happens next?
- Where do you look when a customer calls asking for an update?
Back Office
Materials, audits, commission
- Walk me through everything you touch after a job is submitted.
- How do you know a job is ready for you to act on?
- What do you keep in a spreadsheet that the CRM doesn't hold?
Project Managers
Scheduling, crews, inspection
- How do you decide which job to schedule next?
- When a job stalls, how do you find out, and from whom?
- What would you need to see the moment you open a job?
THE GUIDING QUESTION
How might we give every role a shared, reliable view of a job without adding complexity to their workflow?
Linked data lived in people's heads, not in the system
Users kept a mental map of which job linked to which customer, crew, invoice, and material order. There was no structural relationship between records. Any absence or staff change created immediate knowledge gaps and risk of error.
Every update was a separate manual action across multiple files
There were no triggers or linked fields. Updating a job meant independently editing cells across multiple sheets. Small inconsistencies compounded quickly. No one could be sure a record reflected the current state of a job.
Each role had a different relationship to the same job data
Sales reps needed customer and status context. Project managers needed crew and materials. Office staff needed invoices and payments. Executives needed an overview. All of these users were touching the same job data but had no shared, unified view of it.
Make the Job Detail page where work happens
A job's customer and core details come straight from QuickBooks, while every service that used to live in Excel (orders, crews, fees, PM work, invoices) is pulled in and categorized under Job Info. The Job Details page works like a home screen for the job, not a flat form: open it and every answer is one place away.
- Visibility
- Anyone should answer "where is this job and what happens next?" in under five seconds.
- Sequence
- The operational lifecycle has a real order. The interface should reflect it.
- Containment
- Everything tied to a job, documents, notes, requests, estimates, photos, lives inside the job.

The first version captured everything as a feed, every event timestamped, with a manual status dropdown on top. It looked organized and shipped fast. But once live, usage data showed it was documenting jobs, not moving them.
68%
of job opens ended with the user still checking the spreadsheet
5.2 days
average time a job sat at a stage with no recorded next action
1 in 3
jobs had a status that disagreed with the latest feed entry
9 / 12
users couldn't name the next step without calling the office
“I can see everything that happened. I still can't tell you what to do next.”
The feed answered "what is this job?" but never "what happens next, and whose move is it?" so teams kept the spreadsheet open beside it, and the problem we set out to solve was still unsolved.
The approach the data pointed to
- Make it forward-looking
- Stop logging what happened and start surfacing the next action, promote "Next Step" to a first-class field.
- One source of truth
- Derive status from the pipeline itself, retiring the manual dropdown so state can never disagree with reality.
- Assign every stage
- Give each of the seven stages a single clear owner, so handoffs are explicit and nothing stalls unseen.

The feed became a horizontal pipeline of the seven real operational stages, rendered as a stepper across the top of every job. The current stage is unmistakable, "Next Step" is promoted to a first-class field, and each stage carries a single clear owner.
Job Cycle as a stepper, not a checklist
Problem. How do we visually represent the operational lifecycle?
Decision. Horizontal stepper. Its linearity communicates sequence at a glance, and placing it atop every Job Detail screen makes the workflow the frame the user reads everything else through. Stages stay re-openable for jobs that kick back.
"Next Step" as a first-class field
Problem. Users opened the job to find out what to do next, the CRM made them deduce it from status.
Decision. Hybrid. The next step is computed from the Job Cycle by default, but the right roles can override it when reality diverges, reliable in the 90% case, with room for the edge cases.
Categorize post-submittal work under Job Info
Problem. After a job was submitted, the work it generated (material orders, scheduling, audits, COC, commission) had nowhere structured to live, so it spilled back into spreadsheets.
Decision. Everything a job produces after submittal is grouped under a single Job Info area, organized by category instead of scattered fields so the record grows with the job rather than sprawling across files.
Sync customer & job info from QuickBooks, own the operations
Problem. Customer and job information lived in QuickBooks and the team trusted it. Duplicating or replacing it would create two sources of truth and a political fight.
Decision. One-way sync. Customer and job details flow in from QuickBooks as read-only fields, while every operational service that used to live in Excel (materials, crew, fees, PM, invoicing) moves into the Job module the CRM owns.

Jobs that sat silently in a spreadsheet became visible
Bottlenecks at "Audit Work Order" surfaced operational issues leadership didn't know they had. The qualitative shift mattered as much as the numbers: the work finally had a single, shared home.
100%
reduction in spreadsheet dependency across Back Office & PM teams
40%
faster job coordination, Sales handoff to first Back Office action
3 wks
to daily adoption across Back Office and Project Manager roles
min → sec
to locate a contract or insurance scope inside the job

