Case study 03 · Granite Construction · Aug–Sep 2026
Job Site Management Hub
One place for a regional safety team to find every active jobsite, who to call when they get there, and air-quality and incident alerts by text.
- My role
- Product owner, researcher and builder: requirements, data model, three app pages, three automated flows, usability fixes, handoff to the enterprise Power Platform team.
- Users
- Regional safety staff visiting sites; superintendents and foremen; office staff and new hires who need a meeting point and a phone number.
- Methods
- Stakeholder conversations · task analysis · data audit and cleaning · information architecture · iterative usability fixes · handoff documentation
- Tools
- Power Apps (model-driven app with custom pages) · Dataverse · SharePoint lists · Power Automate · Outlook
- Scale
- 334 sites tracked, 141 active; 70+ contacts synced from the directory; daily sync of 273 job records.
- Outcome
- Packaged as a solution and handed to the enterprise team for a DEV → STG → UAT → PROD migration.
Visiting a site meant asking around
During a regional safety push, the team needed the same handful of facts for every active site: exact address, end date, the prime contact and their phone number, current work activities, this week's safety focus, where to park, what PPE to wear, and when the morning and midday safety huddles happen. That information existed. It lived in award emails, a spreadsheet that was out of date the week it was made, and the heads of the people who had already been there.
I spent the first days building the list by hand for a handful of sites and watching what was hard: no one place to look, no way to know which of two phone numbers was current, and no way to tell if a site was still active without calling.
- 141active sites in the region across Washington, Oregon and Idaho
- 56of them had no usable address on file when I started. Data quality was the first UX problem.
- 3separate sources of truth: award emails, a spreadsheet, and people's memory
- 2daily safety huddles per site that a visitor needed to know about before arriving
Three pages, organized around three questions
Where is the site? Who do I call? Is it safe to be outside today? Each page answers one question and nothing else.
Where is it?
Search and filter every active site, open details, fix what's wrong on the spot, and get directions to the meeting point rather than the mailing address.
Who do I call?
A searchable directory synced from the company people list. Tap a person to see their role, the sites they cover, and one-tap call and email.
Is it safe outside today?
Crews pick their city and sign up for air-quality and incident alerts by text. Sign-ups write to a table the safety team can act on during smoke season.
03 · Keeping it true without anyone maintaining it
Three flows so the hub never depends on someone remembering to update it
Sync job locations
Runs every morning before the field starts. Reads the company job list, updates 273 job records, and adds any new site it hasn't seen.
Sync directory contacts
Pulls people from the company directory and merges dual roles, so a superintendent who is also a foreman appears once, with both roles, rather than twice.
New job email → new site
Watches for "NEW JOB" award emails, parses the job number, office and site name, creates the site flagged Needs Update, and lists exactly what's still missing.
The "Missing Information" field turned a data-quality problem into a to-do list the team could work through, one site at a time.
Small fixes that came from watching people use it
- 01
A loading card that doesn't fight the platform
The model-driven host shows its own spinner over a custom page while it loads, and it can't be turned off. My loading message sat underneath it. I moved the card below the vertical center so the two never overlap, and gave it an elapsed-time line so a slow load felt intentional rather than broken.
- 02
Tap a contact, get a card
The first version listed names and phone numbers. People wanted to know which sites a person covered before calling. Tapping a row now opens a card with role, formatted phone, email, office, and a bulleted list of their job sites, with Call and Email buttons.
- 03
Phone number required, and the form says why
Text alerts are the whole point of the sign-up. The phone field is now required, validated to ten digits, and the status message explains the reason instead of just refusing.
- 04
Clipped descenders and text that wouldn't wrap
Modern label controls in the platform don't render line breaks and clip letters like "g" and "y" at default heights. I switched multi-line text to HTML controls and set explicit heights, the kind of detail that reads as "polished" versus "someone's side project".
Built so it could leave with someone else
Near the end of the internship the enterprise Power Platform team asked to take the hub through a proper DEV → STG → UAT → PROD pipeline with environment variables and a service account. My developer environment couldn't add co-owners, so I packaged the app, all three custom pages, all three flows and ten data tables into a single exportable solution, documented every hard-coded reference they'd need to swap, and wrote a handoff guide covering what was built, what was next, and the platform quirks that had cost me time.
Data quality is a design problem
A directory with 56 sites missing an address is not a database problem, it's an interface problem: nobody had a place to notice the gap or a reason to fill it. Showing "Needs Update" and what's missing did more than any cleanup script.
Design around the platform, not against it. Every constraint I couldn't remove (the host spinner, label rendering, single-user environments) became a design decision instead of a bug report.
Write the handoff from day one. The document I gave the enterprise team was the same running notes I'd kept for myself; the only difference was that I'd been keeping them.