Skip to content

yalsabah/vincritiq

Repository files navigation

VinCritiq

AI-powered used-car deal analyzer. Upload a CARFAX PDF and a few photos of a vehicle, and VinCritiq returns a structured deal report — pricing vs. market, depreciation curve, financing math, vehicle history flags, an interactive 3D model, and a Great / Good / Fair / Bad verdict.

🌐 Live site: vincritiq.com


What it does

  • CARFAX + photo analysis — parse the report, classify title status, accident count, owner history, and service health.
  • Pricing intelligence — compare against KBB and market averages; surface % over/under and a structured price story.
  • Financing math — APR, term, down payment, monthly payment, total interest, total cost.
  • Depreciation curve — projected 1/3/5-year residual values for the specific year/make/model.
  • Verdict engine — heavy-flag rules (salvage, frame damage, 4+ owners, etc.) hard-cap the rating; price drives the base case otherwise.
  • Interactive 3D model — generated once per year/make/model/trim from a vehicle photo via Tripo3D, cached in Cloudflare R2, then re-served instantly to every future user querying the same vehicle.
  • Body-color swatches — repaint the 3D model in 8 preset colors via shader-injected per-pixel re-hueing.

Stack

  • Frontend: React 18 (CRA), Tailwind, Three.js / @react-three/fiber / @react-three/drei
  • Backend: Cloudflare Pages Functions (/functions/api/*)
  • Storage: Cloudflare R2 (3D model cache), Firebase Storage (vehicle photos)
  • Database & Auth: Firebase Firestore + Firebase Auth
  • AI: Anthropic Claude Sonnet (streaming, multimodal, prompt caching)
  • 3D pipeline: Tripo3D image-to-model API → R2 mirror for permanent URLs
  • Hosting: Cloudflare Pages

Run it locally

1. Prerequisites

  • Node.js 18+ and npm
  • Git
  • A Firebase project (free Spark plan is fine for local dev; Blaze required for Storage)
  • API keys for: Anthropic Claude, Tripo3D, optionally VinAudit and Vincario (VIN decode)

2. Clone and install

git clone https://github.com/<your-org>/vincritiq.git
cd vincritiq/carbot
npm install

3. Configure environment variables

Create carbot/.env (this file is gitignored). The dev proxy in src/setupProxy.js reads server-side secrets from this file and proxies them to the real upstream APIs so the browser never sees them.

# ── Server-side secrets (used by the dev proxy in src/setupProxy.js) ──
CLAUDE_API_KEY=sk-ant-…
TRIPO_KEY=tsk_…
VINAUDIT_KEY=…           # optional — VIN-image lookups
VINCARIO_KEY=…           # optional — VIN decode
VINCARIO_SECRET=…        # optional — VIN decode

# ── Public Firebase web config (baked into the client bundle) ──
REACT_APP_FIREBASE_API_KEY=…
REACT_APP_FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com
REACT_APP_FIREBASE_PROJECT_ID=your-project
REACT_APP_FIREBASE_STORAGE_BUCKET=your-project.firebasestorage.app
REACT_APP_FIREBASE_MESSAGING_SENDER_ID=…
REACT_APP_FIREBASE_APP_ID=1:…:web:…
REACT_APP_FIREBASE_MEASUREMENT_ID=G-…

Get the Firebase web config from Firebase Console → Project Settings → General → Your apps → Web app → SDK setup.

4. Set up Firebase

In the Firebase Console:

  1. Authentication → enable Email/Password and Google sign-in.

  2. Firestore Database → create in production mode, then publish these rules (Rules tab):

    rules_version = '2';
    service cloud.firestore {
      match /databases/{database}/documents {
        // Cross-user 3D model cache — slug-keyed, no per-user ownership.
        match /models3d/{slug} {
          allow read, create, update: if request.auth != null;
        }
    
        // Per-user chat sessions, messages, settings.
        match /users/{uid}/{document=**} {
          allow read, write: if request.auth != null && request.auth.uid == uid;
        }
      }
    }
  3. Storage (requires Blaze plan) → publish storage.rules from this repo.

  4. (Optional) Storage lifecycle → apply storage-lifecycle.json via gsutil to auto-delete user uploads after 90 days.

5. Start the dev server

npm start

Opens http://localhost:3000. The dev proxy starts automatically and prints a startup banner showing which API keys it loaded — if a key shows MISSING, double-check .env and restart.

6. (Optional) Deploy your own copy

This project deploys to Cloudflare Pages with a connected R2 bucket. Push to your fork, then in the Cloudflare dashboard:

  1. Pages → Create project → connect your repo, build command npm run build, output build/.
  2. Settings → Environment variables → add the server-side secrets as encrypted Secrets (CLAUDE_API_KEY, TRIPO_KEY, etc.). The Firebase REACT_APP_* values are already in wrangler.toml.
  3. R2 → create a bucket named vincritiq-models. The binding is declared in wrangler.toml.
  4. Settings → Custom domains → point your domain at the Pages project.

Available scripts

Script What it does
npm start Run dev server with proxy on localhost:3000
npm run build Production build into build/
npm test CRA test runner (interactive watch)

Project layout

carbot/
├── src/
│   ├── components/      # ChatInterface, ReportModal, RightSidebar, …
│   ├── contexts/        # Auth + Chat React contexts
│   ├── utils/           # claudeApi, model3d, pricing, pdfParser, …
│   └── setupProxy.js    # Dev-only API key proxy
├── functions/api/       # Cloudflare Pages Functions (production proxy)
│   ├── claude.js
│   ├── models/upload.js # Tripo → R2 mirror
│   ├── tripo/[[path]].js
│   └── vinaudit.js
├── public/
├── storage.rules        # Firebase Storage rules
├── storage-lifecycle.json
├── wrangler.toml        # Cloudflare Pages config + R2 binding
└── tailwind.config.js

Troubleshooting

  • auth/invalid-api-key on loadREACT_APP_FIREBASE_API_KEY missing/wrong; restart npm start after editing .env.
  • /api/claude 500 — Claude key missing in .env or hit the per-request size limit (the app compresses photos but very large CARFAX PDFs can still tip it).
  • 3D model stuck "pending" — likely Firestore rules don't allow update on models3d/{slug}. Re-publish the rules above.
  • CORS errors loading GLB — in dev the Tripo URL is routed through /dev-glb-proxy; in prod the GLB must be served from R2 (MODELS_PUBLIC_BASE env var must be set in the Cloudflare dashboard).
  • "Client is offline" warning on first load — benign. Firestore's WebChannel is still connecting; the code retries automatically.

License

Private project — all rights reserved.

About

React + Cloudflare Pages app that analyzes used-car deals via Claude (CARFAX + photo multimodal), generates 3D models via Tripo3D, and caches them in R2 by vehicle slug.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors