Secure Bike Parking: Scoring Where to Lock Up
Where you lock your bike in Portland decides whether it’s there when you get back. I turned that street knowledge into a map.
The Problem
Some racks are theft magnets, some are safe. That knowledge lives in riders’ heads, not anywhere you can look it up.
What I Built
A map-driven guide that scores each parking spot by theft risk, visibility, and street-level imagery, and lets riders add spots of their own. Two surfaces: a public map and an admin moderation portal. It started as a two-person, five-hour hackathon build and grew into a roughly 500-commit platform.
Tech Stack
- TypeScript/TSX
- SQL
- JavaScript
- React 19
- Vite
- React Router
- Cloudflare Pages Functions
- Cloudflare Workers
- Cloudflare D1
- Cloudflare KV
- Cloudflare R2
- Cloudflare Queues
- browser localStorage
- npm workspaces
- Wrangler
- Cloudflare Pages preview branches
- Worker cron and queue consumer
- Anthropic Claude Haiku 4.5 for NL parsing
- explanation generation
- submitted-photo vision judging
- Vitest
- Playwright
- Node test runner
- TypeScript project references
- OpenAPI codegen drift check
- Leaflet
- leaflet.markercluster
- jose
- openapi-typescript
- exifr
- heic2any
- fflate
How It Works
The recommendation pipeline fuses several mismatched sources - Nominatim geocoding, OSM and Overpass spots, PortlandMaps crime data, Google Street View and Mapillary imagery - and scores each one. Claude vision judges the spots; a lighter model parses trip requests in plain language. User submissions run through a human-in-the-loop ingest pipeline. Shared OpenAPI contracts are enforced by a Playwright end-to-end gate on every UI change, so two separate front ends can never drift from the API.
What Made It Hard
Fusing messy, mismatched geodata into one score a rider can trust. Building a moderation pipeline a human can actually review at speed. Keeping a contract-tested API honest across two independent front ends.
The Throughline
A civic tool for my own city: take scattered, hard-won local knowledge and make it usable in ten seconds by anyone. The contract in the middle is what lets it stay honest as it grows.
Status
Live at securebikeparking.org, grown from the hackathon demo into a working platform.