Skip to content

CCM-15258 - Event target subscription changes#64

Open
mjewildnhs wants to merge 54 commits intomainfrom
feature/CCM-15258
Open

CCM-15258 - Event target subscription changes#64
mjewildnhs wants to merge 54 commits intomainfrom
feature/CCM-15258

Conversation

@mjewildnhs
Copy link
Contributor

@mjewildnhs mjewildnhs commented Mar 24, 2026

Description

Updates the callbacks delivery pipeline to route events per-subscription/per-target (including per-target DLQs) and introduces tooling to manage the clientId→applicationId map in SSM used for signing.

Changes:

  • Add applications-map-add CLI command and SSM repository support for maintaining the applications map parameter.
  • Update transform/filter lambda output to include payload, matched subscriptions, and per-target signatures; update EventBridge Pipes + Terraform to fan out events per-subscription/per-target with per-target DLQs.
  • Refactor integration tests to seed config via tooling/JSON seed config and validate received callback headers (API key + signature).
  • Fix for intermittent issue in ITs caused by clock skew

Context

Type of changes

  • Refactoring (non-breaking change)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would change existing functionality)
  • Bug fix (non-breaking change which fixes an issue)

Checklist

  • I am familiar with the contributing guidelines
  • I have followed the code style of the project
  • I have added tests to cover my changes
  • I have updated the documentation accordingly
  • This PR is a result of pair or mob programming

Sensitive Information Declaration

To ensure the utmost confidentiality and protect your and others privacy, we kindly ask you to NOT including PII (Personal Identifiable Information) / PID (Personal Identifiable Data) or any other sensitive data in this PR (Pull Request) and the codebase changes. We will remove any PR that do contain any sensitive information. We really appreciate your cooperation in this matter.

  • I confirm that neither PII/PID nor sensitive data are included in this PR and the codebase changes.

