The Inspector

Inspiration

It started with my dad, a structural engineer in New York City. A while back he mentioned that filling out NYC DOB inspection forms, the TR1 and TR8, was painful and manual. The idea stuck with me.

When I finally sat down to build it, I did my research and found the problem had already been solved. NYC's DOB NOW portal had automated the entire workflow. There was nothing left to build.

So I went back to him. That conversation uncovered something different, something that hadn't been automated, something that still costs him hours on every job:

"One thing that I asked you had to do with what we call a preconstruction survey, or precon. For exterior we are looking at all walls and trying to find cracks or other flaws. Walls have a large extent so you take photos one small section at a time. When you come home you can't recall which photo was taken where."

"When you do the interior, walls of each room look the same. So something that tracks the room and the location within that room can be of value."

"People don't want to pay much for precon survey. Without the app too much time is needed and you still don't get the organization needed. Paying a monthly fee but automating the process will give the engineer a higher profit per job."

That was the real problem. The gap between walking a building and producing a defensible record of what you found there.

What We Built

The Inspector is a mobile-first field survey tool for structural engineers and inspectors. The workflow is simple: create a survey from a report template, walk the building and capture photos from your phone into organized sections, annotate photos in place with arrows, freehand markup, and pins, then export a structured PDF with everything rendered and ready to sign off.

Stack: Next.js 16, Prisma 7, Aurora Serverless v2 on AWS RDS, S3 for photo storage with direct browser uploads via presigned URLs, NextAuth.js for auth, deployed on Vercel.

How We Built It

We worked milestone by milestone. The first few milestones covered the foundation: bootstrapping the stack with Prisma 7's new driver-adapter pattern, auth with NextAuth.js, CI/CD on Vercel, S3 infrastructure via Terraform, and the core survey UI covering the dashboard, new survey form, detail page, and capture screen.

Midway through I discovered CompanyCam, a photo documentation tool for contractors that had already solved a version of this problem. Another gut check. But looking closer, CompanyCam is built for general contractors. It has no concept of structural findings, report templates tied to inspection checklists, or PDF export formatted for engineering sign-off. It is a photo organizer, not an inspection tool. Rather than abandoning the project I used it as a benchmark. If a feature existed in CompanyCam I needed a reason why ours was better for the specific inspection workflow. That analysis drove the second phase of the build:

  • Report templates: survey creation defaults to picking a pre-defined checklist so engineers are not building sections from scratch on every job
  • Org and multi-tenancy: replaced single-owner scoping with a proper organization and membership model so a PE can belong to multiple firms and field engineers can be shared across orgs
  • Photo annotations: a non-destructive drawing layer stored as normalized coordinates, rendered as SVG overlays in both the in-app lightbox and the exported PDF
  • Fast uploads: switched from buffering files through the server to direct browser to S3 presigned PUT, which was the biggest capture performance improvement
  • Pinch zoom: real multi-touch tracking in the photo lightbox using TouchEvents since Pointer Events do not expose finger distance

Challenges

The pivots

The original plan was a digital TR1/TR8 inspection form tool. That idea came from my dad years earlier. By the time I sat down to build it the entire problem had already been solved by a government portal. One conversation with him surfaced the precon survey problem instead. Then midway through building that, CompanyCam showed up as a near-competitor. Neither pivot was wasted time. Each one tightened the actual problem being solved.

Next.js 16

Our CLAUDE.md opens with: "This is NOT the Next.js you know." Middleware-based auth no longer works the same way, NEXTAUTH_URL behaves differently across build, runtime, and preview deploys, and Turbopack introduced its own edge cases. We hit breaking changes on auth and static generation that required going back to the documentation and in some cases reading the source.

Prisma 7 and RDS SSL

Prisma 7 removed built-in connection string handling for serverless environments. We wired the pg adapter explicitly at client construction time and then discovered that a newer version of pg-connection-string now treats sslmode=require as verify-full, which fails against RDS without the AWS CA bundle. The fix was to strip sslmode from the URL entirely and pass the ssl options directly to the pool config.

Annotation coordinate math

Photos render at different sizes depending on the device. Annotations are stored as normalized coordinates between 0 and 1:

$$x_{normalized} = \frac{x_{pixel}}{w_{container}}, \quad y_{normalized} = \frac{y_{pixel}}{h_{container}}$$

The same annotation renders correctly at 390px on a phone and at 1200px in a PDF column because the same math runs in both places.

Security gaps in multi-tenancy

When we added organizations a code review caught that the engineer picker in survey creation was listing all field engineers globally, not scoped to the requesting org. We centralized all authorization checks into a single access module to prevent that class of bug from recurring.

Changing laptops mid-hackathon

We moved machines during crunch time with no Node, no Docker, and no credentials, on hotel WiFi with 600ms latency to npm. We provisioned Aurora from scratch with a new Terraform config, hit the same SSL bug in production on Vercel, and debugged back to a working deploy through logs alone.

What We Learned

Talk to the person with the problem before writing any code. We almost built the wrong thing twice. One real conversation with a working structural engineer was worth more than all the research that preceded it.

Ship forms first. Every major feature started as a plain HTML form with server actions and no client-side JavaScript. Interactivity only came in where a form genuinely could not do the job.

Keep the original photo untouched. Annotations are a separate layer applied at export time. Inspectors need the unmodified source image to hold up in legal and insurance contexts.

What's Next

  • GPS tagging per photo, which was the original feature my dad described
  • Offline capture with sync for basements and rooms with no signal
  • Email delivery for mentions, which are currently stored but not sent
  • Invite by email, which currently requires the person to already have an account ```

Built With

Share this project:

Updates