This is your complete operator guide for Make Your Vehicle — how it works today, what's already configured, and exactly what's left to flip on for a full production launch.
Make Your Vehicle turns a text description (or reference photos) into a FiveM-ready vehicle resource. The workflow: create a project → describe it or upload images → AI analysis → 3D generation → configure handling, emergency lighting (ULC/ELS), and livery → validate → export a ZIP.
The app is fully functional right now using a mock AI provider, so every screen, job, and the FiveM export all work end-to-end without paid APIs. To ship a real product, you connect a real 3D-generation provider and move the database/storage to production services. Each of those is behind a clean provider abstraction, so switching is a config change — not a rewrite.
Do these, in order, to go from local demo to a live product:
NEXTAUTH_SECRET and your real domain in envFrom the project folder:
npm install npm run db:push # creates the local SQLite database npm run dev # http://localhost:9021
Open localhost:9021, create an account, and build a vehicle. New accounts get the Free plan (1 vehicle + 1 livery, 60 credits).
All configuration lives in .env.local. The important switches:
# Database — SQLite locally; a postgres URL for production DATABASE_URL="file:./dev.db" # Auth — set a strong secret & your real URL in production NEXTAUTH_SECRET="change-me" NEXTAUTH_URL="http://localhost:9021" # OAuth (optional) GOOGLE_CLIENT_ID="" GOOGLE_CLIENT_SECRET="" DISCORD_CLIENT_ID="" DISCORD_CLIENT_SECRET="" # AI providers — "mock" keeps everything offline AI_VISION_PROVIDER="mock" AI_MODEL_PROVIDER="mock" AI_TEXTURE_PROVIDER="mock" MESHY_API_KEY="" TRIPO_API_KEY="" # Storage — "local" or "s3" STORAGE_PROVIDER="local" # Stripe PAYMENTS_ENABLED="true" STRIPE_SECRET_KEY="rk_live_…" STRIPE_PUBLISHABLE_KEY="pk_live_…" NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY="pk_live_…" STRIPE_WEBHOOK_SECRET="whsec_…" STRIPE_PRICE_CREATOR="price_…" STRIPE_PRICE_PRO="price_…" STRIPE_PRICE_STUDIO="price_…"
Local dev uses SQLite for zero setup. Production should use PostgreSQL. Steps:
prisma/schema.prisma, set provider = "postgresql".DATABASE_URL to your Postgres connection string.src/lib/database/client.ts to @prisma/adapter-pg.npm run db:push (or set up prisma migrate).This is the one piece that makes the product "real." The app ships with a mock provider that simulates the full pipeline and produces a test resource. To generate actual 3D models, implement a provider that satisfies the ModelGenerationProvider interface and register it.
// src/lib/ai/providers/meshy.ts
export class MeshyProvider implements ModelGenerationProvider {
name = "meshy";
async generate(input) { /* call Meshy API, return job id */ }
async poll(jobId) { /* poll status, return model URL when done */ }
}
// src/lib/ai/index.ts — register & select by env
case "meshy": return new MeshyProvider();Then set AI_MODEL_PROVIDER="meshy" and add MESHY_API_KEY. The same pattern applies to vision (text/image → spec) and texture/livery providers.
A generated mesh is not automatically a FiveM vehicle. Production-grade output still needs the mesh processing pipeline (retopo, collisions, bones, LODs, YFT/YTD conversion). Budget for a GPU/processing service or manual finishing — the app structures and packages everything else around it.
Uploads (reference images, generated assets) are written to public/uploads locally. For production, set STORAGE_PROVIDER="s3" and implement the S3 branch in src/lib/storage/index.ts (the interface and local implementation are already there). Use signed URLs and a private bucket so assets aren't publicly listable.
Stripe is already connected — live keys are set, the Creator/Pro/Studio products exist, and checkout is embedded directly in the billing page(customers never leave the portal). The customer portal ("Manage Billing") is wired too.
The one remaining step for reliable production billing is a webhook on your live domain:
https://YOUR_DOMAIN/api/webhooks/stripecheckout.session.completed, customer.subscription.created/updated/deleted, invoice.payment_succeeded.STRIPE_WEBHOOK_SECRET.Note: upgrades already sync instantly on checkout return even without a webhook — the webhook is what keeps renewals, cancellations, and failed payments in sync automatically going forward. For local testing use the Stripe CLI: stripe listen --forward-to localhost:9021/api/webhooks/stripe.
By default, generation runs inline in the API route, so it works with zero infrastructure. For heavier real generation, run the dedicated Redis-backed worker:
# set REDIS_URL in .env.local, then: npm run worker
Runs on any Node host (Vercel, Railway, Render, a VPS). For production:
NEXTAUTH_SECRET, and your domain in NEXTAUTH_URL / NEXT_PUBLIC_APP_URL.npm run build npm start # serves on port 9021
Add the Stripe webhook pointing at your live domain, and you're live.
Being straight with you so there are no surprises at launch:
Everything around the generation core — accounts, billing, credits, project management, configuration, validation, and packaging — is production-shaped and ready.