Photo based repair approval for car workshops. Mechanics text a quote link, customers approve from their phone browser with no login or app.
A mechanic finds extra work mid service, such as a worn brake pad or a cracked hose. They photograph it, tag its severity red, amber, or green, set a price, and text the customer a link. The customer opens it in their phone browser with no login or app install, sees the photo and price, and taps approve or decline. The whole decision takes under two minutes.
MechanicPulse is in a time boxed validation trial ahead of incorporation, building toward a proof of concept gated by real checkpoints with workshops. I am the application developer on a 3 person team, owning the mechanic app and the customer report page, including upload reliability on poor mobile signal.
Both the mechanic tool and the customer page are browser only Next.js apps with zero install. Photos upload directly from the browser to a private S3 bucket through short lived presigned URLs, so the API never touches file bytes. The Fastify API uses raw SQL via pg against PostgreSQL on RDS, and every write that matters, sending a report or recording a decision, runs in an explicit transaction with row level locking to prevent double submits.
Mechanics sign in with email and password using bcrypt and JWT. Customers have no login at all. Security comes from a single use, high entropy token that is hashed before it is stored, so a database leak cannot be turned back into working customer links.
The biggest risk is not a missing feature but a photo that fails to upload on one bar of signal in a basement carpark. Testing on real devices in bad conditions surfaced an iOS Safari bug: WebP encoding silently fell back to PNG, making compressed photos larger rather than smaller. It was found and fixed before any pilot.
An append only events table records report sent, first open (race safe), and approval submitted. Time to decision and approval rate are available from the first customer link instead of being added after the pilot.
Keycloak was rejected for mechanic login because it is not needed at single tenant scale and costs an always on container. Phone OTP login was rejected because it adds an SMS dependency to a path that does not need one. Both are documented as revisit if conditions change, not simply dropped.
Expired link, revoked quote, and already decided report each render their own deliberate screen showing the workshop's phone number, the real fallback, instead of a generic error page.
| Service | Role | Status |
|---|---|---|
| AWS RDS (PostgreSQL) | Transactional, row locked writes and events table | Built |
| AWS S3 | Private photo storage via presigned URLs | Built |
| GitHub Actions | CI with Playwright on mobile Chrome and Safari | Built |
| SMS provider | Quote link delivery, Twilio or a local aggregator | Planned |