Skip to main content

Dish Suggestions

This section documents the dish suggestion endpoints of the MiseOS API.

Dish suggestions allow kitchen staff to propose new dishes for upcoming menu weeks. Each suggestion is associated with a station, a target week, and a set of allergens.

Suggestions are reviewed by head chefs or sous chefs who can either approve or reject them. Approved suggestions are automatically converted into dishes in the dish bank, while rejected suggestions must include feedback for the creator.

Dish suggestion lifecycle
#

Kitchen staff can submit dish suggestions for upcoming weeks.

stateDiagram-v2
    [*] --> PENDING : suggestion created

    PENDING --> APPROVED : approve
    PENDING --> REJECTED : reject

    APPROVED --> DISH : dish created

Dish suggestions are created with the POST /dish-suggestions endpoint and initially have the status PENDING.

Endpoints
#

MethodURLAuth
GET/dish-suggestionsKITCHEN_STAFF
GET/dish-suggestions/current-weekHEAD_CHEF, SOUS_CHEF
GET/dish-suggestions/{id}KITCHEN_STAFF
POST/dish-suggestionsKITCHEN_STAFF
PUT/dish-suggestions/{id}KITCHEN_STAFF
DELETE/dish-suggestions/{id}KITCHEN_STAFF
DELETE/dish-suggestions/{id}/allergens/{allergenId}KITCHEN_STAFF
PATCH/dish-suggestions/{id}/approveHEAD_CHEF, SOUS_CHEF
PATCH/dish-suggestions/{id}/rejectHEAD_CHEF, SOUS_CHEF

DishSuggestion response object
#

The dish suggestion object has the following structure with approval status:

{
  "id": 1,
  "nameDA": "Røget Laks",
  "descriptionDA": "Laks med dild creme og rugbrødschips",
  "dishStatus": "APPROVED",
  "feedback": null,
  "station": { "id": 1, "name": "Cold Kitchen" },
  "createdBy": { "id": 2, "firstName": "Claire", "lastName": "Smyth" },
  "reviewedBy": { "id": 1, "firstName": "Gordon", "lastName": "Ramsay" },
  "reviewedAt": "2026-03-27 11:00",
  "allergens": [
    { "id": 1, "nameDA": "Gluten", "nameEN": "Gluten", "displayNumber": 1 },
    { "id": 4, "nameDA": "Fisk", "nameEN": "Fish", "displayNumber": 4 },
    { "id": 7, "nameDA": "Mælk", "nameEN": "Milk", "displayNumber": 7 }
  ],
  "targetWeek": 14,
  "targetYear": 2026,
  "deadline": "2026-05-07",
  "isPastDeadline": false,
  "createdAt": "2026-03-27 10:00",
  "updatedAt": null
}

deadline represents the submission deadline for the suggestion’s target week.
isPastDeadline indicates whether the deadline has already passed at the time of the request.

Status values
#

StatusDescription
PENDINGAwaiting review by head chef or sous chef
APPROVEDApproved and converted into a dish
REJECTEDRejected with feedback from management

GET /dish-suggestions
#

Returns dish suggestions filtered by query parameters.

Access rules:

  • Kitchen staff only see suggestions they created.
  • Head chefs and sous chefs can see suggestions from all stations.

Query parameters

ParameterTypeDescription
statusStringFilter by status: PENDING, APPROVED, REJECTED
weekIntegerTarget week — must be provided with year
yearIntegerTarget year — must be provided with week
stationIdLongFilter by station
orderByStringField used for sorting (status, station, createdAt)

Example Request
#

curl -H "Authorization: Bearer <token>" \
https://miseos.corral.dk/api/v1/dish-suggestions?status=PENDING&week=14&year=2026&stationId=1&orderBy=createdAt

Response 200 — array of dish suggestion objects.

[
  {
    "id": 1,
    "nameDA": "Røget Laks",
    "descriptionDA": "Laks med dild creme og rugbrødschips",
    "dishStatus": "PENDING",
    "feedback": null,
    "station": { "id": 1, "name": "Cold Kitchen" },
    "createdBy": { "id": 2, "firstName": "Claire", "lastName": "Smyth" },
    "reviewedBy": null,
    "reviewedAt": null,
    "allergens": [
      { "id": 1, "nameDA": "Gluten", "nameEN": "Gluten", "displayNumber": 1 },
      { "id": 4, "nameDA": "Fisk", "nameEN": "Fish", "displayNumber": 4 },
      { "id": 7, "nameDA": "Mælk", "nameEN": "Milk", "displayNumber": 7 }
    ],
    "targetWeek": 14,
    "targetYear": 2026,
    "deadline": "2026-05-07",
    "isPastDeadline": false,
    "createdAt": "2026-03-27 10:00",
    "updatedAt": null
  },
  {
    "id": 2,
    "nameDA": "Grillet Kylling",
    "descriptionDA": "Kylling med BBQ sauce og coleslaw",
    "dishStatus": "PENDING",
    "feedback": null,
    "station": { "id": 1, "name": "Hot Kitchen" },
    "createdBy": { "id": 3, "firstName": "Gino", "lastName": "D'Acampo" },
    "reviewedBy": null,
    "reviewedAt": null,
    "allergens": [
      { "id": 7, "nameDA": "Mælk", "nameEN": "Milk", "displayNumber": 7 }
    ],
    "targetWeek": 14,
    "targetYear": 2026,
    "deadline": "2026-05-07",
    "isPastDeadline": false,
    "createdAt": "2026-03-28 14:30",
    "updatedAt": null
  },
  ...
]

