All work
03Personal project — in progress

Multi-Tenant Photo Commerce & Fulfillment Platform

An independent, multi-tenant platform for ordering AI-styled photo products over WhatsApp, with wallet payments, an admin backoffice, and physical fulfillment through a printer agent — designed, built and security-audited end to end across four separately-versioned services.

Role

Independent developer — architecture, backend, and production-readiness audit

Context

A personal project: a multi-tenant platform where customers order AI-styled photo products over WhatsApp, pay into an in-app wallet, and have orders fulfilled through a physical printer. Built end to end — backend, admin backoffice, WhatsApp integration and print fulfillment — across four independently-versioned services, each with its own test suite and CI pipeline.

System

A NestJS/TypeScript backend (Prisma over MySQL) exposes the store, product/design-template, wallet and order APIs. Redis and BullMQ back queues, rate limiting and webhook idempotency. A dedicated Express service verifies and relays inbound WhatsApp messages from Twilio — checking the request signature and claiming each message ID in Redis before it reaches the backend — alongside a direct Meta WhatsApp Cloud API integration. A React/Redux Toolkit backoffice manages stores, products and orders. A separate, database-polling printer agent handles physical fulfillment, deliberately simpler than an earlier Socket.IO-based print worker that never made it into the production path.

Problem

Customers order and customize physical photo products entirely through WhatsApp rather than a conventional storefront, while the platform serves multiple independent stores whose data, orders and wallets have to stay isolated from one another.

Engineering challenge

Keeping tenants' data genuinely isolated (not just filtered at the API layer), making wallet balance changes safe under concurrent requests, treating an external channel (Twilio's webhook) as untrusted input that has to be verified and de-duplicated, and handling user-supplied file references for printing without opening the backend to path-traversal or SSRF.

My contribution

  • Designed and built the backend (NestJS/Prisma/MySQL), the WhatsApp ordering flow across two channels (Meta Cloud API and a Twilio webhook relay), the wallet/payment logic, and the React backoffice.
  • Built the webhook-relay service that verifies Twilio's request signature and claims each message ID in Redis before forwarding it, so a duplicated or replayed webhook delivery can't be processed twice.
  • Ran a structured production-readiness audit against my own system — authentication and refresh-token handling, multi-tenant data isolation, wallet concurrency, webhook replay protection, and file-download exposure — then fixed what it found and wrote regression tests for each fix.
  • Wrote and maintained the automated test suites across all four services and their CI pipelines.

Technical decisions

  • Replaced an earlier Socket.IO-based print worker with a simpler database-polling printer agent — fewer moving parts to keep consistent with order state, at the cost of polling latency instead of push updates.
  • Used Redis-claimed message IDs as the idempotency mechanism for the Twilio webhook relay, rather than assuming Twilio delivers each message exactly once.
  • Enforced store/tenant scoping at the data-access layer after the audit surfaced a cross-tenant disclosure path, rather than relying on API-layer checks alone.

Technology

NestJS / TypeScript
Structures the backend into modules (stores, orders, wallet, WhatsApp) with strict typing.
Prisma / MySQL
Schema-first data access and migrations for the relational store/order/wallet data.
Redis / BullMQ
Queues, rate limiting, and webhook-idempotency tracking.
Meta WhatsApp Cloud API
The primary channel customers order through.
Twilio (webhook relay)
A second WhatsApp channel — verified by request signature and de-duplicated in Redis before it reaches the backend.
React / Redux Toolkit
The admin backoffice for managing stores, products and orders.
JWT + HttpOnly refresh cookies
Session/auth handling, with bcrypt-hashed credentials.
Docker Compose
Runs the backend, database, Redis and supporting services locally and in CI.
GitHub Actions
A CI pipeline per service, running the test suites on every change.

Result

A working, end-to-end system with roughly 448 automated tests passing across the four services' CI pipelines. A self-directed production-readiness audit found and fixed a cross-tenant data-disclosure issue, a wallet race condition, a webhook-replay gap, a server-side request forgery bypass on file downloads, and a path-traversal issue in the printer agent — each with its own regression test. As of the most recent audit the system is not yet production-ready; that audit, and what it found, is the clearest evidence of how I actually work through a system before calling it done.

What I learned

Running a real audit against your own system — trying to break it the way a concurrent request or an untrusted webhook would, not just exercising the happy path — surfaces problems that ordinary feature work never touches. A passing test suite and a system that's safe under concurrent, adversarial or duplicated input turned out to be two different bars.

Architecture
Channels
WhatsApp (Meta API)
WhatsApp (Twilio)
Webhook gateway
HMAC-verified relay
Redis idempotency
API layer
NestJS backend
Data & queue
MySQL (Prisma)
Redis / BullMQ
Fulfillment
Printer agent (DB polling)

Four separately-versioned services, each with its own CI pipeline