diff --git a/.github/scripts/release_code.sh b/.github/scripts/release_code.sh index bae80f5c1c..47a7e5813b 100755 --- a/.github/scripts/release_code.sh +++ b/.github/scripts/release_code.sh @@ -69,6 +69,7 @@ sam deploy \ EnabledSiteODSCodesValue="${ENABLED_SITE_ODS_CODES:-' '}" \ EnablePostDatedNotifications="$ENABLE_POST_DATED_NOTIFICATIONS" \ EnabledSystemsValue="${ENABLED_SYSTEMS:-' '}" \ + EnabledSupplierApplicationIDsValue="${ENABLED_SUPPLIER_APPLICATION_IDS:-' '}" \ BlockedSiteODSCodesValue="${BLOCKED_SITE_ODS_CODES:-' '}" \ NotifyRoutingPlanIDValue="$NOTIFY_ROUTING_PLAN_ID" \ NotifyAPIBaseURLValue="$NOTIFY_API_BASE_URL" \ diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f250528843..06982f91fe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -81,6 +81,7 @@ jobs: ENABLE_POST_DATED_NOTIFICATIONS: true ENABLED_SYSTEMS: "Internal Test System" BLOCKED_SITE_ODS_CODES: "B3J1Z" + ENABLED_SUPPLIER_APPLICATION_IDS: "XXXXX" NOTIFY_ROUTING_PLAN_ID: "e57fe5cc-0567-4854-abe2-b7dd9014a50c" NOTIFY_API_BASE_URL: "https://int.api.service.nhs.uk" MTLS_KEY: psu-mtls-1 @@ -124,6 +125,7 @@ jobs: ENABLE_POST_DATED_NOTIFICATIONS: true ENABLED_SYSTEMS: "Internal Test System" BLOCKED_SITE_ODS_CODES: "B3J1Z" + ENABLED_SUPPLIER_APPLICATION_IDS: "XXXXX" # Workaround empty string handling NOTIFY_ROUTING_PLAN_ID: "e57fe5cc-0567-4854-abe2-b7dd9014a50c" NOTIFY_API_BASE_URL: "https://int.api.service.nhs.uk" MTLS_KEY: psu-mtls-1 @@ -135,7 +137,8 @@ jobs: PROXYGEN_ROLE: ${{ secrets.PROXYGEN_PTL_ROLE }} release_qa: - needs: [tag_release, release_dev, package_code, get_commit_id, get_config_values] + needs: + [tag_release, release_dev, package_code, get_commit_id, get_config_values] uses: ./.github/workflows/run_release_code_and_api.yml with: pinned_image: ${{ needs.get_config_values.outputs.pinned_image }} @@ -164,6 +167,7 @@ jobs: ENABLE_POST_DATED_NOTIFICATIONS: true ENABLED_SYSTEMS: "Internal Test System" BLOCKED_SITE_ODS_CODES: "B3J1Z" + ENABLED_SUPPLIER_APPLICATION_IDS: "XXXXX" # Workaround empty string handling NOTIFY_ROUTING_PLAN_ID: "e57fe5cc-0567-4854-abe2-b7dd9014a50c" NOTIFY_API_BASE_URL: "https://int.api.service.nhs.uk" MTLS_KEY: psu-mtls-1 diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index ede6a1bfa1..60dbe9dd21 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -118,6 +118,7 @@ jobs: ENABLE_POST_DATED_NOTIFICATIONS: true ENABLED_SYSTEMS: "Internal Test System" BLOCKED_SITE_ODS_CODES: "XXXXX" # Workaround empty string handling + ENABLED_SUPPLIER_APPLICATION_IDS: "XXXXX" NOTIFY_ROUTING_PLAN_ID: "e57fe5cc-0567-4854-abe2-b7dd9014a50c" NOTIFY_API_BASE_URL: "https://int.api.service.nhs.uk" MTLS_KEY: psu-mtls-1 @@ -159,6 +160,7 @@ jobs: ENABLE_NOTIFICATIONS_EXTERNAL: false ENABLED_SYSTEMS: "Internal Test System" BLOCKED_SITE_ODS_CODES: "B3J1Z" + ENABLED_SUPPLIER_APPLICATION_IDS: "XXXXX" # Workaround empty string handling NOTIFY_ROUTING_PLAN_ID: "e57fe5cc-0567-4854-abe2-b7dd9014a50c" NOTIFY_API_BASE_URL: "https://int.api.service.nhs.uk" MTLS_KEY: psu-mtls-1 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7ec0a4fdf2..7cc5dd132e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -44,7 +44,6 @@ jobs: jira_release_prefix: "psu" secrets: EXECUTE_JIRA_LAMBDA_ROLE: ${{ secrets.DEV_CLOUD_FORMATION_EXECUTE_LAMBDA_ROLE }} - package_code: needs: [tag_release, get_config_values] @@ -83,6 +82,7 @@ jobs: ENABLE_POST_DATED_NOTIFICATIONS: true ENABLED_SYSTEMS: "Internal Test System" BLOCKED_SITE_ODS_CODES: "XXXXX" # Workaround empty string handling + ENABLED_SUPPLIER_APPLICATION_IDS: "XXXXX" NOTIFY_ROUTING_PLAN_ID: "e57fe5cc-0567-4854-abe2-b7dd9014a50c" NOTIFY_API_BASE_URL: "https://int.api.service.nhs.uk" MTLS_KEY: psu-mtls-1 @@ -129,6 +129,7 @@ jobs: ENABLE_POST_DATED_NOTIFICATIONS: false ENABLED_SYSTEMS: "Internal Test System" BLOCKED_SITE_ODS_CODES: "B3J1Z" + ENABLED_SUPPLIER_APPLICATION_IDS: "XXXXX" NOTIFY_ROUTING_PLAN_ID: "e57fe5cc-0567-4854-abe2-b7dd9014a50c" NOTIFY_API_BASE_URL: "https://int.api.service.nhs.uk" MTLS_KEY: psu-mtls-1 @@ -181,6 +182,7 @@ jobs: ENABLE_POST_DATED_NOTIFICATIONS: false ENABLED_SYSTEMS: "Internal Test System, Apotec Ltd - Apotec CRM - Production, CrxPatientApp, nhsPrescriptionApp, Titan PSU Prod" BLOCKED_SITE_ODS_CODES: "B3J1Z" + ENABLED_SUPPLIER_APPLICATION_IDS: "XXXXX" NOTIFY_ROUTING_PLAN_ID: "e57fe5cc-0567-4854-abe2-b7dd9014a50c" NOTIFY_API_BASE_URL: "https://int.api.service.nhs.uk" MTLS_KEY: psu-mtls-1 @@ -233,6 +235,7 @@ jobs: ENABLE_POST_DATED_NOTIFICATIONS: true ENABLED_SYSTEMS: "Internal Test System, Apotec Ltd - Apotec CRM - Production, CrxPatientApp, nhsPrescriptionApp, Titan PSU Prod" BLOCKED_SITE_ODS_CODES: "B3J1Z" + ENABLED_SUPPLIER_APPLICATION_IDS: "XXXXX" NOTIFY_ROUTING_PLAN_ID: "e57fe5cc-0567-4854-abe2-b7dd9014a50c" NOTIFY_API_BASE_URL: "https://int.api.service.nhs.uk" MTLS_KEY: psu-mtls-1 @@ -248,7 +251,8 @@ jobs: REGRESSION_TESTS_PEM: ${{ secrets.REGRESSION_TESTS_PEM }} release_int: - needs: [tag_release, release_qa, package_code, get_commit_id, get_config_values] + needs: + [tag_release, release_qa, package_code, get_commit_id, get_config_values] uses: ./.github/workflows/run_release_code_and_api.yml with: pinned_image: ${{ needs.get_config_values.outputs.pinned_image }} @@ -277,6 +281,7 @@ jobs: ENABLE_POST_DATED_NOTIFICATIONS: true ENABLED_SYSTEMS: "CrxPatientApp" BLOCKED_SITE_ODS_CODES: "XXXXX" # Workaround empty string handling + ENABLED_SUPPLIER_APPLICATION_IDS: "XXXXX" NOTIFY_ROUTING_PLAN_ID: "e57fe5cc-0567-4854-abe2-b7dd9014a50c" NOTIFY_API_BASE_URL: "https://int.api.service.nhs.uk" MTLS_KEY: psu-mtls-1 @@ -296,7 +301,8 @@ jobs: REGRESSION_TESTS_PEM: ${{ secrets.REGRESSION_TESTS_PEM }} release_int_sandbox: - needs: [tag_release, release_qa, package_code, get_commit_id, get_config_values] + needs: + [tag_release, release_qa, package_code, get_commit_id, get_config_values] uses: ./.github/workflows/run_release_code_and_api.yml with: pinned_image: ${{ needs.get_config_values.outputs.pinned_image }} @@ -323,6 +329,7 @@ jobs: ENABLE_POST_DATED_NOTIFICATIONS: false ENABLED_SYSTEMS: "Internal Test System, Apotec Ltd - Apotec CRM - Production, CrxPatientApp, nhsPrescriptionApp, Titan PSU Prod" BLOCKED_SITE_ODS_CODES: "B3J1Z" + ENABLED_SUPPLIER_APPLICATION_IDS: "XXXXX" NOTIFY_ROUTING_PLAN_ID: "e57fe5cc-0567-4854-abe2-b7dd9014a50c" NOTIFY_API_BASE_URL: "https://int.api.service.nhs.uk" MTLS_KEY: psu-mtls-1 @@ -375,6 +382,7 @@ jobs: ENABLE_POST_DATED_NOTIFICATIONS: false ENABLED_SYSTEMS: "CrxPatientApp" BLOCKED_SITE_ODS_CODES: "XXXXX" # Workaround empty string handling + ENABLED_SUPPLIER_APPLICATION_IDS: "XXXXX" NOTIFY_ROUTING_PLAN_ID: "e57fe5cc-0567-4854-abe2-b7dd9014a50c" # INT and PROD share a value NOTIFY_API_BASE_URL: "https://api.service.nhs.uk" MTLS_KEY: psu-mtls-1 diff --git a/.github/workflows/run_release_code_and_api.yml b/.github/workflows/run_release_code_and_api.yml index d65ef1c1ae..f797424ef4 100644 --- a/.github/workflows/run_release_code_and_api.yml +++ b/.github/workflows/run_release_code_and_api.yml @@ -85,6 +85,9 @@ on: BLOCKED_SITE_ODS_CODES: required: true type: string + ENABLED_SUPPLIER_APPLICATION_IDS: + required: true + type: string NOTIFY_ROUTING_PLAN_ID: required: true type: string @@ -216,6 +219,7 @@ jobs: ENABLED_SITE_ODS_CODES: ${{ steps.read.outputs.ods_csv }} ENABLED_SYSTEMS: ${{ inputs.ENABLED_SYSTEMS }} BLOCKED_SITE_ODS_CODES: ${{ inputs.BLOCKED_SITE_ODS_CODES }} + ENABLED_SUPPLIER_APPLICATION_IDS: ${{ inputs.ENABLED_SUPPLIER_APPLICATION_IDS }} NOTIFY_ROUTING_PLAN_ID: ${{ inputs.NOTIFY_ROUTING_PLAN_ID }} NOTIFY_API_BASE_URL: ${{ inputs.NOTIFY_API_BASE_URL }} TEST_PRESCRIPTIONS_1: ${{ inputs.TEST_PRESCRIPTIONS_1 || 'noval' }} diff --git a/Makefile b/Makefile index 4491a234ec..46f2cae220 100644 --- a/Makefile +++ b/Makefile @@ -48,6 +48,7 @@ sam-sync: guard-AWS_DEFAULT_PROFILE guard-stack_name compile "EnabledSystemsValue=$${ENABLED_SYSTEMS:-Internal Test System}" \ "EnabledSiteODSCodesValue=$${ENABLED_SITE_ODS_CODES:-A83008,FA565}" \ BlockedSiteODSCodesValue=$${BLOCKED_SITE_ODS_CODES:-XXXXX} \ + EnabledSupplierApplicationIDsValue=$${ENABLED_SUPPLIER_APPLICATION_IDS:-XXXXX} \ NotifyRoutingPlanIDValue=$${NOTIFY_ROUTING_PLAN_ID:-e57fe5cc-0567-4854-abe2-b7dd9014a50c} \ NotifyAPIBaseURLValue=$${NOTIFY_API_BASE_URL:-https://int.api.service.nhs.uk} \ EnableNotificationsInternal=$${ENABLE_NOTIFICATIONS_INTERNAL:-true} \ @@ -80,6 +81,7 @@ sam-deploy: guard-AWS_DEFAULT_PROFILE guard-stack_name "EnabledSystemsValue=$${ENABLED_SYSTEMS:-Internal Test System}" \ "EnabledSiteODSCodesValue=$${ENABLED_SITE_ODS_CODES:-A83008,FA565}" \ BlockedSiteODSCodesValue=$${BLOCKED_SITE_ODS_CODES:-XXXXX} \ + EnabledSupplierApplicationIDsValue=$${ENABLED_SUPPLIER_APPLICATION_IDS:-XXXXX} \ NotifyRoutingPlanIDValue=$${NOTIFY_ROUTING_PLAN_ID:-e57fe5cc-0567-4854-abe2-b7dd9014a50c} \ NotifyAPIBaseURLValue=$${NOTIFY_API_BASE_URL:-https://int.api.service.nhs.uk} \ EnableNotificationsInternal=$${ENABLE_NOTIFICATIONS_INTERNAL:-true} \ diff --git a/SAMtemplates/functions/main.yaml b/SAMtemplates/functions/main.yaml index c7ce7d2534..b151d757c3 100644 --- a/SAMtemplates/functions/main.yaml +++ b/SAMtemplates/functions/main.yaml @@ -46,6 +46,9 @@ Parameters: EnabledSystemsParam: Type: AWS::SSM::Parameter::Name + EnabledSupplierApplicationIDsParam: + Type: AWS::SSM::Parameter::Name + BlockedSiteODSCodesParam: Type: AWS::SSM::Parameter::Name @@ -132,8 +135,13 @@ Resources: POST_DATED_PRESCRIPTIONS_SQS_QUEUE_URL: !Ref PostDatedNotificationsSQSQueueUrl ENABLE_POST_DATED_NOTIFICATIONS: !Ref EnablePostDatedNotifications SQS_SALT: !Ref SQSSaltSecret - ENABLED_SITE_ODS_CODES_PARAM: !Ref EnabledSiteODSCodesParam + # Remove this once we've confirmed that product ID based filtering is working as expected and we + # no longer need the ability to switch back to the old filtering method + USE_APP_ID_FOR_NOTIFICATIONS_FILTERING: false ENABLED_SYSTEMS_PARAM: !Ref EnabledSystemsParam + # + ENABLED_APPLICATION_IDS_PARAM: !Ref EnabledSupplierApplicationIDsParam + ENABLED_SITE_ODS_CODES_PARAM: !Ref EnabledSiteODSCodesParam BLOCKED_SITE_ODS_CODES_PARAM: !Ref BlockedSiteODSCodesParam ENABLE_NOTIFICATIONS_PARAM: !Ref EnableNotificationsInternalParam LOG_LEVEL: !Ref LogLevel diff --git a/SAMtemplates/main_template.yaml b/SAMtemplates/main_template.yaml index e0a0307a7b..e1448ddc00 100644 --- a/SAMtemplates/main_template.yaml +++ b/SAMtemplates/main_template.yaml @@ -129,6 +129,10 @@ Parameters: Type: String Default: " " + EnabledSupplierApplicationIDsValue: + Type: String + Default: " " + BlockedSiteODSCodesValue: Type: String Default: " " @@ -188,6 +192,7 @@ Resources: EnableNotificationsExternalValue: !Ref EnableNotificationsExternal EnabledSiteODSCodesValue: !Ref EnabledSiteODSCodesValue EnabledSystemsValue: !Ref EnabledSystemsValue + EnabledSupplierApplicationIDsValue: !Ref EnabledSupplierApplicationIDsValue BlockedSiteODSCodesValue: !Ref BlockedSiteODSCodesValue NotifyRoutingPlanIDValue: !Ref NotifyRoutingPlanIDValue NotifyAPIBaseURLValue: !Ref NotifyAPIBaseURLValue @@ -254,6 +259,7 @@ Resources: SQSSaltSecret: !GetAtt Secrets.Outputs.SQSSaltSecret EnabledSiteODSCodesParam: !GetAtt Parameters.Outputs.EnabledSiteODSCodesParameterName EnabledSystemsParam: !GetAtt Parameters.Outputs.EnabledSystemsParameterName + EnabledSupplierApplicationIDsParam: !GetAtt Parameters.Outputs.EnabledSupplierApplicationIDsParameterName BlockedSiteODSCodesParam: !GetAtt Parameters.Outputs.BlockedSiteODSCodesParameterName NotifyRoutingPlanIDParam: !GetAtt Parameters.Outputs.NotifyRoutingPlanIDParameterName NotifyAPIBaseURLParam: !GetAtt Parameters.Outputs.NotifyAPIBaseURLParameterName diff --git a/SAMtemplates/parameters/main.yaml b/SAMtemplates/parameters/main.yaml index 6ed0892fc3..bb4f7ce793 100644 --- a/SAMtemplates/parameters/main.yaml +++ b/SAMtemplates/parameters/main.yaml @@ -28,6 +28,10 @@ Parameters: Type: String Default: " " + EnabledSupplierApplicationIDsValue: + Type: String + Default: " " + BlockedSiteODSCodesValue: Type: String Default: " " @@ -39,7 +43,7 @@ Parameters: NotifyAPIBaseURLValue: Type: String Default: " " - + TestPresciptionsParamValue1: Type: String @@ -69,6 +73,14 @@ Resources: Type: String Value: !Ref EnabledSystemsValue + EnabledSupplierApplicationIDsParameter: + Type: AWS::SSM::Parameter + Properties: + Name: !Sub ${StackName}-PSUNotifyEnabledSupplierApplicationIDs + Description: "List of supplier application IDs for which notifications are enabled" + Type: String + Value: !Ref EnabledSupplierApplicationIDsValue + BlockedSiteODSCodesParameter: Type: AWS::SSM::Parameter Properties: @@ -155,6 +167,7 @@ Resources: Resource: - !Sub arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${StackName}-PSUNotifyEnabledSiteODSCodes - !Sub arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${StackName}-PSUNotifyEnabledSystems + - !Sub arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${StackName}-PSUNotifyEnabledSupplierApplicationIDs - !Sub arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${StackName}-PSUNotifyBlockedSiteODSCodes - !Sub arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${StackName}-PSUNotifyRoutingPlanID - !Sub arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${StackName}-PSUNotifyApiBaseUrl @@ -179,6 +192,12 @@ Outputs: Export: Name: !Sub ${StackName}-PSUNotifyEnabledSystemsParam + EnabledSupplierApplicationIDsParameterName: + Description: "Name of the SSM parameter holding enabled supplier apigee application IDs" + Value: !Ref EnabledSupplierApplicationIDsParameter + Export: + Name: !Sub ${StackName}-PSUNotifyEnabledSupplierApplicationIDsParam + BlockedSiteODSCodesParameterName: Description: "Name of the SSM parameter holding blocked site ODS codes" Value: !Ref BlockedSiteODSCodesParameter diff --git a/packages/common/commonTypes/src/index.ts b/packages/common/commonTypes/src/index.ts index 808e28df60..243f8fa378 100644 --- a/packages/common/commonTypes/src/index.ts +++ b/packages/common/commonTypes/src/index.ts @@ -10,6 +10,7 @@ export interface PSUDataItem { TaskID: string TerminalStatus: string ApplicationName: string + ApplicationID: string ExpiryTime: number // (Optional, legacy batch-processors only) Indicates that {@link LastModified} is postdated; // contains the ISO 8601 timestamp when the postdated update was set. diff --git a/packages/nhsNotifyLambda/tests/testHelpers.ts b/packages/nhsNotifyLambda/tests/testHelpers.ts index ce64f090d7..437f5490f2 100644 --- a/packages/nhsNotifyLambda/tests/testHelpers.ts +++ b/packages/nhsNotifyLambda/tests/testHelpers.ts @@ -53,6 +53,7 @@ export function constructPSUDataItem(overrides: Partial = {}): PSUD TaskID: "mnopqr-ghijkl-abcdef", TerminalStatus: "ready to collect", ApplicationName: "Jim's Pills", + ApplicationID: "550e8400-e29b-41d4-a716-446655440000", ExpiryTime: 123, ...overrides } diff --git a/packages/postDatedLambda/tests/testBusinessLogic.test.ts b/packages/postDatedLambda/tests/testBusinessLogic.test.ts index 095a1593ef..663d2485f1 100644 --- a/packages/postDatedLambda/tests/testBusinessLogic.test.ts +++ b/packages/postDatedLambda/tests/testBusinessLogic.test.ts @@ -39,6 +39,7 @@ function createPSURecord(overrides: Partial = {}): PSUDataItem { TaskID: "task-123", TerminalStatus: "terminal", ApplicationName: "post-dated-tests", + ApplicationID: "550e8400-e29b-41d4-a716-446655440000", ExpiryTime: 0, PostDatedLastModifiedSetAt: "2026-01-01T00:00:00.000Z" } diff --git a/packages/specification/eps-prescription-status-update-api.yaml b/packages/specification/eps-prescription-status-update-api.yaml index b105cd33b9..5a09813428 100755 --- a/packages/specification/eps-prescription-status-update-api.yaml +++ b/packages/specification/eps-prescription-status-update-api.yaml @@ -459,6 +459,9 @@ x-nhsd-apim: - name: show-all-suppliers required: false header: show-all-suppliers + - name: id + required: false + header: nhsd-application-id ratelimiting: proxy: limit: 20000 diff --git a/packages/updatePrescriptionStatus/src/updatePrescriptionStatus.ts b/packages/updatePrescriptionStatus/src/updatePrescriptionStatus.ts index 1e9b8cb63b..fcaf86755a 100644 --- a/packages/updatePrescriptionStatus/src/updatePrescriptionStatus.ts +++ b/packages/updatePrescriptionStatus/src/updatePrescriptionStatus.ts @@ -106,6 +106,7 @@ const lambdaHandler = async (event: APIGatewayProxyEvent): Promise, xRequestID: string, - applicationName: string + applicationName: string, + applicationId: string ): Array { const dataItems: Array = [] @@ -381,6 +383,7 @@ export function buildDataItems( TaskID: task.id!, TerminalStatus: task.status, ApplicationName: applicationName, + ApplicationID: applicationId, ExpiryTime: (Math.floor(Date.now() / 1000) + TTL_DELTA) } diff --git a/packages/updatePrescriptionStatus/src/utils/sqsClient.ts b/packages/updatePrescriptionStatus/src/utils/sqsClient.ts index aff5bcfbbe..fd73b6aaa8 100644 --- a/packages/updatePrescriptionStatus/src/utils/sqsClient.ts +++ b/packages/updatePrescriptionStatus/src/utils/sqsClient.ts @@ -212,7 +212,7 @@ export async function pushPrescriptionToNotificationSQS( } // Only allow through sites and systems that are allowedSitesAndSystems - const allowedSitesAndSystemsData = await checkSiteOrSystemIsNotifyEnabled(data) + const allowedSitesAndSystemsData = await checkSiteOrSystemIsNotifyEnabled(data, logger) // Only these statuses will be pushed to the SQS const updateStatuses: Set = new Set([ diff --git a/packages/updatePrescriptionStatus/src/validation/notificationSiteAndSystemFilters.ts b/packages/updatePrescriptionStatus/src/validation/notificationSiteAndSystemFilters.ts index ae4c607e97..a1bb33f60b 100644 --- a/packages/updatePrescriptionStatus/src/validation/notificationSiteAndSystemFilters.ts +++ b/packages/updatePrescriptionStatus/src/validation/notificationSiteAndSystemFilters.ts @@ -2,6 +2,10 @@ import {PSUDataItemWithPrevious} from "@psu-common/commonTypes" import {initiatedSSMProvider} from "@psu-common/utilities" import {Logger} from "@aws-lambda-powertools/logger" +const USE_APP_ID_FOR_NOTIFICATIONS_FILTERING = + (process.env.USE_APP_ID_FOR_NOTIFICATIONS_FILTERING || "false") + .toLowerCase() === "true" + function str2set(value: string | undefined): Set { const raw = value ?? "" return new Set(raw @@ -13,23 +17,27 @@ function str2set(value: string | undefined): Set { async function loadConfig(): Promise<{ enabledSiteODSCodes: Set, - enabledSystems: Set, + enabledSystemAppNames: Set, + enabledSystemAppIds: Set, blockedSiteODSCodes: Set }> { const paramNames = { [process.env.ENABLED_SITE_ODS_CODES_PARAM!]: {maxAge: 5}, [process.env.ENABLED_SYSTEMS_PARAM!]: {maxAge: 5}, + [process.env.ENABLED_APPLICATION_IDS_PARAM!]: {maxAge: 5}, [process.env.BLOCKED_SITE_ODS_CODES_PARAM!]: {maxAge: 5} } const all = await initiatedSSMProvider.getParametersByName(paramNames) const enabledSiteODSCodes = str2set(all[process.env.ENABLED_SITE_ODS_CODES_PARAM!] as string) - const enabledSystems = str2set(all[process.env.ENABLED_SYSTEMS_PARAM!] as string) + const enabledSystemAppNames = str2set(all[process.env.ENABLED_SYSTEMS_PARAM!] as string) + const enabledSystemAppIds = str2set(all[process.env.ENABLED_APPLICATION_IDS_PARAM!] as string) const blockedSiteODSCodes = str2set(all[process.env.BLOCKED_SITE_ODS_CODES_PARAM!] as string) return { enabledSiteODSCodes, - enabledSystems, + enabledSystemAppNames, + enabledSystemAppIds, blockedSiteODSCodes } } @@ -48,21 +56,46 @@ export async function checkSiteOrSystemIsNotifyEnabled( logger?: Logger ): Promise> { // Get the configuration from either the cache or SSM - const {enabledSiteODSCodes, enabledSystems, blockedSiteODSCodes} = await loadConfig() + const {enabledSiteODSCodes, enabledSystemAppNames, enabledSystemAppIds, blockedSiteODSCodes} = await loadConfig() const unfilteredItemCount = data.length + logger?.info("Filtering items based on enabled sites and systems configuration", + { + enabledSystemAppIds: Array.from(enabledSystemAppIds), + enabledSystemAppNames: Array.from(enabledSystemAppNames), + enabledODSCodes: Array.from(enabledSiteODSCodes), + blockedODSCodes: Array.from(blockedSiteODSCodes) + } + ) + const filteredItems = data.filter((item) => { + const appId = item.current.ApplicationID.trim().toLowerCase() const appName = item.current.ApplicationName.trim().toLowerCase() const odsCode = item.current.PharmacyODSCode.trim().toLowerCase() - // Is this item either ODS enabled, or supplier enabled? - const isEnabledSystem = enabledSiteODSCodes.has(odsCode) || enabledSystems.has(appName) - if (!isEnabledSystem) { - return false + logger?.info( + "Product ID, application name, and ODS code", + {appId, appName, odsCode} + ) + + // Is this item supplier enabled? + if (USE_APP_ID_FOR_NOTIFICATIONS_FILTERING) { + logger?.info("Using application ID for notifications filtering") + const isEnabledApplication = enabledSiteODSCodes.has(odsCode) || enabledSystemAppIds.has(appId) + if (!isEnabledApplication) { + return false + } + } else { + logger?.info("Using application name for notifications filtering") + const isEnabledSystem = enabledSiteODSCodes.has(odsCode) || enabledSystemAppNames.has(appName) + if (!isEnabledSystem) { + return false + } } // Cannot have a blocked ODS code if (blockedSiteODSCodes.has(odsCode)) { + logger?.info("Site ODS code is explicitly blocked", {odsCode}) return false } diff --git a/packages/updatePrescriptionStatus/tests/testDatabaseClient.test.ts b/packages/updatePrescriptionStatus/tests/testDatabaseClient.test.ts index c321cb09d0..4290bff2a5 100644 --- a/packages/updatePrescriptionStatus/tests/testDatabaseClient.test.ts +++ b/packages/updatePrescriptionStatus/tests/testDatabaseClient.test.ts @@ -35,6 +35,7 @@ describe("Unit test persistDataItems", () => { TaskID: "TaskID_1", TerminalStatus: "TerminalStatus_1", ApplicationName: "name", + ApplicationID: "550e8400-e29b-41d4-a716-446655440000", ExpiryTime: 10 }, { @@ -48,6 +49,7 @@ describe("Unit test persistDataItems", () => { TaskID: "TaskID_1", TerminalStatus: "TerminalStatus_2", ApplicationName: "name", + ApplicationID: "550e8400-e29b-41d4-a716-446655440000", ExpiryTime: 10 } ] @@ -87,6 +89,7 @@ describe("Unit test persistDataItems", () => { TaskID: "TaskID_1", TerminalStatus: "TerminalStatus_1", ApplicationName: "name", + ApplicationID: "550e8400-e29b-41d4-a716-446655440000", ExpiryTime: 10 }, { @@ -100,6 +103,7 @@ describe("Unit test persistDataItems", () => { TaskID: "TaskID_1", TerminalStatus: "TerminalStatus_2", ApplicationName: "name", + ApplicationID: "550e8400-e29b-41d4-a716-446655440000", ExpiryTime: 10 } ] @@ -123,6 +127,7 @@ describe("Unit test persistDataItems", () => { TaskID: "TaskID_1", TerminalStatus: "TerminalStatus_1", ApplicationName: "name", + ApplicationID: "550e8400-e29b-41d4-a716-446655440000", ExpiryTime: 10 } const dataItems = Array(150).fill(dataItem) @@ -148,6 +153,7 @@ describe("Unit test persistDataItems", () => { TaskID: "TaskID_1", TerminalStatus: "TerminalStatus_1", ApplicationName: "name", + ApplicationID: "550e8400-e29b-41d4-a716-446655440000", ExpiryTime: 10 }, { @@ -161,6 +167,7 @@ describe("Unit test persistDataItems", () => { TaskID: "TaskID_1", TerminalStatus: "TerminalStatus_2", ApplicationName: "name", + ApplicationID: "550e8400-e29b-41d4-a716-446655440000", ExpiryTime: 10 } ] @@ -194,6 +201,7 @@ describe("Unit test getPreviousItem", () => { TaskID: "previous-task-id", TerminalStatus: "ready to collect", ApplicationName: "Jim's Pills", + ApplicationID: "550e8400-e29b-41d4-a716-446655440000", ExpiryTime: 123 } const previousItem = { @@ -207,6 +215,7 @@ describe("Unit test getPreviousItem", () => { TaskID: "previous-task-id", TerminalStatus: "ready to collect", ApplicationName: "Jim's Pills", + ApplicationID: "550e8400-e29b-41d4-a716-446655440000", ExpiryTime: 123 } const currentItem = { @@ -220,6 +229,7 @@ describe("Unit test getPreviousItem", () => { TaskID: "current-task-id", TerminalStatus: "ready to collect", ApplicationName: "Jim's Pills", + ApplicationID: "550e8400-e29b-41d4-a716-446655440000", ExpiryTime: 123 } @@ -334,6 +344,7 @@ describe("Unit test rollbackDataItems", () => { TaskID: "TaskID_1", TerminalStatus: "TerminalStatus_1", ApplicationName: "name", + ApplicationID: "550e8400-e29b-41d4-a716-446655440000", ExpiryTime: 10, ...overrides }) diff --git a/packages/updatePrescriptionStatus/tests/testSqsClient.test.ts b/packages/updatePrescriptionStatus/tests/testSqsClient.test.ts index f720533a4e..4fb13586e0 100644 --- a/packages/updatePrescriptionStatus/tests/testSqsClient.test.ts +++ b/packages/updatePrescriptionStatus/tests/testSqsClient.test.ts @@ -487,7 +487,8 @@ describe("Unit tests for checkSiteOrSystemIsNotifyEnabled", () => { }) const item2 = createMockDataItem({ PharmacyODSCode: "zzz999", - ApplicationName: "internal test SYSTEM" + ApplicationName: "internal test SYSTEM", + ApplicationID: "550e8400-e29b-41d4-a716-446655440000" }) const result = await checkSiteOrSystemIsNotifyEnabled([ { @@ -530,11 +531,13 @@ describe("Unit tests for checkSiteOrSystemIsNotifyEnabled", () => { const previous = createMockDataItem({ PharmacyODSCode: "NOTINLIST", ApplicationName: "Some Other System", + ApplicationID: "550e8400-e29b-41d4-a716-446655441234", Status: "previous" }) const current = createMockDataItem({ PharmacyODSCode: "NOTINLIST", - ApplicationName: "Some Other System" + ApplicationName: "Some Other System", + ApplicationID: "550e8400-e29b-41d4-a716-446655441234" }) const result = await checkSiteOrSystemIsNotifyEnabled([{previous, current}], logger) expect(result).toEqual([]) diff --git a/packages/updatePrescriptionStatus/tests/testUpdatePrescriptionStatus.test.ts b/packages/updatePrescriptionStatus/tests/testUpdatePrescriptionStatus.test.ts index a03d391b60..1130e94821 100644 --- a/packages/updatePrescriptionStatus/tests/testUpdatePrescriptionStatus.test.ts +++ b/packages/updatePrescriptionStatus/tests/testUpdatePrescriptionStatus.test.ts @@ -239,7 +239,7 @@ describe("buildDataItems", () => { fullUrl: "" } - const dataItems = buildDataItems([requestEntry], "", "") + const dataItems = buildDataItems([requestEntry], "", "", "") expect(dataItems[0].LineItemID).toEqual(lineItemID) expect(dataItems[0].PrescriptionID).toEqual(prescriptionID) @@ -269,7 +269,7 @@ describe("buildDataItems", () => { fullUrl: "" } - const dataItems = buildDataItems([requestEntry], "", "") + const dataItems = buildDataItems([requestEntry], "", "", "") expect(dataItems[0].RepeatNo).toEqual(repeatNo) }) @@ -283,7 +283,7 @@ describe("buildDataItems", () => { fullUrl: "" } - const dataItems = buildDataItems([requestEntry], "", "") + const dataItems = buildDataItems([requestEntry], "", "", "") expect(dataItems[0].ExpiryTime).toBeGreaterThan(expectedExpiryTime) }) @@ -300,7 +300,7 @@ describe("buildDataItems", () => { fullUrl: "" } - const dataItems = buildDataItems([requestEntry], "", "") + const dataItems = buildDataItems([requestEntry], "", "", "") const first: any = dataItems[0] expect(first.PostDatedLastModifiedSetAt).toEqual(lastUpdated) }) diff --git a/packages/updatePrescriptionStatus/tests/utils/testUtils.ts b/packages/updatePrescriptionStatus/tests/utils/testUtils.ts index ef7137cb6c..5591ff8e60 100644 --- a/packages/updatePrescriptionStatus/tests/utils/testUtils.ts +++ b/packages/updatePrescriptionStatus/tests/utils/testUtils.ts @@ -209,6 +209,7 @@ export function createMockDataItem(overrides: Partial): PSUDataItem TaskID: "mnopqr-ghijkl-abcdef", TerminalStatus: "ready to collect", ApplicationName: "Internal Test System", + ApplicationID: "550e8400-e29b-41d4-a716-446655440000", ExpiryTime: 123, ...overrides }