Skip to content

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_upto on both menus and sections
  • Times are sent/received in 12-hour format (e.g., "09:00 AM")
  • Timezone context via ?timeZone=America/New_York query 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 table
  • yum/api/db/models/menuItem.ts -- Menu item table
  • yum/api/db/models/menuItemMapping.ts -- Item-to-section mapping
  • yum/api/schema/menuItem.ts -- Zod schemas including ServingSizeSchema
  • yum/api/utils/timeUtils.ts -- Timezone conversion utilities
  • yum/docs/SERVING_SIZES.md -- Multi-size items documentation