Inspiration: what is the problem, and how do I know it is real?

Families in San Diego have to work out whether a particular bike is allowed for a particular child, in the places they actually ride. State law, city rules and school-campus requirements can give different answers. A product sold as an e-bike can also have an unlock mode, missing pedals or specs that put it outside an e-bike definition.

I asked riders about that gap. In my small anonymous survey, none of the seven riders reported having a class-label sticker on their bike, four reported a police warning or citation since August 13, and five reported a crash or near miss in the past year. The survey explained the classes in the question itself, so it could not measure what riders already knew. In separate in-person conversations, 26 of 34 riders said they did not know their bike's class until it was explained. These are small convenience samples, not estimates for every rider in San Diego.

The rules research showed why knowing the bike matters. The City of San Diego has an under-12 restriction on Class 1 and 2 e-bikes, while SDUHSD has separate class, tag and training requirements for campus access. I wanted a family to get an answer for their bike and rider without having to reconcile those sources themselves.

Sources: San Diego Municipal Code and SDUHSD Bike Safety.

What it does

The checker asks where the rider goes, their age, the ride date and the bike's specs. A family can enter the facts, paste a product link or read a class-label photo. Extracted facts show the words they came from and remain editable.

It gives a YES or NO for each checked place and an overall answer, with reasons, source links and dates. NO distinguishes a prohibited ride from one the app cannot confirm. It names city, county and school rules that have not been checked.

The same engine powers a modification checker and a bike finder with 29 catalog models. The map shows racks, shops and repair spots. A route checker examines streets and paths against the rider, bike, mapped restrictions and available jurisdiction rules, and can try an alternative around problem sections. Elevation and battery estimates help explain the trip; the battery model is explicitly labeled untested on real rides.

The interface works in English and Spanish, on a phone, without an account. A printable QR flyer makes it easy to share at a school or bike shop.

How I built it

I separated the application into fact extraction, a dated rules engine and presentation. OCR and the optional photo detector help read a bike. Deterministic TypeScript rules and translated templates produce the legal answers; a language model does not write a verdict.

The state table covers all 50 states and DC. The local layer covers San Diego County's 18 incorporated cities, unincorporated areas and SDUHSD campuses. Rules retain their citations, verification levels and effective dates. A ride outside the table's verification window cannot receive an unsupported YES.

For routing, Valhalla proposes a bicycle route, Census TIGERweb identifies the jurisdictions it crosses, and OpenStreetMap tags supply mapped restrictions. The app then checks the pieces against its rules. Leaflet draws the map, and Three.js provides the surrounding 3D experience.

Challenges I ran into

Photo classification was the clearest failed experiment. The first approach got 8 of 12 pedal calls right. A second got 18 of 24 and missed three machines without pedals. Both failed the criteria set before testing, so I left the feature out until a third approach passed.

The OWLv2 version got 23 of 24 held-out photos right, including all 12 machines without pedals. It remains an optional pedal check, asks the user on close calls and never decides legality by itself. That small test does not establish accuracy on everyday uploads.

Another challenge was preserving uncertainty. Conflicting manufacturer specs, missing facts, laws that change on a date and incomplete local coverage must stay visible instead of turning into a reassuring answer. Routing adds another boundary: a bicycle route returned by a mapping service is not automatically a route the app can confirm for this rider and bike.

Accomplishments I am proud of

The latest recorded suite passes 1,283 tests. Generated checks cover 758,280 engine cases and 1,003,920 complete rides, with zero false approvals against the separate reference checker. Those are generated test combinations, not observed trips. They show agreement with the project's rules data, not proof that the data captures every applicable law.

I also kept the failed photo experiments and their original pass criteria in the repository. The app exposes sources, uncertain facts and coverage limits to users, rather than hiding them behind a single confident answer.

What I learned

An answer needs a clear boundary: which facts it uses, which places it covers and which date it applies to. Separating those parts made errors easier to trace. I also learned to treat a failed evaluation as a reason to change or remove a feature, and to distinguish passing software tests from validating a legal interpretation or a battery estimate in the real world.

What's next

Next I would ask local cycling-safety and legal reviewers to examine the rules, expand field testing with riders and parents, and establish a regular data-refresh process. The battery estimate needs its planned real-ride test. I would also improve photo performance on phones and expand verified local coverage beyond San Diego County.

AI assistance

I chose the project, defined its scope, designed the architecture, selected the tech stack, and handled debugging and technical decisions. AI assistance was limited to writing implementation code from my instructions.

Libraries, APIs and data sources

The application uses TypeScript, JavaScript, Next.js, React, React DOM, Tailwind CSS, Node.js and Vercel. Its libraries include Leaflet, react-leaflet, Three.js, tesseract.js, qrcode and Hugging Face Transformers.js with OWLv2 and the browser's WebGPU API. Development and testing use Vitest, ESLint, tsx, Python unittest and DuckDB with httpfs.

External services include OpenStreetMap tiles, Overpass, Nominatim and Photon geocoding, FOSSGIS's Valhalla routing service, Census TIGERweb and QLever's OpenStreetMap endpoint. Hugging Face and jsDelivr serve model and library assets. Saved data includes Overture Maps, Census geographic and ZIP datasets, NCES school-district data, manufacturer specs and cited legal sources. OpenStreetMap contributors and Overture Maps are credited; source and license details are documented in the repository.

Built With

Share this project:

Updates

Submission history