Web · Multi-tenant · Next.js 16 · Supabase · Leaflet · Web Push
Pin311
Report a problem to your city without downloading anything.
Pin311 is a civic issue-reporting platform where the reporting side has almost no friction and the receiving side gets real data. Residents submit from a browser with zero identity requirements. Officials get a map, a queue, categories, photos, and CSV or JSON export they can hand to whatever system already runs the department. One deployment serves many cities, each with its own tenant.
- Next.js 16 (App Router)
- React 19
- TypeScript
- Tailwind CSS 4
- Supabase (Postgres + Storage)
- Leaflet / react-leaflet
- Web Push
Origin
How it started
After a storm, the way a town actually reports damage is a Facebook thread — hundreds of photos, no addresses, no categories, no way to count anything. Meanwhile the official channel is a phone number that rings during business hours. The gap is not that cities don't care; it's that the intake format is unusable on both ends. Pin311 exists to make the easy path also be the structured path.
Features
What it does
Zero-friction reporting
Drop a pin, attach a photo, choose a category, submit. No download, no account, no password, no email verification. Every requirement removed from that flow is a measurable increase in how many residents finish it.
Multi-tenant from the first commit
Each city is a tenant with its own categories, branding, and data boundary, served from one deployment. Standing up a new municipality is configuration, not a fork — which is the difference between a product and a custom build you maintain forever.
Structured output, not a thread
Officials get a filterable map and queue plus CSV and JSON export. The goal was never to be the city's system of record — it's to hand clean, mappable data to whatever already is.
Categories are configuration
Storm damage was the first category, not the product. Potholes, code violations, downed limbs, streetlights — the schema treats the category tree as tenant data, so the same platform covers routine 311 and a disaster surge without a code change.
Under the hood
Engineering
Reusing a proven stack on purpose
Pin311 runs the same shape as BRYKK — Next.js 16 App Router, React 19, TypeScript, Tailwind v4, Supabase for Postgres and storage, Leaflet for maps, web-push for notifications. Deliberately boring and deliberately shared: the second and third products in a stack you already know cost a fraction of the first, and the operational knowledge compounds instead of fragmenting.
Anonymous intake, accountable output
Reports carry no identity, which removes the friction but invites abuse, so trust lives on the receiving side — rate limiting, moderation queues, and per-tenant review rather than authentication at the door. Making the resident prove who they are would have solved the wrong problem at the cost of the only metric that matters.