A real, revenue-carrying ecommerce site for a research-chemical supplier. Rather than walk through the product, this is an outline of what it is built from and what keeps it running — which is the part that transfers to other work.
Build stack
| Layer | Choice |
|---|---|
| Framework | Next.js 14, static build |
| Language | TypeScript |
| Catalog, orders, customer vault | Headless Shopify |
| Payments | Stripe |
| Infrastructure as code | Terraform |
| CI/CD | GitHub Actions |
Keeping catalog and checkout in headless Shopify was the first significant decision. Card data and PCI scope never enter my infrastructure. Less control, dramatically less liability — a trade worth making every time for a small operator.
AWS infrastructure
Everything runs in a dedicated AWS account created under AWS Organizations, fully separated from any personal account: isolated billing, IAM, and resource boundaries.
Edge and delivery
- Route 53 for DNS
- CloudFront as CDN, serving the static build from S3
- ACM for TLS
- Lambda@Edge for auth and geo rules
Application and data
- Lambda for Shopify and Stripe webhook handling
- DynamoDB for orders and customer records
- Cognito for customer authentication
- S3 with signed URLs for certificates of analysis and safety data sheets, so compliance documents are never publicly listable
- SES for transactional mail
Observability
- CloudWatch for logs and metrics
- CloudTrail for the audit trail
- Sentry for application errors
Deployment and day-to-day management
- Terraform state in an S3 bucket with a DynamoDB lock table, inside the same account it manages
- GitHub Actions assumes a cross-account role via AWS OIDC federation — no long-lived AWS access keys anywhere in CI
- Human access through AWS SSO rather than IAM users
- Roughly 90 commits of iteration to date
The OIDC decision is the one I would defend hardest. Static access keys in CI are the single most common way small teams leak credentials, and removing them costs about an hour of setup.
The part that took the thinking
Not the storefront — the boundary drawing. Deciding what lives in Shopify, what lives in my account, and what is allowed to cross between them. For regulated products, the document handling and the audit trail matter considerably more than the checkout flow.
The code belongs to the client, so it stays closed.