feat(kitchen-ops-bff): bridge kitchen state into shared flow
This commit is contained in:
parent
fcaa7e0d91
commit
b6b6c8fcf6
@ -30,4 +30,6 @@ This BFF exposes kitchen board, claim or release, transition, and priority workf
|
|||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
- `kitchen-service` currently exposes claim but not a dedicated release contract, so the release route reuses the claim validation path and projects a release-oriented response for the BFF edge.
|
- `kitchen-service` currently exposes claim but not a dedicated release contract, so the release route reuses the claim validation path and projects a release-oriented response for the BFF edge.
|
||||||
|
- Transition requests now forward `ContextId` to `kitchen-service` so kitchen actions land in the correct shared restaurant lifecycle context.
|
||||||
|
- The BFF keeps temporary edge-state compatibility for existing web clients by translating `Cooking|Ready|Served` to the canonical kitchen-service states `Preparing|ReadyForPickup|Delivered`.
|
||||||
- Correlation IDs are preserved through Thalos session checks and kitchen-service calls.
|
- Correlation IDs are preserved through Thalos session checks and kitchen-service calls.
|
||||||
|
|||||||
@ -9,11 +9,10 @@ kitchen-ops-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.
|
- Kitchen board projection over linked restaurant tickets.
|
||||||
- Kitchen queue and dispatch optimization hooks.
|
- Kitchen work-item claim, release, transition, and priority workflows aligned with canonical kitchen-service state transitions.
|
||||||
- Kitchen work-item claim, release, transition, and priority workflows aligned with kitchen-service.
|
- Cross-app state continuity from customer or waiter submission through kitchen execution and POS readiness.
|
||||||
- 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 kitchen-ops-bff agilewebs/kitchen-ops-bff:de
|
|||||||
- Integration artifact path: `greenfield/demo/restaurant/docker-compose.yml`
|
- Integration artifact path: `greenfield/demo/restaurant/docker-compose.yml`
|
||||||
## Known Limitations
|
## Known Limitations
|
||||||
|
|
||||||
- Kitchen-ops now delegates dashboard and work-item actions to `kitchen-service`, but the upstream kitchen workflow adapter still serves deterministic demo data rather than database-backed state.
|
- Kitchen-ops now delegates dashboard and work-item actions to `kitchen-service`, which projects persisted kitchen ticket state and syncs order progression back into the shared restaurant lifecycle.
|
||||||
|
- Temporary edge-state translation remains in place for existing web clients until the Stage 47 kitchen web task adopts the canonical kitchen-service states directly.
|
||||||
- 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.
|
||||||
|
|||||||
@ -75,7 +75,11 @@ public sealed class KitchenWorkflowServiceClient(HttpClient httpClient) : IKitch
|
|||||||
{
|
{
|
||||||
using var response = await httpClient.PostAsJsonAsync(
|
using var response = await httpClient.PostAsJsonAsync(
|
||||||
"internal/kitchen/orders/transition",
|
"internal/kitchen/orders/transition",
|
||||||
new TransitionKitchenWorkItemPayload(request.OrderId, request.TicketId, request.TargetState),
|
new TransitionKitchenWorkItemPayload(
|
||||||
|
request.OrderId,
|
||||||
|
request.TicketId,
|
||||||
|
MapKitchenServiceState(request.TargetState),
|
||||||
|
request.ContextId ?? "demo-context"),
|
||||||
cancellationToken);
|
cancellationToken);
|
||||||
response.EnsureSuccessStatusCode();
|
response.EnsureSuccessStatusCode();
|
||||||
|
|
||||||
@ -88,8 +92,8 @@ public sealed class KitchenWorkflowServiceClient(HttpClient httpClient) : IKitch
|
|||||||
return new TransitionKitchenWorkItemResponse(
|
return new TransitionKitchenWorkItemResponse(
|
||||||
payload.OrderId,
|
payload.OrderId,
|
||||||
payload.TicketId,
|
payload.TicketId,
|
||||||
payload.PreviousState,
|
MapEdgeState(payload.PreviousState),
|
||||||
payload.CurrentState,
|
MapEdgeState(payload.CurrentState),
|
||||||
payload.Transitioned,
|
payload.Transitioned,
|
||||||
payload.Error);
|
payload.Error);
|
||||||
}
|
}
|
||||||
@ -155,7 +159,27 @@ public sealed class KitchenWorkflowServiceClient(HttpClient httpClient) : IKitch
|
|||||||
string ClaimedBy,
|
string ClaimedBy,
|
||||||
string Message);
|
string Message);
|
||||||
|
|
||||||
private sealed record TransitionKitchenWorkItemPayload(string OrderId, string TicketId, string TargetState);
|
private static string MapKitchenServiceState(string edgeState) => edgeState switch
|
||||||
|
{
|
||||||
|
"Cooking" => "Preparing",
|
||||||
|
"Ready" => "ReadyForPickup",
|
||||||
|
"Served" => "Delivered",
|
||||||
|
_ => edgeState
|
||||||
|
};
|
||||||
|
|
||||||
|
private static string MapEdgeState(string serviceState) => serviceState switch
|
||||||
|
{
|
||||||
|
"Preparing" => "Cooking",
|
||||||
|
"ReadyForPickup" => "Ready",
|
||||||
|
"Delivered" => "Served",
|
||||||
|
_ => serviceState
|
||||||
|
};
|
||||||
|
|
||||||
|
private sealed record TransitionKitchenWorkItemPayload(
|
||||||
|
string OrderId,
|
||||||
|
string TicketId,
|
||||||
|
string TargetState,
|
||||||
|
string ContextId);
|
||||||
|
|
||||||
private sealed record TransitionKitchenWorkItemResponsePayload(
|
private sealed record TransitionKitchenWorkItemResponsePayload(
|
||||||
string OrderId,
|
string OrderId,
|
||||||
|
|||||||
@ -4,4 +4,5 @@ public sealed record TransitionKitchenWorkItemRequest(
|
|||||||
string OrderId,
|
string OrderId,
|
||||||
string TicketId,
|
string TicketId,
|
||||||
string TargetState,
|
string TargetState,
|
||||||
string UpdatedBy);
|
string UpdatedBy,
|
||||||
|
string? ContextId = null);
|
||||||
|
|||||||
@ -65,7 +65,7 @@ public sealed class KitchenWorkflowServiceClientTests
|
|||||||
{
|
{
|
||||||
var adapter = new KitchenWorkflowServiceClient(CreateClient("""
|
var adapter = new KitchenWorkflowServiceClient(CreateClient("""
|
||||||
{
|
{
|
||||||
"orderId": "CO-1001",
|
"orderId": "ORD-1001",
|
||||||
"ticketId": "KT-1001",
|
"ticketId": "KT-1001",
|
||||||
"previousState": "Queued",
|
"previousState": "Queued",
|
||||||
"currentState": "Preparing",
|
"currentState": "Preparing",
|
||||||
@ -75,11 +75,11 @@ public sealed class KitchenWorkflowServiceClientTests
|
|||||||
"""));
|
"""));
|
||||||
|
|
||||||
var response = await adapter.TransitionWorkItemAsync(
|
var response = await adapter.TransitionWorkItemAsync(
|
||||||
new TransitionKitchenWorkItemRequest("CO-1001", "KT-1001", "Preparing", "chef-maya"),
|
new TransitionKitchenWorkItemRequest("ORD-1001", "KT-1001", "Cooking", "chef-maya", "demo-context"),
|
||||||
CancellationToken.None);
|
CancellationToken.None);
|
||||||
|
|
||||||
Assert.True(response.Transitioned);
|
Assert.True(response.Transitioned);
|
||||||
Assert.Equal("Preparing", response.CurrentState);
|
Assert.Equal("Cooking", response.CurrentState);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -131,7 +131,7 @@ public sealed class KitchenWorkflowServiceClientTests
|
|||||||
"items": [
|
"items": [
|
||||||
{
|
{
|
||||||
"workItemId": "WK-1001",
|
"workItemId": "WK-1001",
|
||||||
"orderId": "CO-1001",
|
"orderId": "ORD-1001",
|
||||||
"ticketId": "KT-1001",
|
"ticketId": "KT-1001",
|
||||||
"tableId": "T-08",
|
"tableId": "T-08",
|
||||||
"station": "hot-line",
|
"station": "hot-line",
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user