A store needed online ordering and in-store operations on one platform — a website, a self-service kiosk, a tablet POS and an admin dashboard — designed, built and run by a single developer.
Constraints
Sole developer across frontend, backend, database and deployment
Concurrent checkout without race conditions
Real payments with iDEAL and cards
Trilingual customer-facing website
Receipt printing on ESC/POS hardware from the browser
Decisions
D1
Dual-axis order state machine
Order state is modelled as an explicit state machine and enforced by the API.
D2
Idempotency keys + advisory locks
Eliminate race conditions when checkouts arrive concurrently.
3-party recruitment platform for the Japanese market — connecting agencies, companies and candidates through dedicated portals per role (agency, manager, visitor).
Cut · 5 levels
L1INTERFACE
Agency portalD1
Manager portal
Visitor portal
L2FE ARCH.
Shared packagesD2
L3CLIENT DATA
State & data
L4API
NestJS REST APID3D4
L5DATA
MongoDB
Deeper levels: not in this role
Role
Fullstack — monorepo FE architecture + REST API endpoints & JWT auth on BE
Surfaces
Agency portal · Manager portal · Visitor portal
Period
≈ 2025–2026 · about 1 year
Stack
Vue 3 · TypeScript · Feature-Sliced Design · Pinia · TanStack Query · Turborepo · pnpm workspaces · Element Plus · Vite · NestJS · MongoDB · JWT · REST API
Problem
A three-party recruitment platform for the Japanese market: agencies, companies and candidates each need a dedicated portal on the same product.
Constraints
Three role-specific portals — agency, manager and visitor
Frontend architecture and backend endpoints owned in one role
Token-based authentication with access and refresh tokens
Decisions
D1
One monorepo for three portals
Portals and shared packages live in a single Turborepo + pnpm workspace.
D2
Feature-Sliced Design
One layering convention for every portal's codebase.
D3
REST endpoints in NestJS
Built and maintained API endpoints with NestJS and MongoDB.
D4
Access / refresh token auth
JWT authentication flows implemented on the backend.
Stack, from the interface to the server it runs on.
L1 ▽ ±0.00 · A-201
Interface
Multi-portal web apps, a trilingual SSG site, kiosk and POS surfaces.
0807060405030201
20182020202220242026
L1 over time: 8 projects pass through it.
Core
Vue 3 · Banh Mi Daily, EngiHire (Engilink)
Nuxt 4 · Banh Mi Daily
TypeScript · Banh Mi Daily, EngiHire (Engilink)
Working
TailwindCSS
Element Plus · EngiHire (Engilink)
Ant Design Vue · Banh Mi Daily
PWA · Banh Mi Daily
Web Bluetooth · Banh Mi Daily
8 projects pass through this level: Aconcept, Learningift, Rectelework, Learningpocket, JSIC, Engibase Suite, EngiHire (Engilink), Banh Mi Daily.
L2 ▽ −2.20 · A-202
Frontend architecture
Several portals in one codebase with clear module boundaries and shared UI.
0706030201
20182020202220242026
L2 over time: 5 projects pass through it.
Core
Feature-Sliced Design · Banh Mi Daily, EngiHire (Engilink)
Monorepo (pnpm + Turborepo) · Banh Mi Daily, EngiHire (Engilink)
Working
Design Systems
Vite · EngiHire (Engilink)
5 projects pass through this level: Learningift, Rectelework, Engibase Suite, EngiHire (Engilink), Banh Mi Daily.
A-301 · Detail 01 · Scale 1:5
Share the right boundaries
Which responsibilities can change independently?
Three portals build from the same packages/ workspace. A change in packages/ reaches all three; a change inside one portal’s feature slice stays in that portal.
Three EngiHire portals share packages in one workspace, with clear frontend and API responsibilities.
※ Simplified illustration of a documented decision.
L5 ▽ −8.80 · A-205
Data & consistency
Orders that stay correct when checkouts arrive at the same time.
0201
20182020202220242026
L5 over time: 2 projects pass through it.
Core
PostgreSQL · Banh Mi Daily
Prisma · Banh Mi Daily
MongoDB · EngiHire (Engilink)
Working
Mongoose
Order state machine · Banh Mi Daily
Idempotency keys · Banh Mi Daily
Advisory locks · Banh Mi Daily
2 projects pass through this level: EngiHire (Engilink), Banh Mi Daily.
A-305 · Detail 05 · Scale 1:5
Make state explicit
Which changes is an order allowed to make?
An order carries two states, orderStatus and paymentStatus, and the API owns both. It accepts the changes the machine allows and refuses the rest, such as COMPLETED before READY.
Model domain rules where they can be enforced. In Banh Mi Daily, the API owns the order state machine.
Order · orderStatus
RECEIVED
Order recorded, not yet in the kitchen
PREPARING
The kitchen is preparing it
READY
Ready, waiting for the customer to collect it
COMPLETED
The customer has collected the order
CANCELLED
Cancelled on purpose
EXPIRED
Expired on its own when the hold time ran out
Payment · paymentStatus
UNPAID
Not paid yet
PENDING
Waiting for the payment to be confirmed (every payment passes here until it is)
PAID
Payment received
FAILED
Payment failed, was cancelled or expired; no payment attempt is active
GitHub Actions CI runs lint, typecheck, tests and PostgreSQL E2E
API runs in Docker behind Nginx on a VPS
Site and images served from Cloudflare Pages and R2
※ Schematic of documented responsibilities. Not live traffic.
A-501 · Revisions
Career — a history of building.
HTML and jQuery, Vue components on Laravel APIs, nearly six years of frontend architecture with backend work alongside, and now a platform built and run end to end.
20182020202220242026
FreelancerMangoAdsEzbookGroot Co., LtdBanh Mi Daily
Career from 2018 to 2026, as a dimension chain running down.
REV 5 · 06/2026 — Present
Full-Stack Developer
Banh Mi Daily · Freelance
Sole developer of an ordering & store-operations platform: trilingual Nuxt SSG website, self-service kiosk, tablet POS and admin dashboard, built as a pnpm/Turborepo monorepo.
NestJS, Prisma and PostgreSQL — dual-axis order state machine, idempotency keys and advisory locks to eliminate race conditions under concurrent checkout, server-authoritative pricing & VAT, JWT refresh-token rotation with RBAC, Sharp → Cloudflare R2 image pipeline.
Mollie payments (iDEAL & cards) with signature-verified, idempotent webhooks driving payment-status reconciliation and order confirmation.
Vue 3 / Nuxt 4, Ant Design Vue, TanStack Query with Zod validation at the API boundary, Feature-Sliced Design, PWA, ESC/POS receipt printing over Web Bluetooth.
Dockerised API behind Nginx on a VPS, Cloudflare Pages/R2, GitHub Actions CI (lint, typecheck, test, PostgreSQL E2E).