docs(waiter-floor-bff): align waiter workflows to shared lifecycle

This commit is contained in:
José René White Enciso 2026-03-31 18:50:18 -06:00
parent bf78706997
commit 95dc218f28
5 changed files with 23 additions and 18 deletions

View File

@ -26,4 +26,5 @@ This BFF exposes execution-facing waiter workflows over REST while delegating or
## Notes
- The update route currently reuses the operations order submission contract so waiter-floor can expose update semantics without introducing a new cross-repo dependency.
- Both order mutations project into the shared restaurant lifecycle owned by `operations-service`, which means kitchen and POS can observe the same order/check state after downstream stages are wired.
- Correlation IDs are preserved through Thalos session checks and operations-service calls.

View File

@ -9,12 +9,11 @@ waiter-floor-bff
- Epic 3: Improve observability and operational readiness for demo compose environments.
## Domain-Specific Candidate Features
- Order lifecycle consistency and state transitions.
- Waiter assignment visibility with recent floor activity context.
- Waiter-facing projection over the shared restaurant order/check lifecycle.
- Waiter assignment visibility with recent floor activity derived from persisted restaurant state.
- Waiter order update workflows that stay aligned with service-level restaurant order orchestration.
- Kitchen queue and dispatch optimization hooks.
- Cross-app order continuity from waiter 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.

View File

@ -39,5 +39,6 @@ docker run --rm -p 8080:8080 --name waiter-floor-bff agilewebs/waiter-floor-bff:
- Integration artifact path: `greenfield/demo/restaurant/docker-compose.yml`
## Known Limitations
- Waiter-floor now delegates workflow snapshots to `operations-service`, but the upstream operations adapter still serves deterministic demo data rather than database-backed state.
- Waiter-floor now delegates workflow snapshots to `operations-service`, which in turn projects persisted shared lifecycle state from `operations-dal`.
- Kitchen-driven progression and POS payment visibility 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.

View File

@ -57,7 +57,8 @@ public sealed class OperationsWaiterServiceClient(HttpClient httpClient) : IWait
new SubmitRestaurantOrderPayload(request.ContextId, request.OrderId, request.TableId, request.ItemCount),
cancellationToken);
// operations-service currently accepts a full order snapshot for both submit and update semantics.
// The waiter BFF deliberately reuses the shared order-write contract so both submit and update
// actions stay aligned with the canonical restaurant lifecycle owned by operations-service.
var summary = payload.Accepted
? $"Updated order {payload.OrderId}. {payload.Summary}"
: payload.Summary;

View File

@ -17,10 +17,10 @@ public sealed class OperationsWaiterServiceClientTests
"locationId": "restaurant-demo",
"summary": "2 active waiter assignments are currently visible.",
"assignments": [
{ "waiterId": "waiter-01", "tableId": "T-12", "status": "serving", "activeOrders": 2 }
{ "waiterId": "service-pool", "tableId": "T-12", "status": "Preparing", "activeOrders": 2 }
],
"recentActivity": [
"demo-context: table T-12 requested dessert menus"
"Order ORD-1002 is currently preparing for table T-12."
]
}
""");
@ -31,7 +31,8 @@ public sealed class OperationsWaiterServiceClientTests
Assert.Equal("restaurant-demo", response.LocationId);
Assert.Single(response.Assignments);
Assert.Single(response.RecentActivity);
Assert.Equal("waiter-01", response.Assignments.Single().WaiterId);
Assert.Equal("service-pool", response.Assignments.Single().WaiterId);
Assert.Equal("Preparing", response.Assignments.Single().Status);
}
[Fact]
@ -44,7 +45,7 @@ public sealed class OperationsWaiterServiceClientTests
"summary": "2 active waiter assignments are currently visible.",
"assignments": [],
"recentActivity": [
"demo-context: table T-08 is waiting for payment capture"
"Order ORD-1003 was served at table T-21 and is ready for payment capture."
]
}
""");
@ -57,15 +58,15 @@ public sealed class OperationsWaiterServiceClientTests
}
[Fact]
public async Task SubmitOrderAsync_MapsOperationsPayloadToSubmitResponse()
public async Task SubmitOrderAsync_MapsSharedLifecycleAcceptanceResponse()
{
var client = CreateClient("""
{
"contextId": "demo-context",
"orderId": "ORD-42",
"accepted": true,
"summary": "Order ORD-42 for table T-12 was accepted with 3 items.",
"status": "queued",
"summary": "Order ORD-42 was accepted and is ready for kitchen dispatch.",
"status": "accepted",
"submittedAtUtc": "2026-03-31T10:15:00Z"
}
""");
@ -74,20 +75,21 @@ public sealed class OperationsWaiterServiceClientTests
var response = await adapter.SubmitOrderAsync(new SubmitFloorOrderRequest("demo-context", "T-12", "ORD-42", 3), CancellationToken.None);
Assert.True(response.Accepted);
Assert.Equal("queued", response.Status);
Assert.Equal("accepted", response.Status);
Assert.Equal("demo-context", response.ContextId);
Assert.Contains("kitchen dispatch", response.Summary);
}
[Fact]
public async Task UpdateOrderAsync_PrefixesAcceptedUpdateSummary()
public async Task UpdateOrderAsync_PrefixesSharedLifecycleUpdateSummary()
{
var client = CreateClient("""
{
"contextId": "demo-context",
"orderId": "ORD-42",
"accepted": true,
"summary": "Order ORD-42 for table T-12 was accepted with 4 items.",
"status": "queued",
"summary": "Order ORD-42 was accepted and is ready for kitchen dispatch.",
"status": "accepted",
"submittedAtUtc": "2026-03-31T10:15:00Z"
}
""");
@ -96,7 +98,8 @@ public sealed class OperationsWaiterServiceClientTests
var response = await adapter.UpdateOrderAsync(new UpdateFloorOrderRequest("demo-context", "T-12", "ORD-42", 4), CancellationToken.None);
Assert.Contains("Updated order ORD-42.", response.Summary);
Assert.Equal("queued", response.Status);
Assert.Contains("kitchen dispatch", response.Summary);
Assert.Equal("accepted", response.Status);
}
private static HttpClient CreateClient(string json)