QA plan: API module — Lambda + API Gateway (#23)
Story: API module — Lambda (FastAPI/Mangum) + API Gateway HTTP API (#23)
Capability: AWS infrastructure (#19)
ADRs: RAG004 — Mangum adapter; RAG009 — Lambda authorizer on POST /query
Test scope
Section titled “Test scope”| Type | Coverage |
|---|---|
| IaC lint | terraform validate and tflint on modules/api pass |
| Static (plan review) | HTTP API (not REST API) is the gateway type |
| Static (plan review) | Lambda authorizer is attached to POST /query route only; /healthz has no authorizer |
| Static (plan review) | Authorizer caching is disabled (authorizer_result_ttl_in_seconds = 0) per RAG009 |
| Static (plan review) | Lambda execution role is scoped to specific ARNs (no * on bedrock, rds-data, secretsmanager) |
| Integration (manual, QA) | Lambda cold-start: GET /healthz returns 200 after a cold start (measured from CloudWatch log) |
| Integration (manual, QA) | POST /query without auth returns 401 |
| Integration (manual, QA) | POST /query with a valid bearer token returns 200 |
| Contract | OpenAPI spec on the deployed QA API Gateway matches committed openapi.yaml (Newman smoke run) |
| Security (B1) | Authorization header is absent from CloudWatch logs (Story #62 dependency; spot-checked here) |
| Security | Lambda memory and timeout are set to values that do not allow runaway compute |
Entry criteria
Section titled “Entry criteria”Exit criteria
Section titled “Exit criteria”- IaC lint exits 0
- Plan: HTTP API type confirmed, authorizer on POST /query only, cache TTL = 0, IAM scoped
- Manual QA: cold-start
/healthz200;/query401 without token;/query200 with valid token - Contract: Newman run against QA API passes all assertions in the Postman collection
Environments
Section titled “Environments”IaC lint: CI. Integration: manual against QA env. Contract: Newman in CI post-QA-deploy.
Tooling
Section titled “Tooling”terraform validate, tflint, Newman (Postman CLI), AWS CLI.
How tests are written
Section titled “How tests are written”Plan-level assertions via terraform show -json in CI. Newman collection covers the contract:
# Given the QA API is deployed# When Newman runs the rag-sample Postman collection against the QA base URLpostman collection run rag-sample.postman_collection.json --env-var "baseUrl=$QA_URL"# Then all requests pass their response schema and status code assertions- Mangum’s ASGI translation may not preserve all headers in the event-to-ASGI mapping; verify
Authorizationheader arrives correctly in the Lambda event object before the authorizer parses it. - Lambda package size: FastAPI + dependencies must fit within the Lambda deployment package limit (250MB unzipped). Validate with
pip install --targetanddu -sh.
Capability acceptance criteria link
Section titled “Capability acceptance criteria link”RAG004 + RAG009: FastAPI app deployed to Lambda via Mangum, HTTP API gateway, authorizer on POST /query with caching disabled. Exit criteria cover each requirement.
© 2026 Benjamin Arunski