Fix Please

See something broken? Snap it. We'll find who fixes it.

Fix Please (fixplease.work) is a web app built for phones. You take a photo of a pothole, a dead streetlight, or a cracked sidewalk. It works out who's probably responsible and helps you write them a report.

Inspiration

Spotting a pothole is easy. Knowing who to tell is the hard part. A road inside city limits might belong to the state. A streetlight might belong to the power company. A problem near campus could be the university's, the county's, or a private landlord's.

That's usually where people give up. We wanted to close the gap between "someone should fix this" and reaching someone who can. The app starts with what you already have: a photo and a location.

What it does

  1. Snap a photo. Your browser shrinks it and removes hidden metadata before uploading. If the photo has GPS data, we use it to suggest a spot.
  2. Confirm the location. Search an address, use your phone's location, or drop a pin on the map.
  3. Add a note (optional). A lane, landmark, pole number, or HOA name can make a big difference.
  4. Find who fixes it. Gemini looks at the photo and searches official sources, along with map data about the spot. You get an organization, a short explanation, source links, and contact info if it's published.
  5. Send it yourself. Edit the email draft, download it with the photo attached, or share it from your phone. We never send anything for you.

We're upfront about how sure we are. A result backed by an official page is labeled differently from a best guess. If we can't tell who's responsible, we say so and show only what the map tells us. We don't make up a name. If there's no public email address, we leave the field blank instead of inventing one.

There are no accounts, no report database, and no analytics. Your photo, pin, and note go to Google Gemini, and Google may keep search requests for up to 30 days. Map lookups go to OpenStreetMap. Fix Please is for routine repairs, not emergencies.

How we built it

  • Frontend: React, TypeScript, and Vite, with Leaflet for the map. exifr reads GPS from the original photo. Then we redraw the photo on a canvas to get a smaller JPEG with no metadata. We used Grok 4.7 to answer questions related to building a good UI/UX.
  • Backend: Node.js and Express. The server keeps the Gemini API key out of the browser and runs each lookup. Zod checks the AI's structured output, and the frontend and backend share TypeScript types. Backend is generated through Cursor Opus 5.5 extra high
  • Location data: OpenStreetMap's Overpass API finds nearby roads, route numbers, campuses, and streetlights. Nominatim handles address search. U.S. Census data tells us whether a spot is inside a city or in county land. We treat all of this as clues, not proof.
  • AI in two steps: First, Gemini (with Google Search and URL context) looks at the photo and researches who's responsible. A second call turns that research into a structured report without searching again.
  • Checking the AI's work: The server follows citation links, reads the source pages, and confirms that quoted passages and contact details actually appear there. If something can't be confirmed, it's removed or marked less certain. These checks run while the report is being formatted, so they add little wait.
  • Sending: The app builds a downloadable .eml email with the photo attached, and uses the Web Share API on phones. ALTCHA proof-of-work and rate limits protect the paid AI endpoint without making anyone sign up.

Challenges we ran into

  • Nearby doesn't mean responsible. City limits, state highways, campuses, utilities, and private roads all overlap. Map data and the user's note guide the research, but we only give a confident answer when an official page backs it up.
  • AI answers can sound right and still be wrong. Links break, citations point to the wrong page, and contact info gets made up. So we check on the server instead of trusting the model.
  • Public map services are unreliable. They sometimes fail or time out. We added backup sources and a time limit, so one slow service doesn't hold up everything else.
  • A photo doesn't show everything. A daytime picture of a streetlight can't prove it's out at night. The app relies on the user's note for that and warns when the note is missing.
  • Email attachments are tricky. A mailto: link can't attach a photo. We added the downloadable email and phone sharing, and we tell users what each option can and can't do.
  • Location data is sensitive. We read GPS on the device, remove metadata, ask users to confirm the pin, and say plainly what gets sent to Gemini. We don't claim it all stays local.

Accomplishments that we're proud of

  • It goes from a photo to a ready-to-send report, not just a description of the damage.
  • It shows how confident it is, along with its sources.
  • It checks contact info before showing it, and leaves the field blank when it can't.
  • It combines the photo, the exact pin, map data, and a human note into one answer.
  • The user stays in control: nothing is sent automatically, there's no account, and no reports are stored.

What we learned

  • Spotting a problem is easy. Finding the owner is hard. Anyone can recognize a pothole. Knowing who maintains that stretch of road is the useful part.
  • Search isn't verification. Search gives the model something to work from, but you still need separate checks before showing a claim to users.
  • People know things the data doesn't. A pole number or an HOA name can answer what a photo and an address can't.
  • Being honest about uncertainty is more useful than false confidence. A clearly labeled best guess with sources beats a promise you can't back up.
  • The last step matters. Producing text isn't the finish line. If people can't easily edit, attach, and send the report, the app hasn't done its job.

Built With

Technology What it's for
TypeScript, React, Vite App interface and shared types
Node.js, Express API server and lookup coordination
Google Gemini API, Search grounding, URL context Photo analysis and research
Leaflet, OpenStreetMap, Overpass API, Nominatim Map, roads, campuses, streetlights, address search
U.S. Census Bureau geographic data City vs. county boundaries
Zod Checking the AI's structured output
exifr, Canvas API Reading GPS, resizing photos, removing metadata
ALTCHA, express-rate-limit Bot protection and request limits
DOMPurify Cleaning up search-suggestion HTML
Web Share API, .eml files Sending reports with the photo attached
CSS, Lucide React, Public Sans, Big Shoulders Layout, icons, and fonts

Built With

Share this project:

Updates

Submission history