Case Study
Four Internal Apps in Six Weeks
The problem
A lawn and irrigation company runs on paper, texts and spreadsheets. Field inspections lived in people's heads until the weekly meeting. The shop mechanics coordinated over iMessage with no way to flag something urgent or attach a photo to a task. Uniform stock was a spreadsheet one person maintained. A growing fleet of robotic mowers had no tracker at all.
None of these problems justified buying software. All of them cost time every week. The question was whether one person with an AI coding agent could ship working tools fast enough, and simple enough, that crews would actually use them.
What I built
Four mobile-first web apps, built through my self-hosted agents, on one shared stack so each new app started from the last one:
- Property Inspector. Field managers grade properties, log tasks and to-dos with photos, and run pre-meeting summaries from the site. Became the template every later app was cloned from.
- Shop Comms. Messaging and task assignment for the mechanics: multi-person assignment, due dates color-coded by urgency, a time-sensitive flag, photo attachments on messages and tasks, and a dedicated screen for anything flagged.
- Robot Inventory. Tracks the robotic mower fleet: which units are deployed where and their status.
- Uniform Inventory. Stock by size, color and cost, with value reporting and issuance history for HR.
Stack: React, built as installable progressive web apps (they open from a phone's home screen like a native app), Firebase Hosting and Firestore for data, Cloudinary for photos. Each app is small on purpose: one job, few screens, big tap targets, works one-handed in a truck.
Security hardening (July 2026). The apps shipped fast and shipped with open database rules. In one week I ran a hardening pass across all of them: deploy anonymous authentication in the app code, enable it in the console, deploy deny-by-default database rules, then test both directions (the app still works, direct access is refused). Verified against the live deployed rules on September 24, 2026: every app requires authentication on every collection and ends in a deny-all rule.
What was mine
The problem selection, every design decision, the shared stack, the template pattern, the hardening pass and the rollout to each crew. My agents wrote the code. The people who used the apps shaped them: a shop mechanic's feedback drove Shop Comms' second version, a division manager's phone surfaced the iOS layout bugs, HR's cost spreadsheet became the uniform app's value report.
Decisions that mattered:
- One stack, cloned forward. The second app took a fraction of the first's time because the first was built as a template. Brand, navigation, auth, photo uploads and the iOS fixes all carried over. Everything learned went into an app-building wiki my agents read before starting any new one: the stack and design system, iOS installed-app gotchas, Firebase setup and deploy, database design and hardening, photo uploads, push notifications, and the UI patterns that work one-handed.
- Native dialogs are banned. Browser confirm and alert boxes break on iPads in installed-app mode. Every one was replaced with an in-app modal, and that became a rule for every app.
- Safety gates on destructive actions. Clearing a week of inspection data requires typing the phrase "clear this week." Small friction where mistakes are expensive.
- Harden everything at once, then verify from the outside. Rather than fix one app when someone noticed, I ran the same recipe across all of them and confirmed the deployed rules afterward, not the local files.
Problems worth knowing about
- iOS hides things. Buttons sat behind the status bar on a manager's phone. Fixed with safe-area padding on every header, and the fix carried into every later app, including the update banner that had the same problem.
- Installed apps bypass the password manager. On iOS, an app opened from the home screen never shows Safari's save-password prompt. Not a bug, but it changed how login had to work.
- Pixel-measuring a logo. The company wordmark has an asymmetric sun, so centering it as a home-screen icon by its bounding box looked wrong. I measured column density across the image to find the true center of the text and offset it by hand.
- Stale navigation state. Tapping the logo landed on the wrong screen because a "return to" variable wasn't reset. Small, but the kind of bug that makes crews stop trusting an app.
Results
Usage, pulled read-only from each app's database on September 28, 2026:
- Property Inspector (three division managers): 492 inspections across 55 properties in 16 weeks, about 31 a week, with no empty weeks. Use tapers with the end of the mowing season in mid-August.
- Uniform Inventory (HR): 210 issue and return transactions across roughly 18 employees over 21 weeks, about 10 a week, still active.
- Shop Comms (three mechanics): 147 tasks over 21 weeks, about 7 a week, still active. 137 of them closed, a 93% completion rate.
- Robot Inventory (four people across robotics and field management): 118 units tracked and 21 service events logged since mid-July.
Not measured: time saved. I didn't baseline the manual processes before automating them.
What I'd do differently
- Hardening on day one, not month three. The apps ran with open database rules for two months. Nothing happened, and that's luck, not design. The template now starts locked.
- Real login instead of shared passwords. Each app sits behind a client-side password shared by everyone who uses it. That's a gate, not access control. Moving them to company Microsoft login is next.
- Instrument usage from the start. The numbers above came from a read-only database query four months after launch. A simple usage view per app should have been part of the template, so I'd have seen the seasonal curve and the quiet weeks as they happened.