Compare commits
No commits in common. "a347eebde42dc7c360f62d600aaea7ffebd5c556" and "bf787069979a225ee93b4ab246135eb0d002713b" have entirely different histories.
a347eebde4
...
bf78706997
@ -26,6 +26,4 @@ This BFF exposes execution-facing waiter workflows over REST while delegating or
|
|||||||
## Notes
|
## 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.
|
- 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 through the same runtime path.
|
|
||||||
- Assignment and recent-activity reads are already lifecycle-backed through `operations-service`, so this BFF does not need a separate summary-projection fallback for the Stage 49 propagation wave.
|
|
||||||
- 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,12 @@ waiter-floor-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
|
||||||
- Waiter-facing projection over the shared restaurant order/check lifecycle.
|
- Order lifecycle consistency and state transitions.
|
||||||
- Waiter assignment visibility with recent floor activity derived from persisted restaurant state.
|
- Waiter assignment visibility with recent floor activity context.
|
||||||
- Waiter order update workflows that stay aligned with service-level restaurant order orchestration.
|
- Waiter order update workflows that stay aligned with service-level restaurant order orchestration.
|
||||||
- Cross-app order continuity from waiter submission to kitchen preparation and POS payment.
|
- Kitchen queue and dispatch optimization hooks.
|
||||||
- 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,6 +39,5 @@ docker run --rm -p 8080:8080 --name waiter-floor-bff agilewebs/waiter-floor-bff:
|
|||||||
- Integration artifact path: `greenfield/demo/restaurant/docker-compose.yml`
|
- Integration artifact path: `greenfield/demo/restaurant/docker-compose.yml`
|
||||||
## Known Limitations
|
## Known Limitations
|
||||||
|
|
||||||
- Waiter-floor now delegates workflow snapshots to `operations-service`, which in turn projects persisted shared lifecycle state from `operations-dal`.
|
- Waiter-floor now delegates workflow snapshots to `operations-service`, but the upstream operations adapter still serves deterministic demo data rather than database-backed state.
|
||||||
- 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.
|
- Demo PostgreSQL seeds validate integration contracts and smoke determinism, but do not yet imply full persistence implementation parity.
|
||||||
|
|||||||
@ -57,8 +57,7 @@ public sealed class OperationsWaiterServiceClient(HttpClient httpClient) : IWait
|
|||||||
new SubmitRestaurantOrderPayload(request.ContextId, request.OrderId, request.TableId, request.ItemCount),
|
new SubmitRestaurantOrderPayload(request.ContextId, request.OrderId, request.TableId, request.ItemCount),
|
||||||
cancellationToken);
|
cancellationToken);
|
||||||
|
|
||||||
// The waiter BFF deliberately reuses the shared order-write contract so both submit and update
|
// operations-service currently accepts a full order snapshot for both submit and update semantics.
|
||||||
// actions stay aligned with the canonical restaurant lifecycle owned by operations-service.
|
|
||||||
var summary = payload.Accepted
|
var summary = payload.Accepted
|
||||||
? $"Updated order {payload.OrderId}. {payload.Summary}"
|
? $"Updated order {payload.OrderId}. {payload.Summary}"
|
||||||
: payload.Summary;
|
: payload.Summary;
|
||||||
|
|||||||
@ -15,12 +15,12 @@ public sealed class OperationsWaiterServiceClientTests
|
|||||||
{
|
{
|
||||||
"contextId": "demo-context",
|
"contextId": "demo-context",
|
||||||
"locationId": "restaurant-demo",
|
"locationId": "restaurant-demo",
|
||||||
"summary": "2 tables currently require floor attention.",
|
"summary": "2 active waiter assignments are currently visible.",
|
||||||
"assignments": [
|
"assignments": [
|
||||||
{ "waiterId": "service-pool", "tableId": "T-12", "status": "Preparing", "activeOrders": 2 }
|
{ "waiterId": "waiter-01", "tableId": "T-12", "status": "serving", "activeOrders": 2 }
|
||||||
],
|
],
|
||||||
"recentActivity": [
|
"recentActivity": [
|
||||||
"Order ORD-1002 is currently preparing for table T-12."
|
"demo-context: table T-12 requested dessert menus"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
@ -31,8 +31,7 @@ public sealed class OperationsWaiterServiceClientTests
|
|||||||
Assert.Equal("restaurant-demo", response.LocationId);
|
Assert.Equal("restaurant-demo", response.LocationId);
|
||||||
Assert.Single(response.Assignments);
|
Assert.Single(response.Assignments);
|
||||||
Assert.Single(response.RecentActivity);
|
Assert.Single(response.RecentActivity);
|
||||||
Assert.Equal("service-pool", response.Assignments.Single().WaiterId);
|
Assert.Equal("waiter-01", response.Assignments.Single().WaiterId);
|
||||||
Assert.Equal("Preparing", response.Assignments.Single().Status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -42,10 +41,10 @@ public sealed class OperationsWaiterServiceClientTests
|
|||||||
{
|
{
|
||||||
"contextId": "demo-context",
|
"contextId": "demo-context",
|
||||||
"locationId": "restaurant-demo",
|
"locationId": "restaurant-demo",
|
||||||
"summary": "2 tables currently require floor attention.",
|
"summary": "2 active waiter assignments are currently visible.",
|
||||||
"assignments": [],
|
"assignments": [],
|
||||||
"recentActivity": [
|
"recentActivity": [
|
||||||
"Order ORD-1003 was served at table T-21 and is ready for payment capture."
|
"demo-context: table T-08 is waiting for payment capture"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
@ -55,19 +54,18 @@ public sealed class OperationsWaiterServiceClientTests
|
|||||||
|
|
||||||
Assert.Equal("demo-context", response.ContextId);
|
Assert.Equal("demo-context", response.ContextId);
|
||||||
Assert.Single(response.RecentActivity);
|
Assert.Single(response.RecentActivity);
|
||||||
Assert.Contains("floor attention", response.Summary);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task SubmitOrderAsync_MapsSharedLifecycleAcceptanceResponse()
|
public async Task SubmitOrderAsync_MapsOperationsPayloadToSubmitResponse()
|
||||||
{
|
{
|
||||||
var client = CreateClient("""
|
var client = CreateClient("""
|
||||||
{
|
{
|
||||||
"contextId": "demo-context",
|
"contextId": "demo-context",
|
||||||
"orderId": "ORD-42",
|
"orderId": "ORD-42",
|
||||||
"accepted": true,
|
"accepted": true,
|
||||||
"summary": "Order ORD-42 was accepted and is ready for kitchen dispatch.",
|
"summary": "Order ORD-42 for table T-12 was accepted with 3 items.",
|
||||||
"status": "accepted",
|
"status": "queued",
|
||||||
"submittedAtUtc": "2026-03-31T10:15:00Z"
|
"submittedAtUtc": "2026-03-31T10:15:00Z"
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
@ -76,21 +74,20 @@ public sealed class OperationsWaiterServiceClientTests
|
|||||||
var response = await adapter.SubmitOrderAsync(new SubmitFloorOrderRequest("demo-context", "T-12", "ORD-42", 3), CancellationToken.None);
|
var response = await adapter.SubmitOrderAsync(new SubmitFloorOrderRequest("demo-context", "T-12", "ORD-42", 3), CancellationToken.None);
|
||||||
|
|
||||||
Assert.True(response.Accepted);
|
Assert.True(response.Accepted);
|
||||||
Assert.Equal("accepted", response.Status);
|
Assert.Equal("queued", response.Status);
|
||||||
Assert.Equal("demo-context", response.ContextId);
|
Assert.Equal("demo-context", response.ContextId);
|
||||||
Assert.Contains("kitchen dispatch", response.Summary);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task UpdateOrderAsync_PrefixesSharedLifecycleUpdateSummary()
|
public async Task UpdateOrderAsync_PrefixesAcceptedUpdateSummary()
|
||||||
{
|
{
|
||||||
var client = CreateClient("""
|
var client = CreateClient("""
|
||||||
{
|
{
|
||||||
"contextId": "demo-context",
|
"contextId": "demo-context",
|
||||||
"orderId": "ORD-42",
|
"orderId": "ORD-42",
|
||||||
"accepted": true,
|
"accepted": true,
|
||||||
"summary": "Order ORD-42 was accepted and is ready for kitchen dispatch.",
|
"summary": "Order ORD-42 for table T-12 was accepted with 4 items.",
|
||||||
"status": "accepted",
|
"status": "queued",
|
||||||
"submittedAtUtc": "2026-03-31T10:15:00Z"
|
"submittedAtUtc": "2026-03-31T10:15:00Z"
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
@ -99,8 +96,7 @@ public sealed class OperationsWaiterServiceClientTests
|
|||||||
var response = await adapter.UpdateOrderAsync(new UpdateFloorOrderRequest("demo-context", "T-12", "ORD-42", 4), CancellationToken.None);
|
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.Contains("Updated order ORD-42.", response.Summary);
|
||||||
Assert.Contains("kitchen dispatch", response.Summary);
|
Assert.Equal("queued", response.Status);
|
||||||
Assert.Equal("accepted", response.Status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static HttpClient CreateClient(string json)
|
private static HttpClient CreateClient(string json)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user