A full-stack e-commerce application for print services marketplace with React frontend and Express backend.
- Frontend: React 19, TypeScript, Vite, Tailwind CSS, Radix UI, Zustand
- Backend: Express.js, TypeScript, Supabase (Database, Auth, Storage)
- Payments: Paystack
- Testing: Vitest, Playwright
- Database: PostgreSQL via Supabase
- Node.js 18+
- npm 9+
- Supabase account (for database & auth)
npm installCreate a .env file in the root directory:
# Supabase (Required)
VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key
# Optional legacy direct Postgres access
# Leave unset unless you are intentionally using the legacy postgres-store tooling.
DATABASE_URL=postgresql://user:pass@host:5432/database
DATABASE_SSL_MODE=require
# Paystack (Required for payments)
PAYSTACK_SECRET_KEY=sk_live_xxx
PAYSTACK_PUBLIC_KEY=pk_live_xxx
# Server
SERVER_PORT=3001
PUBLIC_SITE_URL=https://thewworksict.com
CORS_ALLOWED_ORIGINS=https://thewworksict.com
# Admin (Optional)
ADMIN_EMAILS=admin@example.com,another@example.com
VITE_ADMIN_EMAILS=admin@example.com,another@example.com
# Security
CSRF_SECRET=replace-with-openssl-rand-hex-32
ORDER_TOKEN_SECRET=replace-with-openssl-rand-base64-32
ORDER_STORE_ENCRYPTION_KEY=replace-with-openssl-rand-base64-32Generate fresh production secrets with:
npm run security:keys# Start both frontend and backend
npm run dev
# Start only frontend
npm run dev:client
# Start only backend
npm run dev:server- Frontend: http://localhost:3001
- Backend API: http://localhost:3001/api
# Build for production
npm run build
# Start production server
npm run startsrc/
├── components/ # React components
│ ├── admin/ # Admin dashboard components
│ ├── store/ # Marketplace components
│ └── ui/ # Reusable UI components (Radix)
├── hooks/ # Custom React hooks
├── lib/ # Core business logic
│ ├── store.ts # Cart state (Zustand)
│ ├── checkout.ts # Checkout utilities
│ ├── supabase.ts # Supabase client
│ └── ...
├── sections/ # Page sections
├── test/ # Test utilities
└── App.tsx # Main app component
server/
├── index.ts # Express server
├── lib/ # Server utilities
└── test/ # API integration tests
e2e/ # E2E tests (Playwright)
- Browse print services catalog
- Search and filter products
- Add to cart
- Secure checkout with Paystack
- Order verification via payment reference
- Email/SMS notifications
- Protected admin dashboard
- Analytics with metrics
- Product management (CRUD)
- Order tracking
- Inventory management
# Run all unit tests
npm run test
# Run unit tests once
npm run test:run
# Run unit tests with coverage
npm run test:coverage
# Run API integration tests
npm run test:api
# Run E2E tests
npm run test:e2e
# Run E2E tests with UI
npm run test:e2e:uiGET /api/health- Health check
GET /api/security/csrf-token- Issue signed CSRF token for browser mutationsPOST /api/checkout/initialize- Initialize checkoutGET /api/checkout/verify/:reference- Verify payment
GET /api/admin/me- Get current adminGET /api/admin/stats- Get dashboard statsGET /api/admin/products- List productsPOST /api/admin/products- Create productPUT /api/admin/products/:id- Update productDELETE /api/admin/products/:id- Delete product
POST /api/payments/paystack/webhook- Paystack webhook
categories- Product categoriesproducts- Product catalogproduct_galleries- Product image galleriesproduct_tags- Product tagssuppliers- Supplier informationorders- Customer ordersorder_items- Order line items
npm run lint
npm run test:run
npm run security:audit
npm run security:env:check:production
npm run security:supabase:check
npm run build
npm run start- Set up Supabase project
- Run all database migrations in timestamp order
- Configure production environment variables, including
NODE_ENV=production,PUBLIC_SITE_URL,CSRF_SECRET,ORDER_TOKEN_SECRET,ORDER_STORE_ENCRYPTION_KEY, andSUPABASE_SERVICE_ROLE_KEY - Configure Paystack webhook URL as
https://thewworksict.com/api/payments/paystack/webhook; Paystack signs webhook payloads with the live secret key inPAYSTACK_SECRET_KEY - Deploy to Railway. The repository includes
railway.jsonwithnpm run build,npm run start, and/api/health. - Attach
thewworksict.comandwww.thewworksict.comas Railway custom domains, then add the Railway DNS records at the registrar.
See docs/deployment.md for detailed deployment instructions.
For branded discovery on Google Search and Google Maps, keep these live after deployment:
- Verify
https://thewworksict.com/in Google Search Console and submithttps://thewworksict.com/sitemap.xml - Maintain a Google Business Profile for
Thewworks ICT & Printswith the same address and phone number used on the website - Keep the brand naming consistent across the site and listings:
ThewworksThewworks ICT & Prints
- Keep the location details consistent everywhere:
No. 5, Okelue Street, Opposite Wema Bank, by Nnebisi Road, Asaba, Delta State, Nigeria08123986155
See docs/seo.md for the full SEO runbook and indexing checklist.
Quick public checks after DNS is live:
Resolve-DnsName thewworksict.com
curl -I https://thewworksict.com/
curl -I https://www.thewworksict.com/
curl https://thewworksict.com/sitemap.xmlMIT