feat(api): /tokenize now runs the full round trip

Repoint public POST /tokenize at the orchestrator (tokenize -> agent -> restore)
so a single path returns {final, deidentified_prompt, agent_tokenized,
session_id} — matching what Fusion mirrors from the front-end path, and what
openapi.yaml already documents. The granular detector moves to internal
/tokenize-raw (x-api-key protected; the orchestrator calls it). /demo kept as an
alias so the UI keeps working.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-02 19:05:26 +10:00
parent 7973556647
commit 9626887ed7

View File

@@ -107,9 +107,11 @@ resource "aws_apigatewayv2_integration" "tokenize" {
payload_format_version = "2.0"
}
# Granular detector is now INTERNAL at /tokenize-raw (x-api-key protected); the
# orchestrator calls it. Public POST /tokenize does the full round trip (below).
resource "aws_apigatewayv2_route" "tokenize" {
api_id = aws_apigatewayv2_api.gateway.id
route_key = "POST /tokenize"
route_key = "POST /tokenize-raw"
target = "integrations/${aws_apigatewayv2_integration.tokenize.id}"
}
@@ -117,7 +119,29 @@ resource "aws_apigatewayv2_stage" "default" {
api_id = aws_apigatewayv2_api.gateway.id
name = "$default"
auto_deploy = true
tags = local.onprem_tag
# Access logs capture the RAW method + path AWS received -- for debugging what
# Fusion actually sends (404 route-no-match never reaches a Lambda log).
access_log_settings {
destination_arn = aws_cloudwatch_log_group.apigw_access.arn
format = jsonencode({
requestId = "$context.requestId"
ip = "$context.identity.sourceIp"
method = "$context.httpMethod"
path = "$context.path"
routeKey = "$context.routeKey"
status = "$context.status"
protocol = "$context.protocol"
userAgent = "$context.identity.userAgent"
integrationError = "$context.integrationErrorMessage"
})
}
tags = local.onprem_tag
}
resource "aws_cloudwatch_log_group" "apigw_access" {
name = "/apigw/${local.name}-gateway-access"
retention_in_days = 7
tags = local.onprem_tag
}
resource "aws_lambda_permission" "tokenize_apigw" {
@@ -261,7 +285,7 @@ resource "aws_lambda_function" "orchestrator" {
environment {
variables = {
REGION = var.region
TOKENIZE_URL = "${trimsuffix(aws_apigatewayv2_stage.default.invoke_url, "/")}/tokenize"
TOKENIZE_URL = "${trimsuffix(aws_apigatewayv2_stage.default.invoke_url, "/")}/tokenize-raw"
RESTORE_URL = "${trimsuffix(aws_apigatewayv2_stage.default.invoke_url, "/")}/restore"
TOKENIZE_API_KEY = var.tokenize_api_key
AGENT_RUNTIME_ARN = var.agent_runtime_arn
@@ -277,12 +301,21 @@ resource "aws_apigatewayv2_integration" "orchestrator" {
payload_format_version = "2.0"
}
# Full round trip (tokenize -> agent -> restore). Public entrypoint is /tokenize
# (what Fusion mirrors); /demo kept as an alias so the existing UI keeps working.
resource "aws_apigatewayv2_route" "orchestrator" {
api_id = aws_apigatewayv2_api.gateway.id
route_key = "POST /demo"
target = "integrations/${aws_apigatewayv2_integration.orchestrator.id}"
}
resource "aws_apigatewayv2_route" "orchestrator_tokenize" {
api_id = aws_apigatewayv2_api.gateway.id
route_key = "POST /tokenize"
target = "integrations/${aws_apigatewayv2_integration.orchestrator.id}"
depends_on = [aws_apigatewayv2_route.tokenize] # free up "POST /tokenize" first
}
resource "aws_lambda_permission" "orchestrator_apigw" {
statement_id = "AllowApiGatewayInvoke"
action = "lambda:InvokeFunction"