Production commerce case study

LadyShelf

I designed a commerce system that treats inventory, money, identity, and operations as correctness problems, not just screens to build.

Role System design, full-stack delivery, and production operations
Stack Next.js, TypeScript, Django REST Framework, Supabase, PostgreSQL
Core constraint Never trust browser prices, stock, identity, or payment state
Delivery state Live backend; final auth and owner workflow verification tracked openly
LadyShelf fashion commerce storefront interface

Engineering brief

The goal was not merely to complete a checkout. It was to preserve business invariants when two customers want the last item, a payment callback arrives twice, an external provider fails, or an operator needs to understand and recover the system.

OwnershipProduct architecture through deployment
SurfacesCustomer storefront, REST API, staff portal, operations
Evidence111 backend test methods, migrations, runbooks, health checks

System boundary

I split the product by responsibility. Next.js owns presentation and interaction; Django owns commerce rules; PostgreSQL owns durable state; Supabase supplies identity; payment and image providers remain replaceable external dependencies. That boundary prevents client state from becoming business truth.

  1. 01Next.js storefrontBrowse, cart, account, checkout, staff UI
  2. 02Django REST APIAuthorization, validation, orchestration
  3. 03PostgreSQLCatalog, stock, orders, payments, audit state
  4. 04External servicesSupabase identity, SasaPay, email, image generation

Critical decisions

Decision 01 / Consistency

Re-price and reserve stock inside one database transaction

The API rebuilds every quote from current product and delivery data. During order creation it locks variants, checks availability again, creates the order snapshot, and decrements stock atomically.

Why it matters: browser prices cannot be forged, and concurrent checkouts cannot silently oversell the same variant.

Decision 02 / Payments

Treat payment as a state machine, not a redirect

Checkout initiation reuses an existing pending transaction. Callbacks lock the payment record, verify successful transactions with the provider, tolerate duplicate delivery, and flag late payment after an order has expired.

Tradeoff: more domain state and tests, in exchange for traceable outcomes when networks retry or reorder events.

Decision 03 / Identity

Separate authentication from the commerce profile

Supabase owns sessions and identity. Django validates signed tokens and hydrates a local customer keyed by the stable subject claim, while retaining ownership of addresses, orders, permissions, and business history.

Why it matters: the identity provider can evolve without pushing commerce rules into authentication metadata.

Decision 04 / Operations

Model staff work as a first-class product surface

Owner and attendant roles have explicit permissions. The custom portal covers orders, manual payments, inventory, customers, staff, settings, and image review instead of making operators manipulate raw records.

Why it matters: operational usability and least privilege are part of system correctness.

Failure design

01

Commit before side effects

Emails and receipts run after a successful database commit, so a notification failure cannot roll back a valid order or announce one that never persisted.

02

Recover abandoned inventory

A scheduled command locks expired unpaid orders, cancels them, restores stock, and records the transition for operators.

03

Make AI work reviewable

Image jobs use explicit states, row-level claiming, bounded exponential backoff, quota-aware retry timing, human approval, and rollback of partially copied assets.

Production posture

ConcernImplemented evidenceBoundary
RuntimeGunicorn container, read-only filesystem, dropped capabilities, CPU and memory limitsDeployed
NetworkCloudflare to Nginx to loopback-only API; database has no host portDeployed
ReleaseImmutable image reference, explicit migrations and roles, health-checked release scriptRepeatable
RecoveryRestricted PostgreSQL backups, retention, timers, structured logs, error emailOff-site restore drill pending
LaunchDeployment handoff records revision, image digest, infrastructure, evidence, and risksAuth and owner-flow verification open

Senior engineering includes naming incomplete work. The deployment is real, but I do not describe it as fully launch-ready while Supabase token verification, owner-facing browser checks, and off-site recovery evidence remain tracked.

What this demonstrates

  • Translating product flows into explicit domain invariants and transactional boundaries.
  • Designing for concurrency, retries, partial failure, authorization, and operational recovery.
  • Making deployment state reproducible and reviewable through scripts, health checks, environment contracts, and handoff documentation.
  • Balancing a personal-project budget with production-minded controls, while documenting the risks that remain.
System designTransactional commerceDjango REST Framework Next.jsPostgreSQLPayment workflowsRBAC Docker hardeningObservabilityOperational runbooks
Back to Projects Previous Case Study: SceneIt