Errors

StatusCause
400week provided without year or vice versa

GET /dish-suggestions/current-week
#

Returns all suggestions for the current ISO week.

Query parameters

ParameterTypeDescription
statusStringOptional status filter

Example Request
#

curl -H "Authorization: Bearer <token>" \
https://miseos.corral.dk/api/v1/dish-suggestions/current-week?status=PENDING

Response 200 — array of dish suggestion objects.


GET /dish-suggestions/{id}
#

Returns a single suggestion. Line cooks can only view their own suggestions.

Example Request
#

curl -H "Authorization: Bearer <token>" \
https://miseos.corral.dk/api/v1/dish-suggestions/1

Response 200 — dish suggestion object.

Errors

StatusCause
403Line cook attempting to view another cook’s suggestion
404Suggestion not found

POST /dish-suggestions
#

Dish suggestions must be submitted before the weekly planning deadline.

The submission deadline is Wednesday of the week preceding the target week.
After this deadline, new suggestions for that week cannot be created or modified.

Request body

{
  "nameDA": "Grillet Torsk",
  "descriptionDA": "Saftig torsk med urter og citron",
  "stationId": 1,
  "allergenIds": [1, 4],
  "targetWeek": 20,
  "targetYear": 2026
}

Response 201 — created dish suggestion object.

Errors

StatusCause
400Missing required fields or invalid data
409Deadline for the target week has passed

PUT /dish-suggestions/{id}
#

Updates a suggestion. Only the creator or management can update. Only PENDING suggestions can be updated.

Request body

{
  "nameDA": "Grillet Torsk med Citron",
  "descriptionDA": "Saftig torsk med friske urter, citron og kapers",
  "allergenIds": [1, 4]
}

Response 200 — updated dish suggestion object.

Errors

StatusCause
400Missing required fields or invalid data
403Not the creator and not management
409Suggestion is not PENDING

DELETE /dish-suggestions/{id}/allergens/{allergenId}
#

Removes a single allergen from a suggestion. Only the creator or management can remove. Only PENDING suggestions can be modified.

Example Request
#

curl -X DELETE \
-H "Authorization: Bearer <token>" \
https://miseos.corral.dk/api/v1/dish-suggestions/5/allergens/1

Response 200 — updated dish suggestion object.

Errors

StatusCause
400Invalid dish suggestion or allergen ID
403Not the creator and not management
404Suggestion or allergen not found

DELETE /dish-suggestions/{id}
#

Deletes a suggestion. Only the creator, head chef, or sous chef can delete.

Example Request
#

curl -X DELETE \
-H "Authorization: Bearer <token>" \
https://miseos.corral.dk/api/v1/dish-suggestions/1

Response 204 — no content.

Errors

StatusCause
400Invalid dish suggestion ID
403Not the creator and not management
404Suggestion not found

PATCH /dish-suggestions/{id}/approve
#

Approves a suggestion. Automatically creates a dish in the dish bank. Triggers a WebSocket notification to the creator.

Example Request
#

curl -X PATCH \
-H "Authorization: Bearer <token>" \
https://miseos.corral.dk/api/v1/dish-suggestions/1/approve

Response 200 — updated dish suggestion object with status APPROVED.

Errors

StatusCause
400Invalid suggestion ID
404Suggestion not found
409Suggestion is not PENDING

PATCH /dish-suggestions/{id}/reject
#

Rejects a suggestion. A feedback message explaining the rejection is required and will be sent to the creator of the suggestion. Triggers a WebSocket notification to the creator.

Example Request
#

curl -X PATCH \
-H "Authorization: Bearer <token>" \
https://miseos.corral.dk/api/v1/dish-suggestions/1/reject

Request body

{
  "feedback": "Retten passer ikke til sommermenuen"
}

Response 200 — updated dish suggestion object with status REJECTED.

Errors

StatusCause
400Feedback is blank or too short
404Suggestion not found
409Suggestion is not PENDING