docs(customer-orders-bff): align customer workflows to shared lifecycle
This commit is contained in:
parent
40933edb84
commit
59554a217f
@ -26,4 +26,5 @@ This BFF exposes customer-facing order submission, status, detail, and history w
|
|||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
- Customer order submission currently maps `ItemIds.Count` into the upstream restaurant order workflow because the internal service contract still accepts aggregate item counts.
|
- 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.
|
- Correlation IDs are preserved through Thalos session checks and operations-service calls.
|
||||||
|
|||||||
@ -9,11 +9,10 @@ customer-orders-bff
|
|||||||
- Epic 3: Improve observability and operational readiness for demo compose environments.
|
- Epic 3: Improve observability and operational readiness for demo compose environments.
|
||||||
|
|
||||||
## Domain-Specific Candidate Features
|
## Domain-Specific Candidate Features
|
||||||
- Order lifecycle consistency and state transitions.
|
- Customer-facing projection over the shared restaurant lifecycle.
|
||||||
- Customer order detail and history views that stay aligned with operations-service workflows.
|
- Customer order detail and history views that stay aligned with waiter, kitchen, and POS state changes.
|
||||||
- Kitchen queue and dispatch optimization hooks.
|
- Cross-app order continuity from customer submission to kitchen preparation and POS payment.
|
||||||
- Operations control-plane policies (flags, service windows, overrides).
|
- Operations control-plane policies (flags, service windows, overrides).
|
||||||
- POS closeout and settlement summary alignment.
|
|
||||||
|
|
||||||
## Documentation Contract
|
## Documentation Contract
|
||||||
Any code change in this repository must include docs updates in the same branch.
|
Any code change in this repository must include docs updates in the same branch.
|
||||||
|
|||||||
@ -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`
|
- Integration artifact path: `greenfield/demo/restaurant/docker-compose.yml`
|
||||||
## Known Limitations
|
## 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.
|
- Demo PostgreSQL seeds validate integration contracts and smoke determinism, but do not yet imply full persistence implementation parity.
|
||||||
|
|||||||
@ -46,7 +46,8 @@ public sealed class OperationsCustomerOrdersServiceClient(HttpClient httpClient)
|
|||||||
|
|
||||||
public async Task<SubmitCustomerOrderResponse> SubmitOrderAsync(SubmitCustomerOrderRequest request, CancellationToken cancellationToken)
|
public async Task<SubmitCustomerOrderResponse> 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(
|
var payload = await SubmitOrderPayloadAsync(
|
||||||
new SubmitRestaurantOrderPayload(request.ContextId, request.OrderId, request.TableId, request.ItemIds.Count),
|
new SubmitRestaurantOrderPayload(request.ContextId, request.OrderId, request.TableId, request.ItemIds.Count),
|
||||||
cancellationToken);
|
cancellationToken);
|
||||||
|
|||||||
@ -24,10 +24,11 @@ public sealed class OperationsCustomerOrdersServiceClientTests
|
|||||||
{
|
{
|
||||||
var adapter = new OperationsCustomerOrdersServiceClient(CreateClient(StatusPayload));
|
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.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]
|
[Fact]
|
||||||
@ -42,25 +43,26 @@ public sealed class OperationsCustomerOrdersServiceClientTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task SubmitOrderAsync_MapsSubmitPayloadUsingItemCount()
|
public async Task SubmitOrderAsync_MapsSharedLifecycleAcceptanceUsingItemCount()
|
||||||
{
|
{
|
||||||
var adapter = new OperationsCustomerOrdersServiceClient(CreateClient("""
|
var adapter = new OperationsCustomerOrdersServiceClient(CreateClient("""
|
||||||
{
|
{
|
||||||
"contextId": "demo-context",
|
"contextId": "demo-context",
|
||||||
"orderId": "CO-1009",
|
"orderId": "ORD-1009",
|
||||||
"accepted": true,
|
"accepted": true,
|
||||||
"summary": "Order CO-1009 for table T-18 was accepted with 3 items.",
|
"summary": "Order ORD-1009 was accepted and is ready for kitchen dispatch.",
|
||||||
"status": "queued",
|
"status": "accepted",
|
||||||
"submittedAtUtc": "2026-03-31T12:30:00Z"
|
"submittedAtUtc": "2026-03-31T12:30:00Z"
|
||||||
}
|
}
|
||||||
"""));
|
"""));
|
||||||
|
|
||||||
var response = await adapter.SubmitOrderAsync(
|
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);
|
CancellationToken.None);
|
||||||
|
|
||||||
Assert.True(response.Accepted);
|
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)
|
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.",
|
"summary": "2 recent customer orders are visible for the active context.",
|
||||||
"orders": [
|
"orders": [
|
||||||
{
|
{
|
||||||
"orderId": "CO-1001",
|
"orderId": "ORD-1001",
|
||||||
"tableId": "T-08",
|
"tableId": "T-08",
|
||||||
"status": "preparing",
|
"status": "preparing",
|
||||||
"guestCount": 2,
|
"guestCount": 2,
|
||||||
"itemIds": [ "ITEM-101", "ITEM-202" ]
|
"itemIds": [ "ITEM-101", "ITEM-202" ]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"orderId": "CO-1002",
|
"orderId": "ORD-1002",
|
||||||
"tableId": "T-15",
|
"tableId": "T-15",
|
||||||
"status": "ready",
|
"status": "ready",
|
||||||
"guestCount": 4,
|
"guestCount": 4,
|
||||||
@ -103,8 +105,8 @@ public sealed class OperationsCustomerOrdersServiceClientTests
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"recentEvents": [
|
"recentEvents": [
|
||||||
"CO-1001 moved to preparing at kitchen hot-line station.",
|
"Order ORD-1001 moved to preparing at the kitchen hot-line station.",
|
||||||
"CO-1002 is ready for table pickup."
|
"Order ORD-1002 is ready for table pickup."
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
""";
|
""";
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user