Orders & fulfilment
Pre-Order for Pickup/Delivery (Restaurants)
Indicative price, not an offer: €39/mo; order time slots, delivery range, ETA estimation
Generated from docs/plan/paid/pre-order-for-pickup-delivery/PLAN.md in the AstroBaaS repository. Nothing described below is implemented — it is the written plan for it.
A restaurant pre-ordering system that allows customers to order before arrival, select time slots, and enables pickup/delivery scheduling.
The problem
Restaurant customers want to order before arrival; needs menu access, time slot selection, and wait-time tracking.
What it does
- Enable time-slot selection at checkout (e.g., ‘pickup at 6pm’, ‘delivery 2-3pm’)
- Show available time slots based on operational hours and current queue
- Calculate wait time (how long until ready)
- Display menu with estimated prep time per item
- Auto-route order to kitchen/fulfillment (structure allows, implementation separate)
- Customer notifications: ‘order confirmed, ready by X’, ‘order ready for pickup’, ‘driver en route’
- Track order progress (in prep, ready, picked up/delivered)
What it deliberately does NOT do
Each boundary carries its reason. A boundary without a reason gets crossed by the next person who reads this.
- Kitchen display system — we don’t display orders in kitchen. Reason: point-of-sale integration outside scope.
- Driver assignment — we don’t assign drivers for delivery. Reason: delivery logistics separate paid feature.
- Menu inventory management — this is part of product data, not ordering logic. Reason: inventory management is separate subsystem.
Data model
New tables: PreOrder {id, orderId, type (‘pickup’|‘delivery’), selectedTimeSlot, readyByTime, status (‘in_prep’|‘ready’|‘picked_up’|‘delivered’), createdAt, readyAt, fulfilledAt}; TimeSlot {id, restaurantId, date, startTime, endTime, capacity, currentOrders (int), isAvailable (bool)}. No migration.
API
- GET /api/restaurants/:id/time-slots
- POST /api/orders/pre-order
- GET /api/pre-orders/:id
- PUT /api/pre-orders/:id/status
Every route added here must also appear in src/pages/openapi.json.ts — a test
fails the build if it does not.
Admin
Restaurant admin: configure operational hours and time slots. Pre-order list: show all pre-orders for today, status, time slot. Manual action: mark ready, mark picked up, send notification.
The seam — why this is paid
Core owns: order structure, time-slot selection interface. Paid owns: kitchen integration, customer notifications, driver management, ETA.
Support commitment: menu sync, order routing to kitchen, customer SLA management
Dependencies
- Order infrastructure
- Restaurant/merchant configuration (hours)
- Notification system (customer SMS/email)
Acceptance checks
Each of these must be able to fail. Before claiming this is done, break the code deliberately and watch each one go red.
- Time-slot query returns list of available slots (with capacity checks)
- Creating pre-order reserves a time slot and decrements availability
- Slot capacity: if slot is full (all 20 seats), it does not appear in available list
- Status updates: marking ready triggers customer notification
Risks
Overbooking: slot capacity exceeded; mitigation: capacity check before reserving. No-show: customer doesn’t arrive; mitigation: hold order for 30 min, then cancel.
Commercial context
| Suggested price | €39/mo; order time slots, delivery range, ETA estimation |
| Rival anchor | Toast: €65/mo built-in; Square: €30/mo add-on; custom: €2000+ |
The anchor is what the nearest equivalent charges on Shopify or Magento today. It is context for a pricing decision, not the decision.
Generated from the commerce plan. See docs/COMMERCE-PLAN.md for the full
catalogue and ../../AI-GUIDE.md for how to work on this repository.