System Design
NestJS, Prisma, and PostgreSQL form one transactional core for the LINE Mini App and admin dashboard. Payments move PENDING → PAID → SUCCESS or FAILED. Items have separate lifecycles. A provider layer routes fulfillment through one contract. ECPay returns signed webhooks. A 10-minute cron finds stuck payments and alerts operators. A 12-hour cron syncs catalogs with per-supplier isolation.