RSJ
An online parts store's problem isn't having inventory, it's that the customer doesn't speak the catalog's language. We built RSJ for Refaccionaria San José by flipping that relationship: the customer picks their vehicle (make, model, year) and our system shows everything that fits, with live price and stock. To do it we stood up a headless three-piece architecture: a Next.js storefront with 68 routes and 174 components, a MedusaJS backend with a custom catalog module of 6 tables, 22 endpoints and 4 sync jobs, and a PayloadCMS layer so marketing can edit the site without touching code, and we deeply integrated the wholesaler's two APIs (catalog and vehicle fitment) with resilient OAuth, an anti-concurrency mutex, backoff retries and caching. The proof is in the scale: a target catalog of 40,000+ products and 120,000+ vehicle applications, ~36,687 products already standardized by a 22-script ETL pipeline, Stripe checkout, 4 mapped branches, all deployed to staging with environment-based CI/CD.
Category
E-Commerce
Stack
Next.js, TypeScript, PostgreSQL
Status
In development
The problem
Buying auto parts online in Mexico forces the customer to already know the exact part name or code they need: brake pad, seal, belt, catalog number. Anyone who isn't a mechanic gives up and ends up calling or driving to the counter. For a parts retailer with four branches and tens of thousands of SKUs sourced from the wholesaler, that's lost sales every day and a catalog so large nobody can browse it.
What we built
- —Search-by-vehicle (the flagship feature): cascading make → model → year dropdowns that return every compatible part, with filters by category, system, brand and availability, price/name sorting and server-side pagination.
- —Custom catalog module in MedusaJS integrating the wholesaler's two APIs: catalog (pricing, stock and images) and vehicle fitment (by make/model/engine/year).
- —Vehicle-fitment client with OAuth authentication, a 55-minute token TTL guarded by a mutex against concurrent logins, exponential-backoff retries and automatic token invalidation on 401.
- —6-table data model (product, brand, car model, vehicle-product, product application, sync log) with fitment indexes and unique keys.
- —4 sync jobs: catalog, vehicle applications, vehicles and images, feeding a search layer with in-memory caching (1-hour TTL).
- —Full module API: 12 store endpoints and 10 admin endpoints for makes/models/years, vehicle search, dynamic filters, product detail and sync control.
- —Dedicated automotive category pages (brakes, engine, electrical, suspension, lubricants, filters, body) plus product detail with gallery, price, stock and a fitment table.
- —Branches with interactive MapLibre maps: 4 locations across the Guadalajara metro area with hours, click-to-call and direct WhatsApp.
- —Complete Stripe Elements checkout, user accounts (profile, address book, order history) and order transfer between users via a shared token.
- —Fully built PayloadCMS: 7 collections, 2 globals and 7 content blocks (Hero, featured products, banners, rich text, grids, carousel, CTA) to manage the site without touching code.
- —An ETL pipeline of ~22 scripts to download, deduplicate, normalize and transform the wholesaler catalog into Medusa's import format.
- —Environment-based CI/CD (develop=build, staging=deploy staging, main=deploy prod) with selective per-component change detection, managed secrets and deployment of 3 containers.
Results
Target catalog: 40,000+ products and 120,000+ vehicle-fitment applications from the wholesaler
Backend: catalog module with 6 tables, 22 API endpoints (12 store + 10 admin) and 4 sync jobs
Storefront: 68 routes and 174 components across 23 modules
CMS: 7 collections, 2 globals and 7 content blocks
ETL: ~22 pipeline scripts to normalize the supplier catalog
4 physical branches with interactive maps
Deployed to staging (preview.refaccionariasanjose.com) since 2026-02-02; ~36,687 wholesaler products already standardized to populate the catalog