Skip to content

Order Flow Architecture

System Architecture

Otter Webhooks
→ Order Management Service
→ RabbitMQ
→ Kitchen Batch Tool Service
→ SSE
→ Frontend

Flow:

  1. Otter sends webhook events (new orders, updates) directly to the Order Management Service's HTTP endpoint.
  2. Order Management Service receives the webhook and publishes the event to RabbitMQ.
  3. The Otter Event Consumer Worker processes events from the RabbitMQ queue.
  4. New orders are saved to the PostgreSQL database.
  5. Essential data (items, stations, quantities, brand, Otter ID) is extracted.
  6. A structured Protobuf message is built.
  7. The structured order is published to a RabbitMQ exchange.
  8. The Kitchen Batch Tool Service consumes the message from RabbitMQ.
  9. It processes the order and calculates batch items.
  10. Updates are streamed to the frontend via SSE.

Order Processing Sequence

sequenceDiagram
    participant O as Otter
    participant OMS as Order Management Service
    participant RMQ as RabbitMQ
    participant KBT as Kitchen Batch Tool Service
    participant FE as Frontend

    O->>OMS: Webhook: New order event
    OMS->>RMQ: Publish event
    RMQ->>OMS: Otter event consumer worker
    OMS->>OMS: Process event (new_order)
    OMS->>OMS: Save order to PostgreSQL
    OMS->>RMQ: Publish structured order
    RMQ->>KBT: Deliver message
    KBT->>KBT: Process order
    KBT->>KBT: Calculate batch items
    KBT->>KBT: Publish to SSE queue
    KBT->>FE: Stream event (SSE)

Monorepo Structure

See Folder Structure Guide for detailed organization. Key directories:

Protobuf Definition

See the Protocol Buffer definition: structured_order_data.proto

Data Extraction

From Otter webhook payload, essential fields are extracted: - metadata.payload.externalIdentifiers.idotter_order_id - metadata.storeIdkitchen_id - metadata.payload.customerPayments → customer information - metadata.payload.fulfillmentInfo → order type and status - metadata.payload.items[]order_items[] with modifiers

Key Components

1. Order Management Service

Purpose: Receives orders from Otter webhooks, processes them, and publishes to RabbitMQ.

Components: - Otter Webhook HTTP Endpoint: The webhook_router.py receives webhook events and publishes to RabbitMQ. - Otter Event Consumer Worker: The consumer.py consumes events from the RabbitMQ queue. - Order Handler: The otter_order_handler.py processes Otter event data and saves it to PostgreSQL. - Structured Order Publisher: The publisher.py publishes structured orders to RabbitMQ. - Background Workers: See the order management service workers directory.

Startup Sequence: 1. Initialize PostgreSQL connection. 2. Initialize RabbitMQ connection and exchanges. 3. Initialize structured order publisher. 4. Start Otter event consumer worker. 5. Start background sync workers.

2. Kitchen Batch Tool Service

Purpose: Consumes orders from RabbitMQ and processes batch items.

Components: - Structured Order Consumer: The consumer.py consumes messages from RabbitMQ. - SSE Endpoint: The orders_router.py streams order events to the frontend. - Batch Item Calculation: The batch_item_calculation.py calculates batch items from orders.

Startup Sequence: 1. Initialize PostgreSQL database. 2. Initialize RabbitMQ connection and queue. 3. Initialize reference data cache. 4. Start structured order consumer. 5. Serve FastAPI with SSE endpoint.

RabbitMQ and Data Transformation

RabbitMQ setup and data transformation:

  • Exchange and Queue Setup: See structured order publisher and consumer implementations
  • Message Flow: Order Management Service publishes to structured_order_data FANOUT exchange
  • Otter Webhook Payload Processing: Uses safe_get() utility for nested JSON paths
  • Protobuf Message Structure: Defined in structured_order_data.proto

Reference Data Cache

Kitchen Batch Tool Service uses in-memory cache for reference data. See reference data cache implementation.

SSE Streaming

Endpoint: GET /orders/events - See orders router for SSE implementation.

Configuration

For environment variable setup, refer to Getting Started. Key variables include:

  • RABBITMQ_URL: RabbitMQ connection string.
  • RABBITMQ_OTTER_EVENTS_EXCHANGE: Otter events exchange name.
  • RABBITMQ_STRUCTURED_ORDER_DATA_EXCHANGE: Structured order exchange name.
  • POSTGRES_SUPABASE_URL: PostgreSQL connection string.

Running the Services

See Getting Started for detailed setup instructions.

Otter Event Types

Order Management Service handles Otter event types:

  • orders.new_order: New order created, saved to PostgreSQL, published to RabbitMQ
  • orders.order_ready: Order ready for pickup or delivery
  • orders.order_handed_off: Order handed off for delivery
  • orders.order_fulfilled: Order completed
  • orders.cancel_order: Order canceled

Testing

Send test webhook to simulate Otter webhook. See Getting Started for testing.

Key Benefits

  • Scalability: Multiple consumers via FANOUT exchange
  • Reliability: RabbitMQ message persistence and delivery guarantees
  • Decoupling: Services communicate via messages, not direct calls
  • Type Safety: Protocol Buffers for structured messages
  • Real-time: SSE streaming for live frontend updates
  • Caching: Reference data cache reduces database load