Case study
DemoOnline store for a small business
A full-stack online store for a fictional small business: catalog, cart, checkout, customer accounts, and an admin dashboard.
- Role
- Planning, development, testing, and deployment
- Demo name
- Lumbung Kabut
- Stack
- Next.js 16
- TypeScript
- Tailwind CSS 4
- Drizzle ORM
- SQLite
- Better Auth
- Zod
- Caddy
- Source code
- View on GitHub: Online store for a small business (opens another site)tenmaryut/toko-online-umkm
The business in this demo is fictional. The data in it is not real.


The problem
Many small businesses depend entirely on marketplaces. Their own store gives them control over the look, customer data, and the relationship with buyers, but it still has to be easy to use: products that are easy to find, shipping costs that are clear up front, and orders that are easy to manage.
The solution
The store is built with Next.js 16 (App Router), Drizzle ORM, and an SQLite database. Shoppers can search and filter products, keep a persistent cart, and check out with flat shipping rates per zone and a simulated payment.
The owner gets a dashboard with a sales chart, product and stock management, and order status updates from paid, packed, and shipped to completed.
Key features
- Catalog with categories, search, price and availability filters, sorting, and prices in Indonesian Rupiah
- A cart that survives page reloads
- Checkout with flat shipping per zone (38 provinces, 4 zones) and simulated payment; stock decreases when an order is placed
- Customer accounts: sign-up, sign-in, order history with a status timeline, and cancellation
- Admin dashboard: 14-day sales chart, products with image uploads, categories, order statuses, and customers
- Demo customer and admin accounts, with data reset automatically every night
- Shopping animations: add-to-cart confirmation, a mini cart, catalog skeletons, toasts, an order timeline, and dashboard numbers that count up
Animation clip
Technical challenges
Stock that stays consistent
Orders are created and stock is reduced in a single database transaction guarded by a CHECK stock ≥ 0 constraint, so stock cannot go negative when two shoppers check out at the same time. Cart prices and stock are always recalculated from the database.
Security enforced on the server
Every input is validated with Zod, admin access is checked in the layout and in every Server Action, sign-in, sign-up, checkout, and admin actions are rate limited, and every page uses a CSP with a per-request nonce.
Safe image uploads
File contents are inspected with sharp rather than trusting the extension, uploads are capped at 2 MB, then converted to WebP without EXIF metadata and stored outside the build folder.
A locked-down service
The standalone Next.js build runs as a non-root systemd service (DynamicUser) with ProtectSystem=strict, PrivateTmp, and NoNewPrivileges; systemd-analyze security rates it 1.2 (OK). The demo admin only sees customer data in masked form.
Test results
Lighthouse (mobile)
Home page
Measured page: /
Product page
Measured page: /produk/kopi-arabika-lereng-pagi
Measured on October 3, 2026 with Lighthouse 13.5.0 in mobile mode, directly against the live site. Scores can vary slightly between runs.
Automated tests
- Unit tests: cart, shipping, price formatting, validation, orders and stock Vitest51
- End-to-end tests: browsing to checkout, admin order status updates, security, and animations Playwright16
67 tests in total, all passing according to the project’s test report from October 3, 2026.