diff --git a/docs/api/customer-order-workflows.md b/docs/api/customer-order-workflows.md index 4d5ca7d..00ccbd7 100644 --- a/docs/api/customer-order-workflows.md +++ b/docs/api/customer-order-workflows.md @@ -26,4 +26,5 @@ This BFF exposes customer-facing order submission, status, detail, and history w ## Notes - Customer order submission currently maps `ItemIds.Count` into the upstream restaurant order workflow because the internal service contract still accepts aggregate item counts. +- Successful submission writes into the same shared restaurant lifecycle later observed by waiter-floor, kitchen-ops, and POS projections. - Correlation IDs are preserved through Thalos session checks and operations-service calls. diff --git a/docs/roadmap/feature-epics.md b/docs/roadmap/feature-epics.md index 6e660f5..02a673a 100644 --- a/docs/roadmap/feature-epics.md +++ b/docs/roadmap/feature-epics.md @@ -9,11 +9,10 @@ customer-orders-bff - Epic 3: Improve observability and operational readiness for demo compose environments. ## Domain-Specific Candidate Features -- Order lifecycle consistency and state transitions. -- Customer order detail and history views that stay aligned with operations-service workflows. -- Kitchen queue and dispatch optimization hooks. +- Customer-facing projection over the shared restaurant lifecycle. +- Customer order detail and history views that stay aligned with waiter, kitchen, and POS state changes. +- Cross-app order continuity from customer submission to kitchen preparation and POS payment. - Operations control-plane policies (flags, service windows, overrides). -- POS closeout and settlement summary alignment. ## Documentation Contract Any code change in this repository must include docs updates in the same branch. diff --git a/docs/runbooks/containerization.md b/docs/runbooks/containerization.md index cd8a94b..ba137cc 100644 --- a/docs/runbooks/containerization.md +++ b/docs/runbooks/containerization.md @@ -39,5 +39,6 @@ docker run --rm -p 8080:8080 --name customer-orders-bff agilewebs/customer-order - Integration artifact path: `greenfield/demo/restaurant/docker-compose.yml` ## Known Limitations -- Customer-orders now delegates workflow snapshots to `operations-service`, but the upstream operations adapter still serves deterministic demo data rather than database-backed state. +- Customer-orders now delegates workflow snapshots to `operations-service`, which projects persisted shared lifecycle state from `operations-dal`. +- Kitchen and POS visibility still depend on the remaining Stage 46-48 restaurant flow tasks being wired end-to-end. - Demo PostgreSQL seeds validate integration contracts and smoke determinism, but do not yet imply full persistence implementation parity. diff --git a/src/Customer.Orders.Bff.Application/Adapters/OperationsCustomerOrdersServiceClient.cs b/src/Customer.Orders.Bff.Application/Adapters/OperationsCustomerOrdersServiceClient.cs index 1d523c3..4654885 100644 --- a/src/Customer.Orders.Bff.Application/Adapters/OperationsCustomerOrdersServiceClient.cs +++ b/src/Customer.Orders.Bff.Application/Adapters/OperationsCustomerOrdersServiceClient.cs @@ -46,7 +46,8 @@ public sealed class OperationsCustomerOrdersServiceClient(HttpClient httpClient) public async Task SubmitOrderAsync(SubmitCustomerOrderRequest request, CancellationToken cancellationToken) { - // operations-service still accepts aggregate item counts for restaurant order submission. + // The customer BFF writes into the same shared restaurant lifecycle used by waiter, kitchen, and POS. + // The upstream contract still accepts aggregate counts, so the edge contract projects item IDs into count. var payload = await SubmitOrderPayloadAsync( new SubmitRestaurantOrderPayload(request.ContextId, request.OrderId, request.TableId, request.ItemIds.Count), cancellationToken); diff --git a/tests/Customer.Orders.Bff.Application.UnitTests/OperationsCustomerOrdersServiceClientTests.cs b/tests/Customer.Orders.Bff.Application.UnitTests/OperationsCustomerOrdersServiceClientTests.cs index 7a1dd14..ea33acc 100644 --- a/tests/Customer.Orders.Bff.Application.UnitTests/OperationsCustomerOrdersServiceClientTests.cs +++ b/tests/Customer.Orders.Bff.Application.UnitTests/OperationsCustomerOrdersServiceClientTests.cs @@ -24,10 +24,11 @@ public sealed class OperationsCustomerOrdersServiceClientTests { var adapter = new OperationsCustomerOrdersServiceClient(CreateClient(StatusPayload)); - var response = await adapter.FetchDetailAsync(new GetCustomerOrderDetailRequest("demo-context", "CO-1001"), CancellationToken.None); + var response = await adapter.FetchDetailAsync(new GetCustomerOrderDetailRequest("demo-context", "ORD-1001"), CancellationToken.None); Assert.NotNull(response.Order); - Assert.Equal("CO-1001", response.Order!.OrderId); + Assert.Equal("ORD-1001", response.Order!.OrderId); + Assert.Contains("preparing", response.Summary, StringComparison.OrdinalIgnoreCase); } [Fact] @@ -42,25 +43,26 @@ public sealed class OperationsCustomerOrdersServiceClientTests } [Fact] - public async Task SubmitOrderAsync_MapsSubmitPayloadUsingItemCount() + public async Task SubmitOrderAsync_MapsSharedLifecycleAcceptanceUsingItemCount() { var adapter = new OperationsCustomerOrdersServiceClient(CreateClient(""" { "contextId": "demo-context", - "orderId": "CO-1009", + "orderId": "ORD-1009", "accepted": true, - "summary": "Order CO-1009 for table T-18 was accepted with 3 items.", - "status": "queued", + "summary": "Order ORD-1009 was accepted and is ready for kitchen dispatch.", + "status": "accepted", "submittedAtUtc": "2026-03-31T12:30:00Z" } """)); var response = await adapter.SubmitOrderAsync( - new SubmitCustomerOrderRequest("demo-context", "CO-1009", "T-18", 4, ["ITEM-101", "ITEM-202", "ITEM-303"]), + new SubmitCustomerOrderRequest("demo-context", "ORD-1009", "T-18", 4, ["ITEM-101", "ITEM-202", "ITEM-303"]), CancellationToken.None); Assert.True(response.Accepted); - Assert.Equal("queued", response.Status); + Assert.Equal("accepted", response.Status); + Assert.Contains("kitchen dispatch", response.Summary); } private static HttpClient CreateClient(string json) @@ -88,14 +90,14 @@ public sealed class OperationsCustomerOrdersServiceClientTests "summary": "2 recent customer orders are visible for the active context.", "orders": [ { - "orderId": "CO-1001", + "orderId": "ORD-1001", "tableId": "T-08", "status": "preparing", "guestCount": 2, "itemIds": [ "ITEM-101", "ITEM-202" ] }, { - "orderId": "CO-1002", + "orderId": "ORD-1002", "tableId": "T-15", "status": "ready", "guestCount": 4, @@ -103,8 +105,8 @@ public sealed class OperationsCustomerOrdersServiceClientTests } ], "recentEvents": [ - "CO-1001 moved to preparing at kitchen hot-line station.", - "CO-1002 is ready for table pickup." + "Order ORD-1001 moved to preparing at the kitchen hot-line station.", + "Order ORD-1002 is ready for table pickup." ] } """;