Skip to content

Commit 983cd09

Browse files
committed
Commit todo file for posterity
1 parent 0b4fbaa commit 983cd09

1 file changed

Lines changed: 95 additions & 0 deletions

File tree

TODO.md

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
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

Comments
 (0)