LUMEN/lore
React ECommerce Website with Print-on-Demand Integration
Full-Stack Developer & Product Owner
- Shipped a real production React/Next.js storefront with Stripe checkout
- Solved valid print options problem: users only see sizes/orientations that work
- Built cost-aware platform with CloudWatch monitoring wired to SMS/email alerts
Overview
Lumen & Lore is an independent project I built to do two things at once: get my artwork out into the world, and learn React/Next.js the right way—by shipping a real production application. It's a working e-commerce site for my watercolour paintings and photography, with print-on-demand fulfillment and a full checkout flow.
I treated it like a real product: build a clean user experience, keep the backend reliable, make deployments repeatable, and add monitoring so problems don't silently sit there.
My role
This was a true end-to-end build. I owned:
- UI/UX design and frontend implementation (React + Next.js)
- Backend services and integrations (Express on AWS Lambda behind API Gateway)
- Product data modeling (DynamoDB) and "admin" workflows to manage catalog updates
- Stripe payments (end-to-end tested)
- Hosting, CDN, DNS, deployment, and infrastructure
- Monitoring and alerting (front + backend) wired to SMS/email notifications
What I built
Customer-facing storefront + checkout
The site supports browsing, product selection, and a complete checkout flow using Stripe, tested end-to-end. The goal was a storefront that feels simple and dependable—no weird edge cases, no confusing choices, no "why is this an option?" moments.
Print-on-demand option logic
I used the GelatoAPI to handle print-on-demand products. The biggest UX challenge wasn't layout—it was correctness. Print-on-demand products have constraints based on image size and orientation (portrait/landscape/square). The site needs to show only the options that actually make sense for that specific item.
I built logic that retrieves the correct print options for each product and displays only valid choices to the user—so people can't select combinations that won't work. This is one of those features that feels invisible when it's done well, but it's the difference between a smooth purchase and a frustrating one.
DynamoDB-first data model (cost-aware by design)
I intentionally kept the data layer on DynamoDB—no SQL database—so the platform stays cost-effective while still supporting the product and order workflows. The constraints around print options (sizes/orientations) are handled in the DynamoDB-driven model and service logic, rather than relying on relational joins.
Technical approach (high level)
This project uses a modern web stack with a pragmatic production setup:
- Frontend: React + Next.js
- Backend services: Express.js running on AWS Lambda
- API layer: AWS API Gateway
- Data: DynamoDB (products, orders, and option constraints)
- Hosting/CDN: S3 + CloudFront distribution
- Payments: Stripe integration (tested end-to-end)
- Observability: CloudWatch monitoring across frontend/backend, tied into alerting via SMS/email
- Delivery: Infrastructure and deployments managed through repeatable scripts/IaC patterns
I also used GitHub Copilot heavily—but in a "tool, not autopilot" way—guiding it through each iteration and staying strict about security, stability, and keeping the code readable.