Food ordering platform
Akbar's own online ordering, at akbar.co.jp. Customers around Tama Plaza and Azamino order delivery or takeout and pay online, straight from the restaurant.
Visit Live Site

Most people now order food through delivery apps, and those apps keep a big cut of every order. Calling the restaurant is slow, and someone has to stay by the phone to take it.

Customers choose delivery to their door or pickup at the shop, then order from the full menu on their phone. No waiting on the line, no misheard orders.

Every curry, set and naan with photos and prices, sorted into tabs. Customers search, filter, pick their spice level and add-ons, and lunch sets appear only when lunch is being served.

Active orders, today's orders and today's income sit at the top, with a sales chart by day, week or month and the most popular dishes beside it. Below, every recent order shows what was ordered, how it was paid and its status, and new ones appear the moment they're placed.

When the kitchen is full, staff pause new orders or close specific delivery times, then reopen with one click. Customers always see what's actually available.
Orders arrive written down and paid for, so the restaurant no longer needs a person just to answer calls and take orders.
Delivery apps take a large share of every order. Orders placed on Akbar's own site skip that commission, so more of each sale stays with the restaurant.
People are used to ordering food on their phones. Now they can do that with Akbar directly, any time, without waiting for someone to pick up.
Stack, architecture and how it is built.
AWS EC2 with Nginx + Gunicorn (2–6 workers). HTTPS via Certbot. Media on Cloudflare R2. Live at akbar.co.jp serving real customers.
Migrated production DB from AWS RDS PostgreSQL to Cloudflare D1 via a custom SQLAlchemy dialect (d1+http) that proxies queries through a Cloudflare Worker, since D1 is only reachable from inside the Workers runtime. Media storage moved from S3 to R2 the same way.
| Table | What it stores |
|---|---|
| CustomerLogin | Phone number (unique), name, email, hashed password, address fields, verification status, order count |
| Admin | Restaurant admin accounts — email, PBKDF2-SHA256 hashed password (310,000 iterations), passcode |
| SuperAdmin | Top-level admin — email and 4-digit passcode. One row expected |
| DeliveryBoy | Delivery staff — name and PIN for simplified login |
| Category | Food categories with position ordering, optional time restriction, and spicy level flag |
| MenuItem | Individual items — name, description, price, S3 image URL, availability, spice options, position, order count |
| AddonCategory | Add-on groups (e.g. "Spice Level", "Drink Choice") scoped per category or per item |
| AddonItem | Individual add-on choices (e.g. "Mild", "Medium Hot") with price. Belongs to an AddonCategory |
| Order | Placed order — links to customer, status, total, payment method, Stripe payment_intent_id, delivery method, scheduled time |
| OrderItem | Items within an order — quantity, price at time of order, spicy level, special instructions, add-ons stored as JSON |
| Settings | Restaurant settings — name, address, phone, opening hours, admin email. One row |
| TodayCurry / MonthlyCurry | CMS data: today's curry name and the monthly special (name, S3 image URL, price) |