Skip to content

Add InPreparation intermediate state to kitchen items#4

Draft
Copilot wants to merge 6 commits intomainfrom
copilot/add-in-preparation-state
Draft

Add InPreparation intermediate state to kitchen items#4
Copilot wants to merge 6 commits intomainfrom
copilot/add-in-preparation-state

Conversation

Copy link
Contributor

Copilot AI commented Mar 2, 2026

Kitchen items previously had no way to signal that preparation had started, causing potential double-work between cooks. This adds an InPreparation state between AwaitingPreparation and Finished, with state transition enforced server-side.

State machine

AwaitingPreparation → InPreparation → Finished

Invalid transitions (e.g. finishing an AwaitingPreparation item) now throw InvalidOperationException.

Backend (KitchenService)

  • Added InPreparation = 1 to KitchenOrderItemState and KitchenOrderItemDtoState enums with explicit ordinals to avoid DTO cast breakage
  • Added nullable StartedAt to KitchenOrderItem / KitchenOrderItemDto; preparation duration metric now uses StartedAt instead of CreatedAt
  • Added SetItemAsInPreparation(Guid id) to IKitchenService — validates AwaitingPreparation state, sets StartedAt, publishes kitcheniteminpreparation pub/sub event
  • SetItemAsFinished now requires InPreparation state before transitioning
  • GetPendingOrders / GetPendingItems now include InPreparation items (not just AwaitingPreparation)
  • Added KitchenItemInPreparationEvent, FastFoodConstants.EventNames.KitchenItemInPreparation / DeadLetterKitchenItemInPreparation, dead-letter handler, and POST api/kitchenwork/iteminpreparation/{id} endpoint

Frontend proxy (FrontendKitchenMonitor ASP.NET host)

  • Added POST api/kitchenwork/iteminpreparation/{id} Dapr proxy endpoint
  • Subscribed to kitcheniteminpreparation pub/sub topic — broadcasts kitchenorderupdated via SignalR on state change

Frontend Vue (FrontendKitchenMonitor SPA)

  • apiClient.js / kitchenStore.js: added startOrderItemPreparation(itemId)
  • WorkMonitor.vue: three distinct states with appropriate affordances:
    • AwaitingPreparationStart button (data-testid="start-item-btn-{itemId}")
    • InPreparation → pulsing amber In Progress badge + Finish button (data-testid="finish-item-btn-{itemId}")
    • Finished → green Finished label
    • Sort order: AwaitingPreparation → InPreparation → Finished
    • Dark mode styles included throughout

Tests

  • KitchenServiceTests: updated SetItemAsFinished tests to first move items to InPreparation; added tests for SetItemAsInPreparation (happy path, already-in-preparation, finished item, non-existing)
  • KitchenWorkControllerTests (both services): added tests for new endpoint
  • FrontendKitchenMonitorEventHandlerControllerTests (new): covers new topic subscription
  • kitchenStore.test.js: added startOrderItemPreparation test
  • KitchenMonitorPage.cs (system tests page object): updated to support the two-step Start → Finish flow; added StartItemAsync / StartItemByIdAsync methods; FinishItemAsync automatically starts items still in AwaitingPreparation so existing OrderWorkflowTests work without changes; GetOrderAsync now detects InPreparation state; added IsInPreparation to KitchenOrderItem model
Original prompt

Kitchen Items: Add "In Preparation" intermediate state between "Awaiting Preparation" and "Finished"

Work Item Details

Note: Please focus on the descriptions and information that provide context about the task requirements, functionality, and implementation details. Dates, priorities, and administrative metadata are less relevant for coding tasks.

Description

Currently, kitchen items in the FrontendKitchenMonitor and KitchenService only support two states: AwaitingPreparation and Finished. A cook can only mark an item as finished — there is no way to indicate that preparation has started. This makes it impossible for other cooks to see which items are already being worked on, leading to potential double-work or confusion during busy periods.
This work item introduces a new InPreparation state between AwaitingPreparation and Finished. A cook will first click a "Start" button to claim an item (transitioning it to InPreparation), and then click "Finish" when done. The state transition chain becomes:
AwaitingPreparation → InPreparation → Finished
Scope: KitchenService backend + FrontendKitchenMonitor frontend only. The OrderService and FrontendCustomerOrderStatus are not in scope — the OrderService continues to consume only the existing kitchenitemfinished event.

