Skip to content

STDNT GEAR

B2B commerce platform where institutions self-serve branded apparel quotes — built solo, end to end.

Role
Founding Engineer (solo)
Timeframe
Apr 2024 — Present
ReactNode.jsExpressPostgreSQLRedisSystem Design
STDNT GEAR storefront hero with custom UCT-branded apparel and a call to design and quote
Customer storefront — hero and catalogue entry

At a glance

Institutions ordering custom apparel used to quote by email. STDNT GEAR lets buyers browse a real catalogue, configure designs, and generate priced quotes themselves — while staff keep final approval.

  • Solo-built, production-ready platform
  • Self-service quote wizard replaces email loops
  • 3,000+ products synced from vendor API
  • Server-locked pricing — quotes can’t be tampered client-side
0
PostgreSQL tables
~0
REST API endpoints
0+
products synced
0
frontends, 1 API

Clients

Customer storefront
Staff admin portal

API

Express REST — JWT auth

Data

PostgreSQL
Redis + in-memory cache
Vendor catalogue API

One API serves both frontends. A scheduled job keeps the catalogue in sync with the vendor.

Product

What shipped

Four connected surfaces — discovery, catalogue, quoting, and account tracking.

01

Storefront

Category-led discovery

02

Catalogue

Faceted search at scale

03

Quote builder

3-step wizard

04

Portal

PDF quotes + tracking

01

Storefront

The public site is the primary sales surface — not a landing page bolted onto admin.

Category-led discovery into the synced vendor catalogue.
Quote journey explained upfront for institutional buyers.
Past work builds trust with universities ordering at scale.
02

Catalogue & discovery

Cached category trees and parallel facet queries keep 3,000+ products fast to filter.

T-Shirts product listing with price and colour facet filters, sort control, and a grid of synced catalogue products
Price and colour facets with live counts on every product card.
Hierarchical navigation backed by the in-memory category cache.
Variant-level detail — swatches, sizes, and stock before personalization.
03

Quote builder

Three-step wizard with server-calculated totals at every step.

Step 1 — per-size quantities against live stock.

1 / 8
04

Submission & portal

Branded PDF quotes, reference numbers, and self-service status tracking.

Profile data pre-fills contact details.
Branded PDF quotation generated at submission.
Reference number confirmed at submission.
Customers track quote status without emailing the supplier.

For engineers

Technical deep dive

Problem context, engineering decisions, security hardening, and honest scope boundaries.

The problem

Schools, sports clubs, and corporate teams ordering branded apparel typically quote by email — slow, opaque, and hard to scale. STDNT GEAR replaces that with self-service quoting while staff retain manual approval before invoicing.

Role & scope

Solo engineer — every layer from schema to deployment:

  • PostgreSQL schema (27 tables) and Express REST API (~70 endpoints).
  • Customer storefront and staff admin portal (both React).
  • Vendor catalogue ingestion pipeline (3,000+ products, prices, stock, swatches).
  • Production deployment and operations.

Key engineering decisions

Vendor catalogue ingestion pipeline

Problem

The vendor API returns thousands of products with nested variants, prices, stock, and colour swatches. Naively inserting everything concurrently caused PostgreSQL deadlocks under load, and a single failed record could kill the whole sync.

Options considered
  • Single-threaded sequential inserts — safe but far too slow for a full catalogue refresh.
  • High concurrency (10+ parallel batches) — fast, but frequent deadlocks on shared indexes.
  • Smart batching with capped concurrency and per-operation retry.
Decision

Grouped products into batches of 50 (partitioned to reduce key overlap), capped concurrency at 2 in-flight batches, and wrapped every write in deadlock-aware retry with exponential backoff.

Trade-off

A full catalogue sync is slower than it could theoretically be, but it runs unattended and self-heals from transient PostgreSQL deadlocks instead of failing the whole job.

Server-authoritative pricing

Problem

Quotes and invoices involve price adjustments (staff discounts, corrections). If a client ever computed or held the authoritative total, a tampered request could change what a customer owes.

Options considered
  • Trust the price the client submits with the quote.
  • Recompute and lock the total server-side whenever a quote is priced or converted to an invoice.
Decision

Every quote total is calculated and locked server-side. Staff-applied adjustments are stored as discrete line items, not baked into a single mutable total, so invoice history stays auditable.

Trade-off

More server-side computation and stricter API contracts, in exchange for pricing integrity that can't be bypassed from the client.

Caching strategy for the product catalogue

Problem

Category trees and multi-facet product filters (brand, gender, material, fit, price) get slow at scale if every filter click hits PostgreSQL with fresh joins.

Options considered
  • No caching — simplest, but filter interactions get sluggish as the catalogue grows.
  • Cache everything in Redis from day one.
  • Layer caches by volatility: in-memory for near-static data, React Query for per-user UI state, Redis reserved for cross-instance needs.
Decision

Cache the category hierarchy in server memory with TTL + explicit invalidation on writes, run facet-count queries in parallel rather than sequentially, and let React Query handle client-side staleness.

Trade-off

In-memory cache doesn't survive a restart or share state across multiple server instances — acceptable for current scale, with Redis already integrated as the upgrade path.

Security & auth

JWT with short-lived access tokens and HttpOnly refresh tokens, plus optional Google OAuth. Account lockout after repeated failed logins, audit logging of auth events, and rate limiting on auth endpoints.

Hardest problems

Keeping a large, frequently-changing external catalogue consistent with an internal schema that also supports fast filtering. Deadlocks under concurrent writes, cache invalidation after syncs, and a quote data model flexible enough for arbitrary print positions without becoming an unstructured blob.

Deliberate scopeNo payment gateway or production-tracking system yet. Customers receive static EFT banking details by email, and fulfillment happens outside the platform. Quoting and invoicing were the highest-leverage problems to solve first.