MechanicAI

Case Study

Full-Stack · AI · SaaS · Rails

MechanicAI

A production-grade Rails API powering an AI car diagnostics platform. Auth, billing, rate limiting, and GPT-5 integration — built from scratch and deployed in 12 days.

RoleSolo Developer
StackNext.js · Rails · PostgreSQL · OpenAI
BillingPaddle
DeployHeroku
Problem

The gap between
symptom and answer

Most people can't interpret what their car is actually doing wrong. They either rush to a mechanic with no context — and risk being overcharged — or ignore symptoms until something fails entirely.

Generic search results don't account for specific symptom combinations. The problem isn't a lack of information. It's a lack of contextual, structured information that leads to a clear action.

MechanicAI takes a plain-language description and returns a structured diagnosis: severity, probable cause, and a clear recommendation — DIY, mechanic, or urgent. The backend is the engine making that possible.

Rushing to a mechanic with no prior context increases the chance of being overcharged

Ignored symptoms compound into expensive failures over time

Generic search results don't account for specific symptom combinations

No clear signal: is this a $10 fix, a scheduled visit, or a tow-truck situation?

Goals

Intentional from day one

01

Build a production-grade Rails API.

02

Integrate GPT-5 mini/nano in a way that produces genuinely useful, structured diagnostic output, not conversational filler.

03

Implement auth and billing that work for a decoupled frontend.

04

Ship, deploy, and harden with rate limiting, validation, and free/pro plan gating before calling it done.

Tech Decisions

Every choice deliberate

The project started with Devise, the Rails default, and hit a wall on day one. Devise redirects to Rails views on email verification, which breaks entirely when the frontend is a separate Next.js app. The migration to Rodauth happened on day three.

Rodauth is lower-level but gives full control. Overriding the verification URL to point to Next.js, configuring httpOnly cookie sessions, and setting up account locking all became straightforward. The migration was painful, but the result is clean. The lesson: for any decoupled frontend, start with Rodauth.

Devise assumes a monolith. For a decoupled frontend, that assumption breaks immediately.

Challenges

Problems worth solving

The migration from Devise to Rodauth happened on day three, before authorization, billing, or deployment. That timing was painful but correct. Absorbing the cost early, while the schema was still simple and the frontend wasn't consuming the API yet, was far cheaper than migrating later.

The fix required overriding the email verification URL, rebuilding the session layer around httpOnly cookies, and re-adding account references to the Car and Chat models. After the migration, nothing fought the library.

Devise's redirect-on-verify behaviour is invisible in a monolith and immediately breaking in a decoupled architecture.

Retrospective

What I'd do differently

01 / Auth

Start with Rodauth

The Devise migration cost a full day and introduced risk at a foundational layer. For any API with a decoupled frontend, Rodauth is the correct starting point — don't validate the default just because it's the default.

02 / API Design

Enforce a consistent error shape from day one

The errors → error rename happened after the frontend was consuming the API. A base responder or shared concern in the initial setup prevents this class of change entirely and keeps the contract clean.

03 / Security

Rate limiting before deployment

Rack::Attack and resource ownership validation belong in the initial build. The sequence should always be: auth, validation, rate limiting, then deploy — not the other way around.

Results

Shipped

Full auth flow: registration, email verification, login, logout, password reset, and account deletion

4-step AI diagnostic session with structured JSON output and persistent conversation history

Free and Pro subscription tiers with Paddle lifecycle handling and gated feature access

Rack::Attack rate limiting, content validation, and account-scoped resource ownership enforcement