Case Study

e-Tempahan: replacing scattered food orders with a real system

A government agency in Sabah was managing meal orders for meetings and events through chat messages and paper. No tracking, no approvals, no records. We built a structured ordering system instead.

Admin dashboard showing booking statistics, approval queue, and order table

Admin portal: statistics, approvals, and the active booking queue.

Modules
13
Stack
Pages, Workers, KV
Status
Live in production

The problem

Food orders arrived through WhatsApp messages, phone calls, and handwritten notes. Three things broke as a result:

What we built

A public booking form for staff, paired with an admin portal for the officers who handle approvals and suppliers.

Public side

Admin side

The parts that were actually hard

Timezone handling. The server runs in UTC. The users are in Malaysia. Every date comparison, including the "cannot book a past date" rule and the "today" statistics, had to be recalculated in Malaysia time. The naive approach silently accepted bookings one day in the past for anyone submitting after midnight local time. We centralised the conversion into a single helper and routed every date operation through it.

Price integrity. The browser sends a menu selection, not a price. The server looks up the current price from the menu record at approval time. If a client tampers with the request body, the price is still correct. This matters because approved bookings feed directly into spend reporting.

Authentication scope. This is a meal ordering system, not a banking application. We deliberately kept the security proportionate: session based login, throttled password reset, forced change on first use, and server side authorisation on every admin endpoint. We did not add multi factor authentication, because the friction would have outweighed the risk for a system holding meal orders.

Architecture choices

The whole system runs on Cloudflare Pages with Workers handling the API and KV for storage. No traditional server, no database to patch, no hosting bill beyond the domain. For an agency without an IT department, that matters more than raw performance: there is nothing to maintain and nothing to go down at 2am.

We deployed behind strict security headers including a content security policy that blocks all external script sources. The trade off is that no third party analytics or tag manager can be added later without an explicit policy change, which is the correct default for a government system.

What I would do differently

The public form has no rate limiting or honeypot field yet. It is behind a government domain with low traffic, so the risk is small, but a bot could still fill the booking table with junk. That is the first thing I would add before the system handles a public launch.

The agency is not named here by request. Details of the internal workflow are summarised, not reproduced.