@mjewildnhs mjewildnhs force-pushed the feature/CCM-15258 branch 2 times, most recently from 912b615 to 2756004 Compare March 24, 2026 19:08
CLIENT_ID=$(jq -r '.clientId' "${SEED_CONFIG_FILE}")
MOCK_APPLICATION_ID="some-application-id"
FUNCTION_NAME="nhs-${ENVIRONMENT}-callbacks-mock-webhook"
MOCK_WEBHOOK_URL=$(aws lambda get-function-url-config \
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be better if we created the webhooks from the config as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally we'd have a few of them so the IT can assert we are sending to the correct target and not just all targets.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually we can just have 1 but use different paths for the different destinations

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Testing deleting clients would be good idea too

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the callbacks delivery pipeline to route events per-subscription/per-target (including per-target DLQs) and introduces tooling to manage the clientId→applicationId map in SSM used for signing.

Changes:

  • Add applications-map-add CLI command and SSM repository support for maintaining the applications map parameter.
  • Update transform/filter lambda output to include payload, matched subscriptions, and per-target signatures; update EventBridge Pipes + Terraform to fan out events per-subscription/per-target with per-target DLQs.
  • Refactor integration tests to seed config via tooling/JSON seed config and validate received callback headers (API key + signature).

Reviewed changes

Copilot reviewed 49 out of 49 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
tools/client-subscriptions-management/src/repository/ssm-applications-map.ts New SSM-backed repository for reading/updating the applications map parameter.
tools/client-subscriptions-management/src/format.ts Add formatted (masked) display for applications map output.
tools/client-subscriptions-management/src/entrypoint/cli/index.ts Register new applications-map-add CLI command.
tools/client-subscriptions-management/src/entrypoint/cli/helper.ts Add SSM parameter-name option and repository factory for SSM applications map operations.
tools/client-subscriptions-management/src/entrypoint/cli/applications-map-add.ts New CLI command to add/update client→application mapping in SSM.
tools/client-subscriptions-management/src/aws.ts Add SSM client creation + parameter-name derivation/resolution + SSM repo factory.
tools/client-subscriptions-management/src/tests/repository/ssm-applications-map.test.ts Unit tests for SSM applications map repository behavior.
tools/client-subscriptions-management/src/tests/format.test.ts Tests for applications map formatting/masking.
tools/client-subscriptions-management/src/tests/entrypoint/cli/applications-map-add.test.ts CLI tests to ensure correct wiring and no application-id logging.
tools/client-subscriptions-management/src/tests/aws.test.ts Tests for parameter-name derivation/resolution helpers.
tools/client-subscriptions-management/package.json Add applications-map-add script and SSM client dependency.
tests/integration/tsconfig.json Enable resolveJsonModule for JSON-based seed config import.
tests/integration/jest.global-teardown.ts Remove S3 teardown; integration config now seeded via tooling before apply.
tests/integration/jest.global-setup.ts Remove S3 setup; integration config now seeded via tooling before apply.
tests/integration/helpers/sqs.ts Derive DLQ queue URL from seeded targetId instead of a fixed name.
tests/integration/helpers/signature.ts Resolve signing inputs from env and add shared header assertions for integration tests.
tests/integration/helpers/seed-config.ts New helper to load typed seed config from JSON.
tests/integration/helpers/mock-client-subscription.json New JSON seed config used by integration tests/tooling.
tests/integration/helpers/index.ts Export seed-config helpers.
tests/integration/helpers/event-factories.ts Use seeded clientId when creating test events.
tests/integration/helpers/cloudwatch.ts Parse and expose x-api-key from webhook logs in addition to signature.
tests/integration/event-bus-to-webhook.test.ts Use shared header assertions and update DLQ wording to per-target.
tests/integration/dlq-redrive.test.ts Use shared header assertions and update DLQ wording to per-target.
scripts/tests/integration.sh Seed client config + applications map before running integration tests; export env for signature checks.
package.json Add workspace script wrapper applications-map:add.
lambdas/mock-webhook-lambda/src/index.ts Improve function-url compatibility and expand structured logging for received callbacks.
lambdas/mock-webhook-lambda/src/tests/index.test.ts Update logging test to match new structured log event.
lambdas/mock-webhook-lambda/jest.config.ts Adjust coverage threshold (branches).
lambdas/client-transform-filter-lambda/src/services/subscription-filter.ts Return matched subscriptionIds alongside targetIds.
lambdas/client-transform-filter-lambda/src/handler.ts Emit payload/subscriptions/signatures; sign per-target and record delivery context separately.
lambdas/client-transform-filter-lambda/src/tests/services/subscription-filter.test.ts Update expectations to include returned subscription IDs.
lambdas/client-transform-filter-lambda/src/tests/index.test.ts Update handler output shape tests; add cases for mixed/missing target apiKeys.
lambdas/client-transform-filter-lambda/src/tests/index.component.test.ts Update component expectations for new output shape and signatures map.
infrastructure/terraform/modules/clients/README.md Add generated module README stub.
infrastructure/terraform/modules/client-destination/variables.tf Replace per-client variables with flattened targets/subscriptions/subscription_targets inputs.
infrastructure/terraform/modules/client-destination/module_target_dlq.tf Create one DLQ per target (for_each).
infrastructure/terraform/modules/client-destination/iam_role_api_target_role.tf Allow access to all per-target API destinations and DLQs.
infrastructure/terraform/modules/client-destination/cloudwatch_event_rule_main.tf Create rules per subscription and targets per subscription-target pairing; transform input payload and set signature header per target.
infrastructure/terraform/modules/client-destination/cloudwatch_event_connection_main.tf Create connections per target with per-target API key.
infrastructure/terraform/modules/client-destination/cloudwatch_event_api_destination_this.tf Create API destinations per target.
infrastructure/terraform/modules/client-destination/README.md Update documentation to reflect new flattened inputs.
infrastructure/terraform/components/callbacks/variables.tf Remove obsolete clients variable.
infrastructure/terraform/components/callbacks/sync-client-config.sh New pre-apply script to sync client config JSONs from S3 into the repo for Terraform consumption.
infrastructure/terraform/components/callbacks/pre.sh Run the client-config sync script before Terraform apply.
infrastructure/terraform/components/callbacks/pipes_pipe_main.tf Update Pipe input template to new lambda output shape.
infrastructure/terraform/components/callbacks/module_client_destination.tf Switch from per-client module instances to a single module fed by flattened locals.
infrastructure/terraform/components/callbacks/locals.tf Load client configs from synced JSON files, flatten targets/subscriptions, and build subscription-target fanout map.
infrastructure/terraform/components/callbacks/README.md Remove documentation for removed clients input.
README.md Update architecture description to per-target DLQs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is created automatically as the dir is referenced in the terraform. Not sure if worth trying stop stop this - bit confusing being empty.

@mjewildnhs mjewildnhs marked this pull request as ready for review March 25, 2026 21:15
@mjewildnhs mjewildnhs requested review from a team as code owners March 25, 2026 21:15
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice if this script could just copy mock-client.json in - this would simplify some of the terraform in locals.tf
However there isn't currently a mechanism to set env vars accessible to the pre.sh.
We can set tfvars (like var.deploy_mock_client_subscriptions)
but these aren't visible outside of terraform.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants