Skip to content

About

Custom t-shirt design & ordering MVP built with Next.js 15, TypeScript, Tailwind CSS, Prisma/Postgres, Stripe, and CustomCat fulfillment.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

creativetees.io

Production-oriented MVP for a custom t-shirt design and ordering platform built around CustomCat fulfillment.

1) Architecture Proposal

Core stack

  • Next.js 15 + App Router + TypeScript
  • Tailwind CSS for UI
  • PostgreSQL + Prisma ORM
  • NextAuth (credentials-based baseline)
  • Stripe Checkout + webhooks
  • CustomCat provider abstraction (mock/live)
  • Object storage abstraction (local or S3-compatible)

High-level flow

  1. Catalog sync job fetches CustomCat products + variants and caches to ProductCache / ProductVariantCache.
  2. User designs shirt in a unified DesignerStudio UI (product + color + size + qty + upload + drag/resize inside print area).
  3. Designer saves a DesignSession, then creates CartItem with persisted transform + artwork metadata.
  4. User checks out in Stripe Checkout.
  5. Stripe checkout.session.completed webhook:
    • marks payment as paid
    • finalizes artwork asset from temp -> final storage URL (design_url)
    • creates local Order and OrderItem records
    • attempts CustomCat order submission
    • stores customCatOrderId or submissionError
  6. CustomCat webhook updates fulfillment and tracking status.
  7. Account + admin dashboards expose order state and operational health.

