Restaurant Management System - Backend API
Production-ready RESTful API for restaurant management with comprehensive RBAC, JWT authentication (access + refresh tokens), advanced filtering & pagination, order workflow state machine, and real-time table status management. Deployed on AWS EC2 with Elastic IP for stable endpoint.
Role
Backend Developer
Client
Academic Project - Web Programming Course
Team
Solo Developer
Timeline
1 week • 2025

Skills & Tools
Skills Applied
Tools & Software
Project Overview
A production-ready RESTful backend for restaurant operations — authentication, menu browsing, order processing, table management, and reviews — with granular role-based access control across 3 roles and 30+ endpoints. Deployed on AWS EC2 with an Elastic IP for a stable endpoint.
Stack
Node.js 20 + Express 5, Prisma ORM (SQLite in dev, PostgreSQL in prod), JWT dual-token auth, bcrypt (10 rounds), Zod validation, Helmet, a CORS whitelist, express-rate-limit, and gzip compression. 14 strategic indexes keep queries fast.
Database Design
Seven normalized entities: Users, Categories, MenuItems, Tables, Orders, OrderItems, and Reviews. Two patterns are central:
- Price snapshot — when an order is created, the current menu price is copied into
OrderItem.priceso historical totals stay accurate even after menu prices change. - Cascade strategy — CASCADE where children are integral (Order to OrderItem, reviews), RESTRICT to protect referenced data (cannot delete users or items with history), and SET NULL for tables so orders survive table removal.
Authentication & Authorization
Dual-token JWT balances security and UX: a 15-minute access token (memory-only) authorizes requests, while a 7-day refresh token issues new access tokens without re-login — stateless, revocable, and low-exposure.
Role-based access control spans 30+ endpoints across three roles:
| Role | Permissions | Restrictions |
|---|---|---|
| CUSTOMER | Create orders | Cannot see other users' orders |
| STAFF | All CUSTOMER permissions | Cannot delete menu items |
| ADMIN | All STAFF permissions | Can only delete orders with status CANCELLED |
Authorization is enforced by composable middleware — authenticateToken, then requireRole([...]), then an ownership check — so CUSTOMER queries are automatically scoped to their own userId.
Order Workflow
Orders follow a strict state machine; skipping states is rejected, and terminal states drive table status:
PENDING → CONFIRMED → PREPARING → READY → COMPLETED
↓
CANCELLED
| Current Status | Allowed Transitions | Who Can Transition | Side Effects |
|---|---|---|---|
| PENDING | CONFIRMED, CANCELLED | STAFF/ADMIN (confirm), CUSTOMER (cancel) | If DINE_IN: set table status to OCCUPIED |
| CONFIRMED | PREPARING, CANCELLED | STAFF/ADMIN | None |
| PREPARING | READY, CANCELLED | STAFF/ADMIN | None |
| READY | COMPLETED, CANCELLED | STAFF/ADMIN | None |
| COMPLETED | None (terminal state) | N/A | Set table status to AVAILABLE, unlock review permissions |
| CANCELLED | None (terminal state) | N/A | Set table status to AVAILABLE |
Order creation validates item availability, quantity bounds (1–20), and order type (DINE_IN requires an available table; TAKEAWAY/DELIVERY must not specify one). It generates an ORD-YYYYMMDD-XXXX number, snapshots prices, and sums the total atomically.
Querying, Tables & Reviews
- Filtering — every collection endpoint supports pagination (
page,limitup to 100), full-textsearch,sortBy/order, plus resource filters (category, price range, availability, status, date range), and returns pagination metadata. - Table status — updates automatically from order lifecycle events: a DINE_IN order sets a table OCCUPIED; completion or cancellation of the last active order returns it to AVAILABLE; staff can manually set RESERVED.
- Reviews — verified only: a user can review an item only after a COMPLETED order containing it, with a unique
(userId, menuItemId)constraint preventing duplicates.
Security & Deployment
Zod validates every request body (email format, password strength, enum values, numeric ranges, length limits, and custom refinements). Helmet sets security headers, CORS uses an origin whitelist, and critical endpoints are rate-limited (login and reviews 5 per 15 min, orders 10 per 15 min). bcrypt hashes passwords with constant-time comparison.
Deployed on an AWS EC2 t2.micro (Ubuntu 22.04) with a static Elastic IP (44.216.9.251), PM2 process management, and Nginx as a reverse proxy. Indexed queries stay under 50ms even at scale; login is intentionally slower due to bcrypt hashing.
Key Takeaways
- The price snapshot pattern is essential for immutable, historically accurate financial records.
- Dual-token JWT gives short-exposure access tokens without constant re-authentication.
- Role scoping must be explicit — always filter CUSTOMER queries by
userIdto prevent data leakage. - A server-side state machine prevents invalid business transitions; strategic indexes prevent performance decay.
Repository: restaurant-api · Live API: 44.216.9.251/api · Course: Web Programming, Hasanuddin University, 2025
Project Metrics
7 normalized database models with 14 indexed fields for query optimization
30+ REST endpoints with role-based authorization (CUSTOMER, STAFF, ADMIN)
JWT dual-token system: 15-minute access tokens + 7-day refresh tokens
Zod schema validation on all input with 20+ custom validation rules
6-state order workflow state machine (PENDING → COMPLETED/CANCELLED)
Rate limiting on critical endpoints: 5-10 requests per 15 minutes
Deployed on AWS EC2 t2.micro with Elastic IP (44.216.9.251)
Automated table status updates based on order lifecycle events
Project Tags
Related Projects
View all projects →
Urban Complaint Pattern Mining on NYC 311 Data (21M+ Records)
End-to-end data mining of 21.3M NYC 311 service requests, discovering a six-complaint 'interior maintenance syndrome' validated against 11M independent housing inspection records. Buildings with the full syndrome show 12-44x higher verified violation rates, holding across building-size strata and a prior time window designed to rule out administrative circularity.

Medical Anamnesis Chatbot with NLP (Chatbot PUSTU)
Production-ready medical chatbot achieving 92.61% intent classification accuracy using Multinomial Naive Bayes for Indonesian Puskesmas healthcare anamnesis workflow. Automated training data generation via Gemini Flash 2.0 API with custom NLP preprocessing pipeline built from scratch.

MyFriends - Emergency SOS & Contact Management App
Production-ready emergency SOS app with multi-layered persistent notification system (foreground + background + 60 scheduled alarms), real-time location sharing, and comprehensive contact management using Flutter and Firebase.
