Skip to main content

Ingredient Requests

This section documents the ingredient request endpoints of the MiseOS API.

Kitchen staff can submit ingredient requests for upcoming delivery dates. Head chefs and sous chefs can review requests and approve or reject them. Approved requests are later aggregated into shopping lists.

Ingredient request workflow
#

 
stateDiagram-v2

[*] --> PENDING : Staff submits request

PENDING --> APPROVED : Head/Sous chef approves
PENDING --> REJECTED : Head/Sous chef rejects
PENDING --> DELETED : Owner or Head/Sous deletes

APPROVED --> [*]
REJECTED --> [*]
DELETED --> [*]

The diagram illustrates the lifecycle of an ingredient request, starting from submission (PENDING) to either approval, rejection, or deletion. Only pending requests can be approved or rejected, and only pending requests can be deleted by the owner or Head/Sous chefs.

Endpoints
#

MethodURLAuth
GET/ingredient-requestsKITCHEN_STAFF
GET/ingredient-requests/{id}KITCHEN_STAFF
POST/ingredient-requestsKITCHEN_STAFF
PUT/ingredient-requests/{id}KITCHEN_STAFF
DELETE/ingredient-requests/{id}KITCHEN_STAFF
PATCH/ingredient-requests/{id}/approveHEAD_CHEF, SOUS_CHEF
PATCH/ingredient-requests/{id}/rejectHEAD_CHEF, SOUS_CHEF

Visibility rule:

  • Head chefs and sous chefs can see all requests
  • Other kitchen staff only see their own requests

Ingredient Request response object
#

The ingredient request object has the following structure:

{
  "id": 1,
  "name": "Frisk Dild",
  "quantity": 10.0,
  "unit": "BUNCH",
  "preferredSupplier": "Grønttorvet",
  "note": "Til laksen",
  "status": "PENDING",
  "requestType": "DISH_SPECIFIC",
  "deliveryDate": "2026-04-01",
  "requestedBy": { "id": 2, "firstName": "Claire", "lastName": "Smyth" },
  "dish": { "id": 1, "dishNameDA": "Røget Laks", "dishNameEN": "Smoked Salmon" },
  "reviewedAt": null,
  "createdAt": "2026-03-27 10:00",
  "updatedAt": null
}

Status values: PENDING | APPROVED | REJECTED
Request type values: DISH_SPECIFIC | GENERAL_STOCK
Unit values: KG | G | L | ML | PCS | BUNCH | SIDES | BOX | BOTTLE | CAN


GET /ingredient-requests
#

Returns ingredient requests with optional filters.

Query parameters

ParameterTypeDescription
statusStringFilter by request status
deliveryDateLocalDateFilter by delivery date (yyyy-MM-dd)
requestTypeStringFilter by request type
stationIdLongFilter by station

Response 200 — array of ingredient request objects.

Errors

StatusCause
400Invalid query value (status, requestType, date format, stationId)

GET /ingredient-requests/{id}
#

Returns a single ingredient request.

Response 200 — ingredient request object.

Errors

StatusCause
403User is not owner and not management
404Request not found

POST /ingredient-requests
#

Creates a new ingredient request.

Validation rules:

  • deliveryDate cannot be in the past
  • deliveryDate cannot be more than 30 days ahead
  • dishId is required for DISH_SPECIFIC
  • For non-management users, dish must belong to user’s station
  • Dish must be active

Request body

{
  "name": "Frisk Dild",
  "quantity": 10.0,
  "unit": "BUNCH",
  "preferredSupplier": "Grønttorvet",
  "note": "Til laksen",
  "requestType": "DISH_SPECIFIC",
  "deliveryDate": "2026-04-01",
  "dishId": 1
}

Response 201 — created ingredient request object.

Errors

StatusCause
400Invalid payload, invalid date window, or missing required fields
403Dish belongs to different station
404Dish/user not found

PUT /ingredient-requests/{id}
#

Updates an existing request.

Rules:

  • Owner or management can update
  • Business rule validation is applied in domain/service layer
  • Payload updates request content fields (not review action)

Request body

{
  "name": "Frisk Dild",
  "quantity": 8.0,
  "unit": "BUNCH",
  "preferredSupplier": "Grønttorvet",
  "note": "Opdateret mængde",
  "requestType": "DISH_SPECIFIC",
  "deliveryDate": "2026-04-01",
  "dishId": 1
}

Response 200 — updated ingredient request object.

Errors

StatusCause
400Invalid payload or date validation failure
403User is not owner and not management
404Request or dish not found
409Request cannot be modified in current state

DELETE /ingredient-requests/{id}
#

Deletes an ingredient request.

Rules:

  • Owner or management can delete
  • Domain rules for deletable state are enforced

Response 204 — no content.

Errors

StatusCause
403User is not owner and not management
404Request not found
409Request cannot be deleted in current state

PATCH /ingredient-requests/{id}/approve
#

Approves a request.
Optional payload can adjust approved quantity/note before approval.

Request body (optional)

{
  "quantity": 8.0,
  "note": "Reduceret mængde godkendt"
}

If body is omitted, current values are kept.

Response 200 — updated ingredient request object (status: APPROVED).

Errors

StatusCause
404Request not found
409Request is not in approvable state

PATCH /ingredient-requests/{id}/reject
#

Rejects a request.

Response 200 — updated ingredient request object (status: REJECTED).

Errors

StatusCause
404Request not found
409Request is not in rejectable state

Notifications
#

These endpoints trigger WebSocket notifications:

  • POST /ingredient-requests → admin pending count broadcast
  • PATCH /ingredient-requests/{id}/approve → direct staff notification + pending count update
  • PATCH /ingredient-requests/{id}/reject → direct staff notification + pending count update
  • DELETE /ingredient-requests/{id} (if deleted) → pending count update