Service boundaries

  • src/lib/customcat/*: provider interface + live/mock adapters
  • src/lib/storage/*: local/S3 provider interface + implementations
  • src/lib/services/*: pricing, catalog sync, cart, checkout, fulfillment orchestration
  • src/lib/security/*: upload validation, webhook signature validation, simple rate limiting

2) Folder Structure

.
├── Dockerfile
├── docker-compose.yml
├── .env.docker
├── prisma
│   ├── schema.prisma
│   └── seed.ts
├── scripts
│   ├── docker/dev-start.sh
│   └── sync-catalog.ts
├── src
│   ├── app
│   │   ├── api
│   │   │   ├── admin/products/toggle
│   │   │   ├── auth/[...nextauth]
│   │   │   ├── auth/register
│   │   │   ├── cart
│   │   │   ├── cart/items
│   │   │   ├── catalog/sync
│   │   │   ├── checkout
│   │   │   ├── designer/session
│   │   │   ├── designer/upload
│   │   │   ├── orders/retry
│   │   │   └── webhooks/{stripe,customcat}
│   │   ├── account
│   │   ├── admin
│   │   ├── cart
│   │   ├── catalog
│   │   ├── checkout
│   │   ├── designer
│   │   ├── login
│   │   ├── orders/[orderNumber]
│   │   ├── orders/confirmation
│   │   ├── register
│   │   ├── globals.css
│   │   ├── layout.tsx
│   │   └── page.tsx
│   ├── components
│   │   ├── auth
│   │   ├── cart
│   │   ├── designer
│   │   ├── orders
│   │   └── ui
│   ├── lib
│   │   ├── auth
│   │   ├── customcat
│   │   ├── db
│   │   ├── jobs
│   │   ├── security
│   │   ├── services
│   │   ├── storage
│   │   ├── env.ts
│   │   └── utils.ts
│   ├── auth.ts
│   └── types/next-auth.d.ts
├── public/uploads/{temp,final}
└── .env.example

3) Prisma Data Model

Implemented in prisma/schema.prisma:

  • User
  • ProductCache
  • ProductVariantCache
  • DesignSession
  • Cart
  • CartItem
  • Order
  • OrderItem
  • Payment
  • UploadedAsset
  • WebhookEvent
  • AppSetting
  • ProductPricingRule
  • IntegrationConfig
  • NextAuth models (Account, Session, VerificationToken)

Includes required fields for:

  • catalog_sku, color, size, quantity
  • artwork URL + transform JSON
  • mockup preview URL
  • Stripe IDs
  • CustomCat order ID
  • fulfillment status + tracking

4) Environment Template

Use .env.example. Core keys:

  • app: APP_BASE_URL, APP_SETTINGS_ENCRYPTION_KEY
  • database: DATABASE_URL
  • auth: NEXTAUTH_SECRET, NEXTAUTH_URL
  • stripe: STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET, NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY
  • customcat: CUSTOMCAT_MODE, CUSTOMCAT_API_BASE_URL, CUSTOMCAT_API_KEY, CUSTOMCAT_WEBHOOK_SECRET
  • storage: STORAGE_PROVIDER + optional S3_*

5) CustomCat Service Abstraction

See:

Interface includes:

  • getCatalogProducts()
  • getCatalogCategories()
  • getProductVariants(productId)
  • getCatalogSkuDetails(catalogSku)
  • createOrder(payload)
  • getOrderStatus(customCatOrderId)
  • handleWebhook(payload)

6) Catalog Sync Job

7) Designer Interface

Main component: src/components/designer/designer-studio.tsx

Features:

  • unified left/center/right workflow UI
  • product/color/size/qty selectors
  • upload PNG/JPG with validation + low-resolution warning
  • bounded print area with drag + resize controls
  • alignment + scale controls
  • save design session + add configured item to cart

7.5) Admin Backend (WordPress-Style Navigation)

Admin area uses a left-sidebar navigation model similar to WordPress at /admin:

  • Dashboard overview
  • Content manager (/admin/content) to edit homepage copy
  • Pricing manager (/admin/pricing) for global markup/shipping + per-product markup overrides
  • Integrations manager (/admin/integrations) for Square, Stripe, CustomCat, storage, and other connection settings
  • Operations page (/admin/operations) for catalog sync, webhook logs, product visibility, and retrying failed submissions

8) Cart + Checkout Flow

9) Stripe Integration

10) Automatic CustomCat Submission After Payment

Fulfillment orchestrator: src/lib/services/order-fulfillment.ts

Behavior on paid webhook:

  • finalize artwork asset to permanent storage URL
  • create local order/payment records
  • submit to CustomCat automatically
  • mark failures for admin retry (/api/orders/retry)

11) Webhook Handlers

Both store WebhookEvent records for audit/debug.

12) Seed Data + Setup

npm install
cp .env.example .env
# configure DATABASE_URL, NEXTAUTH_SECRET, Stripe keys, etc.

npx prisma generate
npx prisma migrate dev --name init
npm run prisma:seed
npm run dev

Seed creates:

  • admin user (from ADMIN_EMAILS first value) with temporary password ChangeMe123!
  • product/variant cache via CustomCat provider (mock by default)

13) Docker Quick Start (Recommended)

Run everything (app + Postgres) with Docker:

docker compose up --build

Then open:

Useful Docker commands:

# stop containers
docker compose down

# stop and remove volumes (full reset)
docker compose down -v

Notes:

  • Docker uses .env.docker by default.
  • App runs on host port 3001 so it will not conflict with an existing localhost:3000.
  • Postgres is exposed on host localhost:5433.

14) Local (Non-Docker) Development Steps

  1. Start Postgres and set DATABASE_URL.
  2. Run Prisma generate + migrate/db push.
  3. Seed DB.
  4. Run app (npm run dev -- --port 3001 if 3000 is occupied).
  5. For checkout testing, run Stripe CLI forwarding webhooks to /api/webhooks/stripe.
  6. For scheduled sync, trigger POST /api/catalog/sync via cron using CRON_SECRET.

15) Explicit TODOs / Endpoint Confirmation

  • src/lib/customcat/live-provider.ts
    • TODO: confirm final CustomCat endpoint paths + exact payload/response field names.
  • src/lib/services/order-fulfillment.ts
    • TODO: align final CustomCat order payload format with production contract.
  • Fraud controls
    • TODO: replace baseline signal flags with external fraud scoring/rules.

Notes

  • API keys are never exposed to the browser.
  • Designer flow is the primary path; catalog/cart/checkout support it.
  • CUSTOMCAT_MODE=mock allows local development without live credentials while preserving production interfaces.

About

Custom t-shirt design & ordering MVP built with Next.js 15, TypeScript, Tailwind CSS, Prisma/Postgres, Stripe, and CustomCat fulfillment.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages