Civic compliance software
SmartComply
We designed and built SmartComply — the system of record that runs a town’s entire stormwater permit program from day one.
- Year
- 2026
- What we did
- Platform, product, brand & site

The problem
Towns are legally accountable for their stormwater programs, yet most run them on spreadsheets, shared drives, and email — so when an auditor or a lawsuit asks who changed what and when, no one can answer.
Every U.S. town with an MS4 permit owes the same work: tracking outfalls, chasing illicit discharges, testing backflow, inspecting construction sites and BMPs, managing industrial pretreatment, issuing enforcement, billing fees, and signing off an annual report that has to hold up under scrutiny. The obligations are federal. The tooling, almost everywhere, is improvised.
SmartComply brought us that gap. A program scattered across files and inboxes isn’t just inefficient — it’s indefensible. The moment an inspection record can’t be tied to a person, a date, and a reason, the town’s legal position erodes. We were asked to turn an ad hoc routine into a system of record that could stand up to an audit.
So we designed and built it: an isolated workspace for each town, every permit obligation modeled as a tracked workflow, every record pinned to an interactive map, and every field carrying its own tamper-evident change history. Enforcement notices generate, get e-signed, and go out by physical mail. Residents report spills through a public intake that lands as a tracked case. A town signs up and is running its full program the same day.
What makes it different
What we built in, on purpose.
The decisions that separated a real system of record from another database with a map.
A workspace per town
Each town gets a fully isolated tenant — its own data, its own program, no bleed. Compliance records can’t share a table with anyone else’s.
Obligations as workflows
We didn’t store records and hope. Every permit requirement is modeled as a tracked workflow, so the work that’s owed and the work that’s done are the same object.
Change history on every field
Each field carries its own tamper-evident history of who changed it and when. The audit answer is built into the data, not reconstructed after the fact.
The map is the index
Outfalls, inspections, investigations and BMPs live on an interactive map. The town’s geography is how you find and reason about its records.
Enforcement that closes the loop
Notices are generated, e-signed and physically mailed from inside the platform — no exporting to Word, no trip to the post office to make it official.
A public front door
Residents report spills and illicit discharge through a public intake that becomes a tracked case the moment it’s filed — citizen reports enter the same system, not a separate inbox.
When the auditor asks who changed this and when, the answer is already in the record.
Under the hood
A multi-tenant compliance platform, specified.
A turbo monorepo on Next.js 16 and React 19, deployed on Vercel, with the data and document machinery a regulator-facing system demands.
Core platform
- Framework
- Next.js 16 (App Router) · React 19 · TypeScript, in a Turborepo with shared db / rules-engine / ui / types / validators packages.
- Data layer
- Drizzle ORM over Nile — Postgres purpose-built for multi-tenant SaaS, giving each municipality a hard-isolated tenant.
- Auth & access
- Clerk for identity, with a custom RBAC layer and tenant-slug routing so roles and data scope per town.
- Background work
- Inngest for durable jobs — notice generation, report snapshots, import pipelines and scheduled compliance checks.
The compliance machinery
- Geospatial
- MapLibre GL renders outfalls, facilities and IDDE cases as interactive map layers — the primary way users navigate.
- Rules engine
- A dedicated package encodes MS4, pretreatment and backflow rules, so deadlines and violations are computed, not hand-tracked.
- Documents
- TipTap for rich editing; pdf-lib + fontkit to generate notices and the annual MCM report; e-signature capture on enforcement.
- Physical mail
- Lob delivers enforcement notices as certified letters, with tracking written back to the case.
- Audit integrity
- Per-record hashing plus field-level change history — the tamper-evident backbone behind every list and detail view.
Money, intake & intelligence
- Payments
- Stripe for subscriptions and fees, Plaid for bank-linked payment, modeled inside the same tenant as the obligations.
- Public intake
- A public, rate-limited spill/illicit-discharge report (Upstash) that creates structured investigation cases.
- AI assist
- The AI SDK (Anthropic · Google · OpenAI) powers import triage and document drafting — intelligence inside the workflow, not a chat bubble.
- Comms
- Transactional email and SMS for notices, reminders and status changes across the lifecycle of a case.
Operations & quality
- Observability
- Sentry + OpenTelemetry (Vercel OTel) for traces and errors across the request and job paths.
- Storage
- Vercel Blob for evidence photos, lab results and generated documents.
- Testing
- Playwright end-to-end, plus Autonoma and Kernel-driven automated QA against seeded demo tenants.
- Delivery
- Vercel with a route-smoke + auth-smoke gate; an automated code-audit step blocks high-severity findings from shipping.
The build, on screen
Inside the platform.










Technology
What it’s built on.
- TypeScript
- Next.js 16
- React 19
- Turborepo
- Nile (Postgres)
- Drizzle ORM
- Clerk
- Custom RBAC
- Anthropic
- OpenAI
- Inngest
- Upstash Redis
- Stripe
- Plaid
- Vercel Blob
- MapLibre
- Lob
- TipTap
- pdf-lib
- Vercel
- Sentry
- OpenTelemetry
Our approach
How we approached the build.
We built backward from the hardest question a town can be asked.
- 01
Started from the audit.
We designed for the moment of scrutiny first — an auditor or a lawsuit asking for proof. Everything else followed from making that answer trivial.
- 02
Modeled the permit, not the paperwork.
We mapped the actual MS4 obligations into workflows so the software mirrors what the permit requires, instead of digitizing whatever spreadsheet a town happened to have.
- 03
Made history non-negotiable.
Change tracking isn’t a feature you turn on — it’s wired into every field. There’s no path to editing a record without leaving a tamper-evident trail.
- 04
Removed the onboarding wall.
We built it so a town self-serves into a working program. No implementation project, no consultants — sign up and the system runs from day one.
Next case study
How we helped FASTMAX turn a wall of tax forms into a finished return.