# Backoffice REST as a Framework Channel This project now treats the TIM/ANATEL Backoffice REST contracts as a corporate channel instead of letting the HTTP routes call a domain workflow executor directly. ## Target execution model ```text Legacy-compatible REST endpoint ↓ BackofficeRestChannelAdapter ↓ ChannelGateway normalization path ↓ BackofficeWorkflowDispatcher ↓ Backoffice workflow LangGraph ↓ Framework layers: guardrails, supervisor, judges, checkpoint, telemetry, MCP ↓ Legacy-compatible REST response adapter ``` ## What changed ### New files - `app/channels/backoffice_rest_adapter.py` - Converts legacy Backoffice REST payloads into `BackofficeChannelEnvelope`. - Preserves the original payload under `request_context`. - Extracts canonical `business_context` such as `customer_key`, `contract_key`, `interaction_key` and `session_key`. - Passes the request through `ChannelGateway.normalize(...)` using `channel = backoffice_rest`. - Falls back to the web adapter shape when the installed framework does not yet have a dedicated `backoffice_rest` adapter. - `app/workflows/backoffice_workflow_dispatcher.py` - Receives a normalized channel envelope. - Emits framework telemetry events for channel normalization and workflow dispatch. - Invokes the correct operational workflow: - `backoffice_checklist` - `backoffice_response_emulator` ### Updated file - `app/main.py` - The compatibility routes no longer call `BackofficeWorkflowExecutor.execute_workflow(...)` directly. - They now call: ```python BackofficeRestChannelAdapter ↓ BackofficeWorkflowDispatcher ↓ BackofficeWorkflowExecutor ``` The `BackofficeWorkflowExecutor` still owns the compiled LangGraph workflows, but it is now behind the channel/dispatcher boundary rather than being the direct REST entrypoint. ## Why this is architecturally cleaner The REST routes are now only transport adapters. They preserve the old external contract, but the request enters the same conceptual pipeline used by other framework channels. This avoids the previous coupling: ```text REST route → BackofficeWorkflowExecutor ``` and replaces it with: ```text REST route → channel adapter → ChannelGateway → workflow dispatcher → LangGraph workflow ``` ## Compatibility The existing routes remain available: - `POST /agent/process-ticket` - `POST /agent/execute` - `POST /agent/process-and-stream` - `POST /case/{transaction_id}/response-emulator/generate` - `POST /case/{transaction_id}/response-emulator/finalize` The response builders are preserved, so external clients should not need to change their payload or response handling. ## Runtime notes The metadata added to workflow state now includes: ```text framework_entrypoint = channel_gateway channel = backoffice_rest normalized_channel = backoffice_rest or web fallback business_context = canonical business keys channel_context = normalized gateway context ``` This makes Langfuse/telemetry easier to interpret because Backoffice REST is visible as a channel entrypoint, not as an ad-hoc executor call.