|
| 1 | +# FIXME: Delete this file |
| 2 | + |
| 3 | + |
| 4 | +# CDK Migration TODO — Stateless Stack |
| 5 | + |
| 6 | +This file tracks the migration of stateless components from SAM templates to CDK. |
| 7 | +Stateful resources (DynamoDB tables, SSM parameters, Secrets Manager secrets, SQS queues) remain in SAM. |
| 8 | + |
| 9 | +## Lambda Functions (`SAMtemplates/functions/main.yaml`) |
| 10 | + |
| 11 | +Each Lambda includes the function itself, a nested `lambda_resources.yaml` stack (IAM role, log group, Splunk subscription filter), and associated IAM policies. |
| 12 | + |
| 13 | +- [x] **UpdatePrescriptionStatus** — Core function that writes prescription status updates to DynamoDB and sends SQS messages for notifications. Has extensive IAM policies for DynamoDB, SQS, Secrets Manager, and SSM parameters. *(uses `TypescriptLambdaFunction` construct)* |
| 14 | +- [x] **ConvertRequestToFhirFormat (CPSU)** — Converts custom format requests to FHIR format. No additional IAM policies beyond basic Lambda execution. *(uses `TypescriptLambdaFunction` construct)* |
| 15 | +- [x] **GetStatusUpdates** — Reads prescription status updates from DynamoDB. Needs DynamoDB read and KMS policies. *(uses `TypescriptLambdaFunction` construct)* |
| 16 | +- [x] **Status** — Returns `_status` health check info (version, commit ID). Needs Secrets Manager access. *(uses `TypescriptLambdaFunction` construct)* |
| 17 | +- [x] **CapabilityStatement** — Returns FHIR CapabilityStatement. No additional IAM policies. *(uses `TypescriptLambdaFunction` construct)* |
| 18 | +- [x] **CheckPrescriptionStatusUpdates** — Conditionally deployed (`DeployCheckPrescriptionStatusUpdate`). Reads from DynamoDB. Needs DynamoDB read and KMS policies. *(conditional `TypescriptLambdaFunction` construct)* |
| 19 | +- [x] **NotifyProcessor** — Processes NHS Notify messages from SQS on a 1-minute schedule (EventBridge Scheduler). Needs SQS, DynamoDB, Secrets Manager, SSM, and KMS policies. Has a dedicated scheduler IAM role. *(uses `TypescriptLambdaFunction` + `CfnSchedule`)* |
| 20 | +- [x] **PostDatedNotifyLambda** — Processes post-dated notifications on a 15-minute schedule (EventBridge Scheduler). Needs SQS and DynamoDB policies. Has a dedicated scheduler IAM role. *(uses `TypescriptLambdaFunction` + `CfnSchedule`)* |
| 21 | +- [x] **NHSNotifyUpdateCallback** — Handles NHS Notify delivery status callbacks. Needs DynamoDB and Secrets Manager policies. *(uses `TypescriptLambdaFunction` construct)* |
| 22 | +- [x] **PsuRestoreValidation** — Conditionally deployed (`EnableBackup`). Validates DynamoDB backup restores. Has a custom IAM policy for `backup:PutRestoreValidationResult` and an EventBridge rule for restore job state changes. *(conditional `TypescriptLambdaFunction` + `Rule`)* |
| 23 | + |
| 24 | +### Per-Lambda shared resources (`lambda_resources.yaml`) |
| 25 | +Each Lambda above has a nested stack that creates: |
| 26 | +- [x] IAM execution role with CloudWatch Logs permissions *(handled by `TypescriptLambdaFunction` construct)* |
| 27 | +- [x] CloudWatch Log Group (with configurable retention, optional KMS encryption) *(handled by `TypescriptLambdaFunction` construct)* |
| 28 | +- [x] Splunk subscription filter (conditional on `EnableSplunk`) *(handled by `TypescriptLambdaFunction` construct — always enabled)* |
| 29 | +- [x] Execute Lambda managed policy (exported for cross-stack references) *(handled by `TypescriptLambdaFunction` construct)* |
| 30 | + |
| 31 | +## State Machines (`SAMtemplates/state_machines/main.yaml`) |
| 32 | + |
| 33 | +Each state machine includes the state machine itself and a nested `state_machine_resources.yaml` stack (IAM role, log group, Splunk subscription filter). |
| 34 | + |
| 35 | +- [x] **UpdatePrescriptionStatusStateMachine** — EXPRESS type. Invokes FHIR Validator (cross-stack import from `fhir-validator` stack) and UpdatePrescriptionStatus Lambda. Uses ASL definition file `UpdatePrescriptionStatusStateMachine.asl.json`. *(uses `ExpressStateMachine` construct + CDK step function definition)* |
| 36 | +- [x] **Format1UpdatePrescriptionsStatusStateMachine** — EXPRESS type. Invokes ConvertRequestToFhirFormat and UpdatePrescriptionStatus Lambdas. Uses ASL definition file `Format1UpdatePrescriptionsStatusStateMachine.asl.json`. *(uses `ExpressStateMachine` construct + CDK step function definition)* |
| 37 | + |
| 38 | +### Per-state-machine shared resources (`state_machine_resources.yaml`) |
| 39 | +Each state machine has a nested stack that creates: |
| 40 | +- [x] IAM execution role with state machine and Lambda invoke permissions *(handled by `ExpressStateMachine` construct)* |
| 41 | +- [x] CloudWatch Log Group (with configurable retention, optional KMS encryption) *(handled by `ExpressStateMachine` construct)* |
| 42 | +- [x] Splunk subscription filter (conditional on `EnableSplunk`) *(handled by `ExpressStateMachine` construct — always enabled)* |
| 43 | +- [x] Execute state machine managed policy (exported for cross-stack references) *(handled by `ExpressStateMachine` construct)* |
| 44 | + |
| 45 | +## API Gateway (`SAMtemplates/apis/main.yaml`) |
| 46 | + |
| 47 | +- [x] **ACM Certificate** (`GenerateCertificate`) — DNS-validated certificate for the custom domain. *(handled by `RestApiGateway` construct)* |
| 48 | +- [x] **REST API** (`RestApiGateway`) — Regional REST API with optional execute-api endpoint disabling (when mTLS is enabled). *(handled by `RestApiGateway` construct)* |
| 49 | +- [x] **Custom Domain** (`RestApiDomain`) — Regional domain with TLS 1.2, optional mTLS truststore from S3. *(handled by `RestApiGateway` construct)* |
| 50 | +- [x] **Route 53 Record** (`RestApiRecordSet`) — Alias A record pointing to the API Gateway domain. *(handled by `RestApiGateway` construct)* |
| 51 | +- [x] **API Deployment and Stage** (`RestApiGatewayDeploymentV2h`, `RestApiGatewayStage`) — Deployment with X-Ray tracing and structured access logging. *(handled by `RestApiGateway` construct via `deploy: true`)* |
| 52 | +- [x] **Domain Mapping** (`RestApiDomainMapping`) — Base path mapping to the `prod` stage. *(handled by `RestApiGateway` construct)* |
| 53 | + |
| 54 | +### API Endpoints |
| 55 | +- [x] **POST /** — `UpdatePrescriptionStatusMethod` — Step Functions integration (StartSyncExecution) to UpdatePrescriptionStatus state machine. *(root resource method in `Apis` construct)* |
| 56 | +- [x] **POST /format-1** — `Format1UpdatePrescriptionStatusMethod` — Step Functions integration to Format1 state machine. *(uses `StateMachineEndpoint` construct)* |
| 57 | +- [x] **POST /notification-delivery-status-callback** — `NotificationDeliveryStatusCallbackMethod` — Lambda proxy integration to NHSNotifyUpdateCallback. *(uses `LambdaEndpoint` construct)* |
| 58 | +- [x] **GET /_status** — `StatusLambdaMethod` — Lambda proxy integration to Status function. *(uses `LambdaEndpoint` construct)* |
| 59 | +- [x] **GET /metadata** — `CapabilityStatementMethod` — Lambda proxy integration to CapabilityStatement function. *(uses `LambdaEndpoint` construct)* |
| 60 | +- [x] **GET /checkprescriptionstatusupdates** — `CheckPrescriptionStatusUpdatesMethod` — Conditional. Lambda proxy integration. *(conditional `LambdaEndpoint` in `Apis` construct)* |
| 61 | +- [x] **POST /get-status-updates** — `GetStatusUpdatesMethod` — Conditional. Lambda integration (non-proxy) with request/response templates. *(conditional non-proxy `LambdaIntegration` in `Apis` construct)* |
| 62 | + |
| 63 | +### API shared resources (`api_resources.yaml`) |
| 64 | +- [x] API Gateway IAM role with policies to invoke Lambdas and state machines *(handled by `RestApiGateway` construct)* |
| 65 | +- [x] API Gateway access log group (with configurable retention, optional KMS encryption) *(handled by `RestApiGateway` construct)* |
| 66 | +- [x] Splunk subscription filter (conditional on `EnableSplunk`) *(handled by `RestApiGateway` construct — always enabled)* |
| 67 | +- [x] CSOC log forwarding (conditional on `ForwardCsocLogs`) *(handled by `RestApiGateway` construct)* |
| 68 | + |
| 69 | +## CloudWatch Alarms (`SAMtemplates/alarms/main.yaml`) |
| 70 | + |
| 71 | +### Log Metric Filters |
| 72 | +- [ ] `GetStatusUpdatesErrorsLogsMetricFilter` — Filters ERROR level logs from GetStatusUpdates |
| 73 | +- [ ] `PrescriptionStatusUpdateErrorsLogsMetricFilter` — Filters 500 status responses from UpdatePrescriptionStatus |
| 74 | +- [ ] `PrescriptionStatusUpdateForcedErrorsLogsMetricFilter` — Filters forced INT test errors |
| 75 | +- [ ] `CPSUFhirConverterErrorLogsMetricFilter` — Filters 500 status responses from CPSU converter |
| 76 | +- [ ] `NotifyProcessorTimeoutsMetricFilter` — Filters timeout messages from NotifyProcessor |
| 77 | + |
| 78 | +### Alarms |
| 79 | +- [ ] `GetStatusUpdatesErrorsAlarm` — Alerts on GetStatusUpdates errors |
| 80 | +- [ ] `GetStatusUpdatesUnhandledErrorsAlarm` — Alerts on GetStatusUpdates unhandled Lambda errors |
| 81 | +- [ ] `PrescriptionStatusUpdateErrorsAlarm` — Alerts on true 500 errors (excludes forced INT test errors via math expression) |
| 82 | +- [ ] `PrescriptionStatusUpdateUnhandledErrorsAlarm` — Alerts on unhandled Lambda errors |
| 83 | +- [ ] `DynamoDBSystemErrorsAlarm` — Alerts on DynamoDB system errors |
| 84 | +- [ ] `DynamoDBWriteConsumptionAlarm` — Alerts when DynamoDB write usage nears provisioned capacity threshold |
| 85 | +- [ ] `CPSUFhirConverterErrorsAlarm` — Alerts on CPSU FHIR converter errors |
| 86 | +- [ ] `NotifyProcessorTimeoutsAlarm` — Alerts on NotifyProcessor timeouts |
| 87 | +- [ ] `NHSNotifyPrescriptionsDeadLetterQueueMessagesAlarm` — Alerts on DLQ messages |
| 88 | + |
| 89 | +## Cross-cutting concerns |
| 90 | + |
| 91 | +- [ ] **Splunk log forwarding** — Conditionally enabled per log group via subscription filters. Requires `SplunkDeliveryStreamArn` and `SplunkSubscriptionFilterRole` from `lambda-resources` stack. |
| 92 | +- [ ] **CSOC log forwarding** — Conditional forwarding of API Gateway access logs to CSOC destination. |
| 93 | +- [ ] **KMS encryption** — CloudWatch log groups optionally encrypted with `account-resources:CloudwatchLogsKmsKeyArn`. |
| 94 | +- [ ] **Cross-stack imports** — Many resources import values from `account-resources`, `lambda-resources`, `eps-route53-resources`, and `fhir-validator` stacks. These will become `Fn.importValue()` calls in CDK. |
| 95 | +- [ ] **Conditional deployments** — `CheckPrescriptionStatusUpdates` and `GetStatusUpdates` endpoints are conditionally deployed. `PsuRestoreValidation` depends on `EnableBackup`. These will need CDK conditions or conditional construct instantiation. |
0 commit comments