active

Zoya Outfits — Full-Stack E-commerce Platform

Production-ready e-commerce platform with OTP-based checkout, product attribute system, multi-location inventory, and a full admin dashboard.

Next.js 15 TypeScript Prisma PostgreSQL Tailwind CSS shadcn/ui Cloudflare R2 BetterAuth

Overview

Zoya Outfits is a production e-commerce platform I designed and built end-to-end for a fashion retailer in Saudi Arabia. It handles product catalog management, OTP-based checkout (aligned with regional payment flow preferences), order tracking, and a full back-office admin dashboard.

Key Features

Product Attribute System

Unlike typical e-commerce platforms with rigid size/color variants, Zoya required a flexible attribute system — products can have custom attributes (material, fit, origin) that differ by category.

model Attribute {
  id         String @id @default(cuid())
  name       String
  type       AttributeType
  categoryId String?
  values     AttributeValue[]
}

model ProductAttribute {
  productId   String
  attributeId String
  valueId     String
}

OTP-Based Checkout

Saudi market checkout flows rely heavily on phone number + OTP verification rather than email. I implemented a stateless OTP system using Redis TTL:

  • Customer enters phone number
  • OTP generated, stored in Redis with 5-minute TTL
  • SMS sent via Taqnyat API
  • On verification, session token issued

Media Storage with Cloudflare R2

Product images are stored in Cloudflare R2 with signed URLs for private access. A background worker handles image optimization on upload using Sharp.

// Signed URL generation (expires in 1 hour)
const url = await r2.sign(key, { expiresIn: 3600 });

Architecture Decisions

DecisionRationale
Next.js App RouterServer Components minimize client JS
Prisma + PostgreSQLComplex relational product schema
BetterAuthFlexible session management, easy OTP extension
Cloudflare R2No egress fees, Cloudflare CDN integration
Server ActionsAvoid exposing API keys to client

Lessons Learned

Building a production platform from scratch forced me to think carefully about data modeling upfront. The attribute system in particular required several schema iterations before it was flexible enough for the retailer’s catalog without becoming unmaintainable.

The OTP checkout flow also revealed an important lesson: regional payment and authentication patterns matter. Generic e-commerce templates optimized for Western markets don’t map well to GCC buyer behavior.