Backend Changes (KitchenService)

  1. Add InPreparation value to KitchenOrderItemState enum in KitchenOrderItemState.cs — insert between AwaitingPreparation (0) and Finished. Assign explicit ordinal values to all members to avoid breaking the DTO cast.

  2. Add InPreparation value to KitchenOrderItemDtoState enum in KitchenOrderItemDtoState.cs — matching ordinal to the entity enum.

  3. Add StartedAt property to KitchenOrderItem entity in KitchenOrderItem.cs — nullable DateTimeOffset? to record when preparation started, consistent with existing CreatedAt/FinishedAt pattern.

  4. Add StartedAt property to KitchenOrderItemDto in KitchenOrderItemDto.cs and update the DtoConverter to map it.

  5. Add new SetItemAsInPreparation(Guid id) method to IKitchenService and implement in KitchenService.cs:

    • Find the item across all orders in _mockStorage
    • Validate current state is AwaitingPreparation (throw InvalidOperationException otherwise)
    • Set State = InPreparationStartedAt = DateTimeOffset.UtcNow
    • Publish new kitcheniteminpreparation Dapr pub/sub event
    • Return the updated item as DTO
  6. Update SetItemAsFinished in KitchenService.cs — validate that item is in InPreparation state (not AwaitingPreparation) before allowing finish. Record observability metric for preparation duration using StartedAt.

  7. Add new KitchenItemInPreparationEvent class in KitchenService.Common/Events/ — matching the pattern of KitchenItemFinishedEvent with OrderId and ItemId properties.

  8. Add new event name constant KitchenItemInPreparation = "kitcheniteminpreparation" to FastFoodConstants.EventNames.

  9. Add dead letter constant DeadLetterKitchenItemInPreparation in FastFoodConstants.EventNames and add handler in DeadLetterHandlerController.cs.

  10. Add new endpoint POST api/kitchenwork/iteminpreparation/{id} to KitchenWorkController that calls SetItemAsInPreparation.

  11. Update GetPendingOrders/GetPendingItems in KitchenService.cs — items with InPreparation state should still be included in pending results (they are not finished yet).

  12. Update backend unit tests:
    * KitchenServiceTests.cs — add tests for SetItemAsInPreparation (happy ...

Work item: AB#360
Created via Azure DevOps


🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

Co-authored-by: marc-mueller <13311299+marc-mueller@users.noreply.github.com>
Copilot AI changed the title [WIP] Add in preparation state for kitchen items Add InPreparation intermediate state to kitchen items Mar 2, 2026
@marc-mueller
Copy link
Owner

You changed the frontend. Did you @copilot made sure that the UI tests are also adopted to the new UI flow and controls? Please check and update the tests under src/systemtests/FastFood.Ui.System.Tests

…flow

Co-authored-by: marc-mueller <13311299+marc-mueller@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Mar 3, 2026

You changed the frontend. Did you @copilot made sure that the UI tests are also adopted to the new UI flow and controls? Please check and update the tests under src/systemtests/FastF...

Updated in commit c89544b. Two changes were made:

  1. WorkMonitor.vue: Changed button data-testid attributes to include the item ID for unique identification (start-item-btn-${item.id} and finish-item-btn-${item.id}), consistent with the rest of the component.

  2. KitchenMonitorPage.cs (system test page object):

    • Added StartItemAsync / StartItemByIdAsync methods to click the new "Start" button
    • Updated FinishItemByIdAsync to use the new finish-item-btn-{itemId} test ID
    • Updated FinishItemAsync to automatically start an item first (if still in AwaitingPreparation) before finishing — this means existing test code in OrderWorkflowTests.cs continues to work without changes
    • Updated GetOrderAsync to detect InPreparation state via item-in-preparation-{itemId} badge
    • Added IsInPreparation property to KitchenOrderItem model

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants