Skip to content
Erick Schaedler

In production

Carbase

An e-commerce platform for a car-tuning shop, with a credentialing pipeline for reseller applications and a page builder the client runs alone.

View live Opens in a new tab

The problem

The shop needed more than a catalog — a way to vet reseller applications before publishing them, and a way to change brand pages and promotions without opening a ticket for every edit.

What I built

A .NET and React platform covering catalog, cart and checkout; customer accounts with order history; a two-stage dealer pipeline that keeps vetting separate from what's shown publicly; and a block-based page builder for brand pages and promotions.

Carbase homepage: a tuned Ferrari with calls to action for the parts catalog and the reseller area.
Carbase homepage on mobile, showing the hero and the main navigation.

Technical decisions

Becoming a listed dealer is two separate steps, on purpose. A public application form collects the raw vetting data — tax ID, how long the business has been running, what they want to sell, why — and an admin reviews it through a status pipeline: new, in contact, approved or rejected. Approving an application does not automatically publish anything; putting a dealer on the public map, with a logo and curated contact details, is a separate, deliberate step. That gap exists so an approved-but-not-yet-onboarded partner never shows up half-finished on the public site.

A product lives in two taxonomies at once, and they don’t overlap. One is a vehicle-fitment tree — make, model, variant — that answers “what does this part fit.” The other is brand and category — who makes it, what kind of part it is — that answers “what is this.” The same suspension kit shows up whether someone browses by their car or by the brand that makes suspension parts, because the two trees are modeled and queried independently instead of forcing one into the other.

A page isn’t a template with fixed slots — it’s an ordered list of typed sections (banner, FAQ, product carousel, hero, text, and others) stored as data, which is what lets the client build a new brand page or a seasonal promotion from existing blocks without a deploy. System pages are flagged separately from client-created ones specifically so their URLs can’t be changed by accident, since those slugs are load-bearing elsewhere in the site.

Checkout runs its full flow — cart, address, shipping quote, order creation — against a payment provider interface rather than a specific gateway wired in directly. After the previous provider was removed, the interface still stands, and it reports itself as unavailable rather than pretending to process a card it can’t. Wiring in a new gateway later means implementing one interface, not touching the checkout flow that already works around it.

Product data can sync in from Akila, an external ERP, but only five fields are under its control — name, unit, price, cost price and stock — and the sync never touches anything else, including the product’s public URL slug, so a name change coming from the ERP can never break a link someone already shared. The moment an admin edits one of those five fields by hand, that specific field is marked unlocked and the next sync skips it — nothing has to be flagged manually, editing the field is the flag. The sync also protects itself against a messy feed: it won’t apply an incoming name that’s already used by another live product, and it won’t let a missing price from the ERP erase the price of an item that’s already for sale online.

Outcome

Running in production — 15 active brands across 11 categories, a public dealer directory, and content pages the client edits without touching code.

Stack

  • .NET
  • PostgreSQL
  • React
  • TypeScript
  • AWS S3