← Granite internship

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.
01 · THE GAP

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
02 · WHAT I BUILT

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.

All Active Sites
Trail improvementsActive · ends Oct 2026 · Directions
Overlay and resurfacingActive · Meeting point on file
Plant constructionNeeds update · address missing
View details · Edit info · Directions

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.

Site Contacts
Superintendent3 sites · Vancouver office
Foreman1 site · Boise office
Project engineer2 sites · Vancouver office
Call · Email

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.

Safety Alerts
Air quality (AQI) alertsWildfire smoke season · by text
Incident alertsRegional safety notices
Work phone (required)10 digits, for text alerts
Sign up

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.

04 · USABILITY DETAILS

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".

05 · HANDOFF

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.

06 · WHAT I LEARNED

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.