### Run Development Server Source: https://github.com/medusajs/medusa-eats/blob/main/frontend/README.md Use one of these commands to start the development server. Open http://localhost:3000 in your browser to view the result. The page auto-updates as you edit the file. ```bash npm run dev ``` ```bash yarn dev ``` ```bash pnpm dev ``` ```bash bun dev ``` -------------------------------- ### Restaurant Begins Preparation Source: https://context7.com/medusajs/medusa-eats/llms.txt Signals that the restaurant has started preparing the order. Sets status to 'restaurant_preparing'. Use the delivery ID in the URL. ```bash curl -X POST "http://localhost:9000/store/deliveries/del_01J.../prepare" ``` ```json # { "delivery": { "delivery_status": "restaurant_preparing", ... } } ``` ```javascript // Frontend: import { prepareDelivery } from "@frontend/lib/actions/deliveries"; await prepareDelivery("del_01J..."); ``` -------------------------------- ### List Restaurants with Filters Source: https://context7.com/medusajs/medusa-eats/llms.txt Example `curl` commands to fetch restaurants, demonstrating filtering by status (`is_open`) and currency, as well as fetching by a specific `handle`. The response includes nested product and variant data with calculated prices. ```bash # List all open restaurants with EUR pricing curl "http://localhost:9000/store/restaurants?is_open=true¤cy_code=eur" # Response: # { # "restaurants": [ # { # "id": "res_01J...", # "handle": "burger-palace", # "name": "Burger Palace", # "address": "12 Main St, Paris", # "phone": "+33 1 23 45 67 89", # "email": "hello@burgerpalace.com", # "image_url": "http://localhost:3000/burger-palace.jpg", # "is_open": true, # "products": [ # { # "id": "prod_01J...", # "title": "Classic Cheeseburger", # "categories": [{ "name": "Burgers" }], # "variants": [ # { # "id": "variant_01J...", # "calculated_price": { "calculated_amount": 1200, "currency_code": "eur" } # } # ] # } # ] # } # ] # } # Fetch by handle curl "http://localhost:9000/store/restaurants?handle=burger-palace" ``` -------------------------------- ### Define a Basic API Route Handler Source: https://github.com/medusajs/medusa-eats/blob/main/backend/src/api/README.md Export an async function named after the HTTP method (e.g., GET) to handle requests for a specific route. This example shows a simple GET request handler. ```typescript import type { MedusaRequest, MedusaResponse } from "@medusajs/medusa" export async function GET(req: MedusaRequest, res: MedusaResponse) { res.json({ message: "Hello world!", }) } ``` -------------------------------- ### API Route with Path Parameters Source: https://github.com/medusajs/medusa-eats/blob/main/backend/src/api/README.md Define routes with dynamic parameters by wrapping parameter names in square brackets in the file path. Access parameters via `req.params`. This example retrieves a product by its ID. ```typescript import type { MedusaRequest, MedusaResponse, ProductService, } from "@medusajs/medusa" export async function GET(req: MedusaRequest, res: MedusaResponse) { const { productId } = req.params const productService: ProductService = req.scope.resolve("productService") const product = await productService.retrieve(productId) res.json({ product, }) } ``` -------------------------------- ### Create Delivery and Start Order Workflow Source: https://context7.com/medusajs/medusa-eats/llms.txt This endpoint creates a delivery entity linked to a cart and restaurant, initiating the order lifecycle workflow. It returns a confirmation message, delivery details, and transaction information. ```bash curl -X POST "http://localhost:9000/store/deliveries" \ -H "Content-Type: application/json" \ -d '{ "cart_id": "cart_01J...", "restaurant_id": "res_01J..." }' # Response: # { # "message": "Delivery created", # "delivery": { # "id": "del_01J...", # "delivery_status": "pending", # "transaction_id": null, # "cart": { "id": "cart_01J...", "items": [...] } # }, # "transaction": { # "transactionId": "txn_01J...", # "workflowId": "handle-delivery-workflow" # } # } # The handleDeliveryWorkflow then runs these steps in order (each step is async/suspended): # 1. setTransactionIdStep — stores workflow transaction_id on the delivery # 2. notifyRestaurantStep — emits "notify.restaurant" event (15 min timeout) # 3. findDriverStep — emits "notify.drivers" event, waits for a claim (15 min timeout) # 4. createOrderStep — converts cart to order # 5. awaitStartPreparationStep — waits for restaurant to begin preparing # 6. awaitPreparationStep — waits for restaurant to mark ready # 7. createFulfillmentStep — creates a Medusa fulfillment # 8. awaitPickUpStep — waits for driver to pick up # 9. awaitDeliveryStep — waits for driver to complete delivery ``` -------------------------------- ### Basic Custom Loader Source: https://github.com/medusajs/medusa-eats/blob/main/backend/src/loaders/README.md A simple loader function that logs a message when the Medusa application starts. Place this file in the `src/loaders` directory. ```typescript export default function () { console.log( "[HELLO LOADER] Just started the Medusa application!" ) } ``` -------------------------------- ### Accessing Services via Container Source: https://github.com/medusajs/medusa-eats/blob/main/backend/src/api/README.md Utilize the global container available on `req.scope` to resolve and use registered services within your API route handlers. This example lists all products. ```typescript import type { MedusaRequest, MedusaResponse, ProductService, } from "@medusajs/medusa" export async function GET(req: MedusaRequest, res: MedusaResponse) { const productService: ProductService = req.scope.resolve("productService") const products = await productService.list() res.json({ products, }) } ``` -------------------------------- ### Configure Route-Specific Middleware with Express Source: https://github.com/medusajs/medusa-eats/blob/main/backend/src/api/README.md Use this to apply specific middleware like urlencoded parsing to individual routes. Ensure the 'express' package is installed. ```typescript import { urlencoded } from "express" export const config: MiddlewaresConfig = { routes: [ { method: "POST", matcher: "/store/custom", middlewares: [urlencoded()], }, ], } ``` -------------------------------- ### GET /store/deliveries Source: https://context7.com/medusajs/medusa-eats/llms.txt Lists deliveries with support for filtering by restaurant, driver, status, and pagination. ```APIDOC ## GET /store/deliveries — List Deliveries ### Description Lists deliveries with full cart and order data. Supports filtering by `restaurant_id`, `driver_id`, `delivery_status`, and pagination via `take`/`skip`. ### Method GET ### Endpoint `/store/deliveries` ### Query Parameters - **restaurant_id** (string) - Optional - Filter deliveries by restaurant ID. - **driver_id** (string) - Optional - Filter deliveries assigned to a specific driver. - **delivery_status** (string) - Optional - Filter deliveries by their status (e.g., "pending"). - **take** (integer) - Optional - The number of deliveries to return per page. - **skip** (integer) - Optional - The number of deliveries to skip for pagination. ### Request Examples ```bash # All deliveries curl "http://localhost:9000/store/deliveries" # Filter by restaurant curl "http://localhost:9000/store/deliveries?restaurant_id=res_01J..." # Filter by driver (includes deliveries assigned to that driver) curl "http://localhost:9000/store/deliveries?driver_id=drv_01J..." # Filter by status with pagination curl "http://localhost:9000/store/deliveries?delivery_status=pending&take=10&skip=0" ``` ### Response #### Success Response (200) - **deliveries** (array) - A list of delivery objects. - **id** (string) - The unique identifier for the delivery. - **delivery_status** (string) - The current status of the delivery. - **transaction_id** (string | null) - The ID of the associated transaction. - **driver_id** (string | null) - The ID of the assigned driver. - **eta** (string | null) - Estimated time of arrival. - **cart** (object) - The cart associated with the delivery. - **order** (object | null) - The order associated with the delivery. ### Response Example ```json { "deliveries": [ { "id": "del_01J...", "delivery_status": "pending", "transaction_id": "txn_01J...", "driver_id": null, "eta": null, "cart": { "id": "cart_01J...", "items": [...] }, "order": null } ] } ``` ### Frontend Usage ```typescript import { listDeliveries, retrieveDelivery } from "@frontend/lib/data/deliveries"; const deliveries = await listDeliveries({ delivery_status: "pending" }); const delivery = await retrieveDelivery("del_01J..."); ``` ``` -------------------------------- ### Define Multiple HTTP Method Handlers Source: https://github.com/medusajs/medusa-eats/blob/main/backend/src/api/README.md Export functions for different HTTP methods (GET, POST, PUT) within the same route file to handle various request types. ```typescript import type { MedusaRequest, MedusaResponse } from "@medusajs/medusa" export async function GET(req: MedusaRequest, res: MedusaResponse) { // Handle GET requests } export async function POST(req: MedusaRequest, res: MedusaResponse) { // Handle POST requests } export async function PUT(req: MedusaRequest, res: MedusaResponse) { // Handle PUT requests } ``` -------------------------------- ### Restaurant Begins Preparation Source: https://context7.com/medusajs/medusa-eats/llms.txt Advances past `awaitStartPreparationStep`. Sets status to `restaurant_preparing`. ```APIDOC ## POST /store/deliveries/:id/prepare — Restaurant Begins Preparation Advances past `awaitStartPreparationStep`. Sets status to `restaurant_preparing`. ### Method POST ### Endpoint `/store/deliveries/:id/prepare` ### Parameters #### Path Parameters - **id** (string) - Required - The ID of the delivery to mark as preparing. ### Request Example ```bash curl -X POST "http://localhost:9000/store/deliveries/del_01J.../prepare" ``` ### Response #### Success Response (200) - **delivery** (object) - Details of the updated delivery. - **delivery_status** (string) - The new status of the delivery (e.g., `restaurant_preparing`). ### Response Example ```json { "delivery": { "delivery_status": "restaurant_preparing", ... } } ``` ``` -------------------------------- ### Apply Middleware to Specific HTTP Methods Source: https://github.com/medusajs/medusa-eats/blob/main/backend/src/api/README.md Restrict middleware application to specific HTTP methods for a given route by adding a `method` property to the route configuration in `/api/middlewares.ts`. This example applies the logger middleware only to GET requests. ```typescript export const config: MiddlewaresConfig = { routes: [ { matcher: "/store/custom", method: "GET", middlewares: [logger], }, ], } ``` -------------------------------- ### User Registration and Login Flow Source: https://context7.com/medusajs/medusa-eats/llms.txt Demonstrates the three-step process for registering a driver, creating their user record, and logging in to obtain a session token. Ensure the correct API endpoints and headers are used. ```typescript // frontend/src/lib/actions/users.ts // Step 1 — Register an auth identity and get a JWT token const registerResponse = await fetch( "http://localhost:9000/auth/driver/emailpass/register", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ entity_id: "jane@example.com", email: "jane@example.com", password: "securepassword", }), } ); const { token } = await registerResponse.json(); // token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." // Step 2 — Create the driver user record (links driver_id into app_metadata) const userResponse = await fetch("http://localhost:9000/store/users", { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}`, }, body: JSON.stringify({ email: "jane@example.com", first_name: "Jane", last_name: "Doe", phone: "+44 7700 900000", actor_type: "driver", }), }); const { user } = await userResponse.json(); // user: { id: "drv_01J...", email: "jane@example.com", first_name: "Jane", ... } // Step 3 — Login (returns token with driver_id in claims) const loginResponse = await fetch( "http://localhost:9000/auth/driver/emailpass", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email: "jane@example.com", password: "securepassword" }), } ); const { token: sessionToken } = await loginResponse.json(); // GET /store/users/me — retrieve current user profile const meResponse = await fetch("http://localhost:9000/store/users/me", { headers: { Authorization: `Bearer ${sessionToken}` }, }); const { user: me } = await meResponse.json(); // me: { id: "drv_01J...", first_name: "Jane", last_name: "Doe", phone: "...", email: "..." } ``` -------------------------------- ### Create a Restaurant Source: https://context7.com/medusajs/medusa-eats/llms.txt Use this endpoint to create a new restaurant. Provide all required details including name, handle, address, and contact information. ```bash curl -X POST "http://localhost:9000/store/restaurants" \ -H "Content-Type: application/json" \ -d '{ "name": "Pasta House", "handle": "pasta-house", "address": "5 Rue de Rivoli, Paris", "phone": "+33 1 99 88 77 66", "email": "info@pastahouse.com", "image_url": "http://localhost:3000/pasta-house.jpg" }' ``` -------------------------------- ### GET /store/deliveries/:id/subscribe Source: https://context7.com/medusajs/medusa-eats/llms.txt Opens a Server-Sent Events stream for real-time updates on a specific delivery, with optional subscription to new deliveries for a restaurant or driver. ```APIDOC ## GET /store/deliveries/:id/subscribe — SSE Real-Time Updates (Per Delivery) ### Description Opens a Server-Sent Events stream for a specific delivery. The frontend subscribes to workflow engine step events. Optionally pass `restaurant_id` or `driver_id` to also receive notifications for new deliveries assigned to that party. ### Method GET ### Endpoint `/store/deliveries/:id/subscribe` ### Path Parameters - **id** (string) - Required - The ID of the delivery to subscribe to. ### Query Parameters - **restaurant_id** (string) - Optional - Subscribe to new deliveries for this restaurant. - **driver_id** (string) - Optional - Subscribe to new deliveries assigned to this driver. ### Request Example ```typescript // frontend — subscribe to a single delivery's live status const eventSource = new EventSource( `http://localhost:9000/store/deliveries/del_01J.../subscribe?restaurant_id=res_01J...`, { withCredentials: false } ); eventSource.onmessage = (event) => { const data = JSON.parse(event.data); // Initial connection: // { message: "Subscribed to workflow", transactionId: "txn_01J..." } // On each workflow step transition: // { workflowId: "handle-delivery-workflow", transactionId: "txn_01J...", step: "notify-restaurant-step", status: "succeeded" } // When a new delivery arrives for the subscribed restaurant: // { message: "Subscribed to workflow", transactionId: "txn_02J...", new: true } console.log("Delivery update:", data); }; eventSource.onerror = () => { eventSource.close(); }; ``` ``` -------------------------------- ### Create and Link Restaurant Products Workflow Source: https://context7.com/medusajs/medusa-eats/llms.txt This workflow creates menu products and links them to a specific restaurant. It internally uses `createProductsWorkflow` and `createRemoteLinkStep`. ```typescript // Create and link menu products to a restaurant import { createRestaurantProductsWorkflow } from "./workflows/restaurant/workflows"; const { result: links } = await createRestaurantProductsWorkflow(scope).run({ input: { restaurant_id: restaurant.id, products: [ { title: "Salmon Roll", description: "Fresh salmon, avocado, cucumber", thumbnail: "http://localhost:3000/salmon-roll.jpg", status: "published", variants: [ { title: "6 pcs", prices: [{ currency_code: "eur", amount: 1600 }] } ], sales_channels: [{ id: "sc_01J..." }], }, ], }, }); // Internally runs createProductsWorkflow then createRemoteLinkStep to bind // restaurantModuleService.restaurant_id ↔ productService.product_id ``` -------------------------------- ### Create Restaurant Workflow Source: https://context7.com/medusajs/medusa-eats/llms.txt Use this workflow to create a new restaurant. Ensure the scope is correctly initialized before running. ```typescript // Create a restaurant import { createRestaurantWorkflow } from "./workflows/restaurant/workflows"; const { result: restaurant } = await createRestaurantWorkflow(scope).run({ input: { restaurant: { name: "Sushi World", handle: "sushi-world", address: "10 Place Vendôme, Paris", phone: "+33 1 11 22 33 44", email: "contact@sushiworld.com", image_url: "http://localhost:3000/sushi-world.jpg", }, }, }); // restaurant.id → "res_01J..." ``` -------------------------------- ### Add Menu Products to Restaurant Source: https://context7.com/medusajs/medusa-eats/llms.txt Creates one or more products and links them to the restaurant. Requires authentication. ```APIDOC ## POST /store/restaurants/:id/products — Add Menu Products Creates one or more products and links them to the restaurant via `createRestaurantProductsWorkflow`. Requires authentication. ### Method POST ### Endpoint /store/restaurants/:id/products ### Parameters #### Path Parameters - **id** (string) - Required - The ID of the restaurant to add products to. ### Request Body - **products** (array) - Required - An array of product objects to add. - **title** (string) - Required - The title of the product. - **description** (string) - Optional - A description of the product. - **thumbnail** (string) - Optional - URL for the product thumbnail image. - **status** (string) - Optional - The publication status of the product (e.g., "published"). - **variants** (array) - Required - An array of product variants. - **title** (string) - Required - The title of the variant. - **prices** (array) - Required - An array of price objects for the variant. - **currency_code** (string) - Required - The currency code (e.g., "eur"). - **amount** (number) - Required - The price amount. - **category_ids** (array) - Optional - An array of category IDs to associate the product with. ### Request Example ```json { "products": [ { "title": "BBQ Bacon Burger", "description": "Smoky BBQ sauce, crispy bacon, cheddar", "thumbnail": "http://localhost:3000/bbq-burger.jpg", "status": "published", "variants": [ { "title": "Regular", "prices": [ { "currency_code": "eur", "amount": 1400 } ] } ], "category_ids": ["pcat_01J..."] } ] } ``` ### Response #### Success Response (200) - **restaurant_products** (array) - An array containing information about the created restaurant products. ``` -------------------------------- ### Add Restaurant Admin Source: https://context7.com/medusajs/medusa-eats/llms.txt Creates a new restaurant admin user and links them to the restaurant. ```APIDOC ## POST /store/restaurants/:id/admins — Add Restaurant Admin Creates a new restaurant admin user and links them to the restaurant via `createUserWorkflow`. ### Method POST ### Endpoint /store/restaurants/:id/admins ### Parameters #### Path Parameters - **id** (string) - Required - The ID of the restaurant to add an admin to. ### Request Body - **email** (string) - Required - The email address of the new admin. - **first_name** (string) - Required - The first name of the new admin. - **last_name** (string) - Required - The last name of the new admin. ### Request Example ```json { "email": "manager@burgerpalace.com", "first_name": "Alice", "last_name": "Smith" } ``` ### Response #### Success Response (200) - **user** (object) - The created restaurant admin user object. - **id** (string) - The unique identifier of the admin user. - **email** (string) - The email address of the admin. ``` -------------------------------- ### List All Drivers Source: https://context7.com/medusajs/medusa-eats/llms.txt Returns all registered drivers in the system. ```APIDOC ## GET /store/drivers — List All Drivers Returns all registered drivers. ### Method GET ### Endpoint /store/drivers ### Response #### Success Response (200) - **drivers** (array) - An array of driver objects. - **id** (string) - The unique identifier of the driver. - **first_name** (string) - The driver's first name. - **last_name** (string) - The driver's last name. - **email** (string) - The driver's email address. - **phone** (string) - The driver's phone number. - **avatar_url** (string | null) - URL for the driver's avatar, or null if not available. - **created_at** (string) - Timestamp when the driver was created. - **updated_at** (string) - Timestamp when the driver was last updated. ``` -------------------------------- ### Seed Demo Data for Medusa Eats Source: https://context7.com/medusajs/medusa-eats/llms.txt This script bootstraps the store configuration, including regions, sales channels, stock locations, shipping options, and creates a sample restaurant with menu products. It's designed to be run via Medusa CLI or npm scripts. ```typescript // Run with: medusa exec ./src/scripts/seed.ts // or: npm run seed import { seedDemoData } from "./src/scripts/seed"; // The seed script (called via CLI): // 1. Creates "Default Sales Channel" // 2. Updates store to support EUR and USD // 3. Creates "Europe" region (gb, de, dk, se, fr, es, it) // 4. Creates tax regions for each country // 5. Sets up fulfillment + stock location (Copenhagen warehouse) // 6. Creates Standard and Express shipping options // 7. Creates a publishable API key linked to the sales channel // 8. Creates one demo restaurant from medusa-eats-seed-data.json // 9. Creates product categories and menu products linked to that restaurant // medusa-eats-seed-data.json shape: // { // "restaurant": { "name": "...", "handle": "...", "address": "...", ... }, // "categories": [{ "name": "Burgers", "handle": "burgers" }, ...], // "products": [{ "title": "Cheeseburger", "category": "burgers", "thumbnail": "/...", ... }] // } ``` -------------------------------- ### Add Menu Products to a Restaurant Source: https://context7.com/medusajs/medusa-eats/llms.txt Creates new products and associates them with a restaurant. Requires authentication. You can also retrieve or delete products using separate endpoints. ```bash curl -X POST "http://localhost:9000/store/restaurants/res_01J.../products" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "products": [ { "title": "BBQ Bacon Burger", "description": "Smoky BBQ sauce, crispy bacon, cheddar", "thumbnail": "http://localhost:3000/bbq-burger.jpg", "status": "published", "variants": [ { "title": "Regular", "prices": [{ "currency_code": "eur", "amount": 1400 }] } ], "category_ids": ["pcat_01J..."] } ] }' ``` ```bash curl "http://localhost:9000/store/restaurants/res_01J.../products" \ -H "Authorization: Bearer " ``` ```bash curl -X DELETE "http://localhost:9000/store/restaurants/res_01J.../products" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "product_ids": ["prod_01J..."] }' ``` -------------------------------- ### User Registration and Authentication Source: https://context7.com/medusajs/medusa-eats/llms.txt This section details the multi-step process for registering users (drivers or restaurant admins) and obtaining authentication tokens. ```APIDOC ## POST /auth/:actor_type/emailpass/register ### Description Registers an authentication identity for a user and returns a JWT token. ### Method POST ### Endpoint /auth/:actor_type/emailpass/register ### Parameters #### Path Parameters - **actor_type** (string) - Required - The type of actor, e.g., `driver` or `restaurant`. #### Request Body - **entity_id** (string) - Required - The entity ID, typically an email address. - **email** (string) - Required - The user's email address. - **password** (string) - Required - The user's password. ### Response #### Success Response (200) - **token** (string) - The JWT token for authentication. ## POST /store/users ### Description Creates a domain user record and links it to the authentication identity's metadata. ### Method POST ### Endpoint /store/users ### Parameters #### Request Body - **email** (string) - Required - The user's email address. - **first_name** (string) - Required - The user's first name. - **last_name** (string) - Required - The user's last name. - **phone** (string) - Optional - The user's phone number. - **actor_type** (string) - Required - The type of actor, e.g., `driver` or `restaurant`. ### Response #### Success Response (200) - **user** (object) - The created user object, including `id`, `email`, `first_name`, etc. ## POST /auth/:actor_type/emailpass ### Description Re-authenticates a user to obtain a fresh token with updated metadata, typically after user creation. ### Method POST ### Endpoint /auth/:actor_type/emailpass ### Parameters #### Path Parameters - **actor_type** (string) - Required - The type of actor, e.g., `driver` or `restaurant`. #### Request Body - **email** (string) - Required - The user's email address. - **password** (string) - Required - The user's password. ### Response #### Success Response (200) - **token** (string) - The JWT token for authentication. ``` -------------------------------- ### Retrieve Restaurant with Deliveries Source: https://context7.com/medusajs/medusa-eats/llms.txt Fetches a single restaurant's details, including its product catalog and delivery information. Specify the currency code for pricing. ```bash curl "http://localhost:9000/store/restaurants/res_01J...?currency_code=eur" ``` -------------------------------- ### Food Ready for Pickup Source: https://context7.com/medusajs/medusa-eats/llms.txt Advances past `awaitPreparationStep`. Sets status to `ready_for_pickup`. ```APIDOC ## POST /store/deliveries/:id/ready — Food Ready for Pickup Advances past `awaitPreparationStep`. Sets status to `ready_for_pickup`. ### Method POST ### Endpoint `/store/deliveries/:id/ready` ### Parameters #### Path Parameters - **id** (string) - Required - The ID of the delivery to mark as ready for pickup. ### Request Example ```bash curl -X POST "http://localhost:9000/store/deliveries/del_01J.../ready" ``` ### Response #### Success Response (200) - **delivery** (object) - Details of the updated delivery. - **delivery_status** (string) - The new status of the delivery (e.g., `ready_for_pickup`). ### Response Example ```json { "delivery": { "delivery_status": "ready_for_pickup", ... } } ``` ``` -------------------------------- ### Add Restaurant Admin Source: https://context7.com/medusajs/medusa-eats/llms.txt Creates a new admin user for a restaurant. Requires a restaurant or admin token. You can also retrieve existing admins. ```bash curl -X POST "http://localhost:9000/store/restaurants/res_01J.../admins" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "email": "manager@burgerpalace.com", "first_name": "Alice", "last_name": "Smith" }' ``` ```bash curl "http://localhost:9000/store/restaurants/res_01J.../admins" \ -H "Authorization: Bearer " ``` -------------------------------- ### Fetch Restaurants and Specific Restaurant in Frontend Source: https://context7.com/medusajs/medusa-eats/llms.txt Use these functions to fetch lists of restaurants or a single restaurant by its handle in the frontend. Ensure the necessary imports are included. ```javascript import { listRestaurants, retrieveRestaurantByHandle } from "@frontend/lib/data/restaurants"; const restaurants = await listRestaurants({ is_open: "true" }); const restaurant = await retrieveRestaurantByHandle("burger-palace"); ``` -------------------------------- ### Restaurant Accepts Order Source: https://context7.com/medusajs/medusa-eats/llms.txt Accepts a delivery order, setting the status to 'restaurant_accepted' and an ETA. Use the delivery ID in the URL. ```bash curl -X POST "http://localhost:9000/store/deliveries/del_01J.../accept" ``` ```json # Response: # { "delivery": { "delivery_status": "restaurant_accepted", "eta": "2024-09-01T12:30:00.000Z", ... } } ``` ```javascript // Frontend action: import { acceptDelivery } from "@frontend/lib/actions/deliveries"; await acceptDelivery("del_01J..."); ``` -------------------------------- ### Food Ready for Pickup Source: https://context7.com/medusajs/medusa-eats/llms.txt Indicates that the food is ready for pickup by the driver. Sets status to 'ready_for_pickup'. Use the delivery ID in the URL. ```bash curl -X POST "http://localhost:9000/store/deliveries/del_01J.../ready" ``` ```json # { "delivery": { "delivery_status": "ready_for_pickup", ... } } ``` ```javascript // Frontend: import { preparationReady } from "@frontend/lib/actions/deliveries"; await preparationReady("del_01J..."); ``` -------------------------------- ### Create Restaurant Source: https://context7.com/medusajs/medusa-eats/llms.txt Creates a new restaurant entity. ```APIDOC ## POST /store/restaurants — Create a Restaurant Creates a new restaurant entity via the `createRestaurantWorkflow`. ### Method POST ### Endpoint /store/restaurants ### Request Body - **name** (string) - Required - The name of the restaurant. - **handle** (string) - Required - A unique handle for the restaurant. - **address** (string) - Required - The physical address of the restaurant. - **phone** (string) - Required - The contact phone number. - **email** (string) - Required - The contact email address. - **image_url** (string) - Optional - URL for the restaurant's image. ### Request Example ```json { "name": "Pasta House", "handle": "pasta-house", "address": "5 Rue de Rivoli, Paris", "phone": "+33 1 99 88 77 66", "email": "info@pastahouse.com", "image_url": "http://localhost:3000/pasta-house.jpg" } ``` ### Response #### Success Response (200) - **message** (string) - Confirmation message. - **restaurant** (object) - The created restaurant object. - **id** (string) - The unique identifier of the restaurant. - **handle** (string) - The restaurant's handle. - **name** (string) - The name of the restaurant. - **is_open** (boolean) - Indicates if the restaurant is currently open. ``` -------------------------------- ### List All Drivers Source: https://context7.com/medusajs/medusa-eats/llms.txt Retrieves a list of all registered drivers in the system. The response includes driver details such as name, email, and phone number. ```bash curl "http://localhost:9000/store/drivers" ``` -------------------------------- ### Configure Medusa Backend with Custom Modules Source: https://context7.com/medusajs/medusa-eats/llms.txt This configuration file registers custom restaurant and delivery modules, sets up the database connection, JWT secret, and CORS origins. It also configures the manual fulfillment provider. ```typescript // backend/medusa-config.ts import { loadEnv, defineConfig, Modules } from "@medusajs/framework/utils"; loadEnv(process.env.NODE_ENV || "development", process.cwd()); module.exports = defineConfig({ admin: { backendUrl: "https://medusa-eats.medusajs.app", }, projectConfig: { databaseUrl: process.env.DATABASE_URL, // e.g. "postgres://postgres@localhost/medusa-eats" http: { storeCors: process.env.STORE_CORS, // e.g. "http://localhost:3000" adminCors: process.env.ADMIN_CORS, authCors: process.env.AUTH_CORS, jwtSecret: process.env.JWT_SECRET || "supersecret", cookieSecret: process.env.COOKIE_SECRET || "supersecret", }, }, modules: { restaurantModuleService: { resolve: "./modules/restaurant", // Custom restaurant + restaurantAdmin entities }, deliveryModuleService: { resolve: "./modules/delivery", // Custom delivery, driver, deliveryDriver entities }, [Modules.FULFILLMENT]: { options: { providers: [ { resolve: "@medusajs/fulfillment-manual", id: "manual-provider" }, ], }, }, }, }); // .env.template // DATABASE_URL=postgres://postgres@localhost/medusa-eats // FRONTEND_URL=http://localhost:3000 // JWT_SECRET=supersecret // Start commands: // npm run setup-db → build + run migrations + seed + create admin // npm run dev → medusa develop (hot reload) // npm start → medusa start (production) ``` -------------------------------- ### Retrieve Restaurant with Deliveries Source: https://context7.com/medusajs/medusa-eats/llms.txt Returns a single restaurant with its full product catalog and associated deliveries. ```APIDOC ## GET /store/restaurants/:id — Retrieve Restaurant with Deliveries Returns a single restaurant with full product catalog and associated deliveries (including cart and order items). ### Method GET ### Endpoint /store/restaurants/:id ### Query Parameters - **currency_code** (string) - Required - The currency code for pricing. ### Response #### Success Response (200) - **restaurant** (object) - The restaurant object. - **id** (string) - The unique identifier of the restaurant. - **name** (string) - The name of the restaurant. - **is_open** (boolean) - Indicates if the restaurant is currently open. - **products** (array) - List of products offered by the restaurant. - **deliveries** (array) - List of associated deliveries. - **id** (string) - The unique identifier of the delivery. - **delivery_status** (string) - The current status of the delivery. - **cart** (object) - The associated cart information. - **id** (string) - The unique identifier of the cart. - **items** (array) - Items in the cart. - **order** (object | null) - The associated order information, or null if not available. ``` -------------------------------- ### Driver Picks Up Order Source: https://context7.com/medusajs/medusa-eats/llms.txt Advances past `awaitPickUpStep`. Sets status to `in_transit`. ```APIDOC ## POST /store/deliveries/:id/pick-up — Driver Picks Up Order Advances past `awaitPickUpStep`. Sets status to `in_transit`. ### Method POST ### Endpoint `/store/deliveries/:id/pick-up` ### Parameters #### Path Parameters - **id** (string) - Required - The ID of the delivery to mark as picked up. ### Request Example ```bash curl -X POST "http://localhost:9000/store/deliveries/del_01J.../pick-up" ``` ### Response #### Success Response (200) - **delivery** (object) - Details of the updated delivery. - **delivery_status** (string) - The new status of the delivery (e.g., `in_transit`). ### Response Example ```json { "delivery": { "delivery_status": "in_transit", ... } } ``` ``` -------------------------------- ### Proceed with Delivery State Machine Source: https://context7.com/medusajs/medusa-eats/llms.txt This frontend server action inspects the current delivery status and automatically calls the correct next action. It is used by both restaurant and driver dashboards. For restaurant dashboards, only the delivery object is needed. For driver dashboards, a driverId is required for claiming. ```typescript // frontend/src/lib/actions/deliveries.ts import { proceedDelivery } from "@frontend/lib/actions/deliveries"; const delivery = await retrieveDelivery("del_01J..."); // For a restaurant dashboard button (no driverId needed): await proceedDelivery(delivery); // If status === "pending" → calls acceptDelivery() // If status === "pickup_claimed" → calls prepareDelivery() // If status === "restaurant_preparing" → calls preparationReady() // For a driver dashboard (driverId required for claiming): await proceedDelivery(delivery, "drv_01J..."); // If status === "restaurant_accepted" → calls claimDelivery(id, driverId) // If status === "ready_for_pickup" → calls pickUpDelivery() // If status === "in_transit" → calls completeDelivery() ``` -------------------------------- ### Manage Carts with Medusa JS SDK Source: https://context7.com/medusajs/medusa-eats/llms.txt Use these frontend server actions to manage carts. The `createCart` function requires a currency code and optionally a restaurant ID. `addToCart` creates a cart if none exists. `removeItemFromCart` removes a specific line item. ```typescript // frontend/src/lib/actions/carts.ts import { createCart, addToCart, removeItemFromCart } from "@frontend/lib/actions/carts"; // Create a new cart tied to a restaurant (EUR currency) const cart = await createCart({ currency_code: "eur" }, "res_01J..."); // cart: { id: "cart_01J...", items: [], region: { currency_code: "eur" }, ... } // Sets cookie: _medusa_cart_id = cart.id // Add a product variant to cart (creates cart if none exists) const updatedCart = await addToCart("variant_01J...", "res_01J..."); // updatedCart: { id: "cart_01J...", items: [{ variant_id: "variant_01J...", quantity: 1 }], ... } // Remove a line item await removeItemFromCart("li_01J..."); // Under the hood the SDK calls: // POST /store/carts → create // POST /store/carts/:id/line-items → add item // DELETE /store/carts/:id/line-items/:itemId → remove item ``` -------------------------------- ### SSE Real-Time Updates for Deliveries Source: https://context7.com/medusajs/medusa-eats/llms.txt Opens an SSE stream for deliveries. Use driver_id for driver-specific updates or restaurant_id for restaurant-wide updates. Requires credentials for authentication. ```typescript const driverEventSource = new EventSource( `http://localhost:9000/store/deliveries/subscribe?driver_id=drv_01J...`, { withCredentials: true } // passes auth cookie ); driverEventSource.onmessage = (event) => { const data = JSON.parse(event.data); // { message: "Subscribed to workflow", transactionId: "txn_01J..." } // or when a new delivery is dispatched to this driver: // { message: "Subscribed to workflow", transactionId: "txn_02J...", new: true } }; ``` ```typescript const restaurantEventSource = new EventSource( `http://localhost:9000/store/deliveries/subscribe?restaurant_id=res_01J...`, { withCredentials: true } ); ``` -------------------------------- ### List Deliveries with Filtering and Pagination Source: https://context7.com/medusajs/medusa-eats/llms.txt Retrieve a list of deliveries, optionally filtering by restaurant, driver, or status, and controlling the number of results with pagination parameters. The response includes cart and order data for each delivery. ```bash # All deliveries curl "http://localhost:9000/store/deliveries" # Filter by restaurant curl "http://localhost:9000/store/deliveries?restaurant_id=res_01J..." # Filter by driver (includes deliveries assigned to that driver) curl "http://localhost:9000/store/deliveries?driver_id=drv_01J..." # Filter by status with pagination curl "http://localhost:9000/store/deliveries?delivery_status=pending&take=10&skip=0" # Response: # { # "deliveries": [ # { # "id": "del_01J...", # "delivery_status": "pending", # "transaction_id": "txn_01J...", # "driver_id": null, # "eta": null, # "cart": { "id": "cart_01J...", "items": [...] }, # "order": null # } # ] # } # Frontend: import { listDeliveries, retrieveDelivery } from "@frontend/lib/data/deliveries"; const deliveries = await listDeliveries({ delivery_status: "pending" }); const delivery = await retrieveDelivery("del_01J..."); ``` -------------------------------- ### Subscribe to Real-Time Delivery Updates via SSE Source: https://context7.com/medusajs/medusa-eats/llms.txt Establish a Server-Sent Events stream to receive live updates for a specific delivery. Optionally, subscribe to new deliveries assigned to a particular restaurant or driver by including their IDs in the URL. ```typescript // frontend — subscribe to a single delivery's live status const eventSource = new EventSource( `http://localhost:9000/store/deliveries/del_01J.../subscribe?restaurant_id=res_01J...`, { withCredentials: false } ); eventSource.onmessage = (event) => { const data = JSON.parse(event.data); // Initial connection: // { message: "Subscribed to workflow", transactionId: "txn_01J..." } // On each workflow step transition: // { workflowId: "handle-delivery-workflow", transactionId: "txn_01J...", step: "notify-restaurant-step", status: "succeeded" } // When a new delivery arrives for the subscribed restaurant: // { message: "Subscribed to workflow", transactionId: "txn_02J...", new: true } console.log("Delivery update:", data); }; eventSource.onerror = () => { eventSource.close(); }; ``` -------------------------------- ### Link Restaurant to Products Source: https://context7.com/medusajs/medusa-eats/llms.txt Defines a remote link between the Restaurant module and the Product module, enabling a relationship between restaurants and their products. ```typescript // backend/src/links/restaurant-products.ts export default defineLink( RestaurantModule.linkable.restaurant, ProductModule.linkable.product ); ``` -------------------------------- ### Driver Picks Up Order Source: https://context7.com/medusajs/medusa-eats/llms.txt Confirms that the driver has picked up the order. Sets status to 'in_transit'. Use the delivery ID in the URL. ```bash curl -X POST "http://localhost:9000/store/deliveries/del_01J.../pick-up" ``` ```json # { "delivery": { "delivery_status": "in_transit", ... } } ``` ```javascript // Frontend: import { pickUpDelivery } from "@frontend/lib/actions/deliveries"; await pickUpDelivery("del_01J..."); ``` -------------------------------- ### SSE Real-Time Updates (Bulk) Source: https://context7.com/medusajs/medusa-eats/llms.txt Opens an SSE stream for all deliveries belonging to a restaurant_id or driver_id. Used by the restaurant and driver dashboards to receive updates across multiple concurrent deliveries. ```APIDOC ## GET /store/deliveries/subscribe — SSE Real-Time Updates (Bulk) Opens an SSE stream for all deliveries belonging to a `restaurant_id` or `driver_id`. Used by the restaurant and driver dashboards to receive updates across multiple concurrent deliveries. ### Query Parameters - **restaurant_id** (string) - Optional - The ID of the restaurant to subscribe to deliveries for. - **driver_id** (string) - Optional - The ID of the driver to subscribe to deliveries for. ### Request Example ```typescript // Driver dashboard — subscribe to all deliveries available to a driver const driverEventSource = new EventSource( `http://localhost:9000/store/deliveries/subscribe?driver_id=drv_01J...`, { withCredentials: true } // passes auth cookie ); driverEventSource.onmessage = (event) => { const data = JSON.parse(event.data); // { message: "Subscribed to workflow", transactionId: "txn_01J..." } // or when a new delivery is dispatched to this driver: // { message: "Subscribed to workflow", transactionId: "txn_02J...", new: true } }; // Restaurant dashboard — subscribe to all restaurant deliveries const restaurantEventSource = new EventSource( `http://localhost:9000/store/deliveries/subscribe?restaurant_id=res_01J...`, { withCredentials: true } ); ``` ```