Menus Domain
The menus domain handles restaurant menu management, including menus, sections, items, serving sizes, and time-based availability.
Data Model
Restaurant
+-> Menu (e.g., "Breakfast Menu", "Lunch Menu")
+-> MenuSection (e.g., "Appetizers", "Entrees")
+-> MenuItemMapping (links items to sections with pricing)
+-> ServingQuantity[] (additional sizes)
MenuItem (shared across menus/sections)
- name, description, images, dietary info
Menus are per-restaurant. Menu items are reusable entities that can appear in multiple menus/sections via MenuItemMapping. Each mapping defines the price, default serving size, and position for that item in that section.
Serving Sizes
Menu items support multiple serving sizes. The servingQty field is TEXT to accommodate various formats:
| Format | Example |
|---|---|
| Numeric | "8", "12", "15" (inches for pizza) |
| Fractions | "1/2", "3/4" (tray sizes for catering) |
| Descriptive | "Small", "Medium", "Large" |
| Weight | "12", "16", "24" (oz for beverages) |
The default serving is stored on MenuItemMapping. Additional sizes are stored in the ServingQuantity table. Updates use atomic replace mode -- providing servingSizes replaces all existing sizes in a single transaction.
Time-Based Availability
Menus and sections support time-based availability:
available_from/available_uptoon both menus and sections- Times are sent/received in 12-hour format (e.g., "09:00 AM")
- Timezone context via
?timeZone=America/New_Yorkquery parameter - Stored in UTC (
TIMESTAMPTZ) in the database - Converted at query time using restaurant's IANA timezone
Key Endpoints
| Endpoint | Method | Description |
|---|---|---|
/restaurants/{id}/menus |
POST/GET | Create or list menus |
/restaurants/{id}/menus/{menuId} |
GET/PUT/DELETE | Single menu CRUD |
/restaurants/{id}/menus/{menuId}/sections |
POST/GET | Menu sections |
/restaurants/{id}/menus/{menuId}/mapped-menu-items |
POST/GET | Add items to sections |
/restaurants/{id}/menus/{menuId}/mapped-menu-items/{id} |
PUT | Update item mapping (price, sizes) |
Dietary Information
Menu items support dietary flags stored as JSONB: vegetarian, vegan, gluten-free, halal, kosher, and custom dietary labels.
Images
Menu items and menus support image uploads via the Cloudflare R2 pipeline (see Data Flow). Images are stored as JSONB arrays with metadata (alt text, description, aspect ratio).
Export/Import
Menu data can be copied between restaurants using yum/api/scripts/copyMenuData.ts or exported via yum/api/services/menuExportImport.ts. The copy script supports cross-database transfers with ID remapping.
Key Files
yum/api/db/models/menuMaster.ts-- Menu tableyum/api/db/models/menuItem.ts-- Menu item tableyum/api/db/models/menuItemMapping.ts-- Item-to-section mappingyum/api/schema/menuItem.ts-- Zod schemas includingServingSizeSchemayum/api/utils/timeUtils.ts-- Timezone conversion utilitiesyum/docs/SERVING_SIZES.md-- Multi-size items documentation