Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
124 commits
Select commit Hold shift + click to select a range
76085aa
Add a notifications table definition. PK prescription ID, GSI NHS number
wildjames Apr 15, 2025
2a6a99c
Make capitalisation consistent
wildjames Apr 15, 2025
b26a0e9
Create a blank notifications lambda. Doesn't have a deployment defini…
wildjames Apr 15, 2025
36fda3d
Add nhs notify lambda to main lambda SAM template
wildjames Apr 15, 2025
5787256
Add scheduler, and update lambda handler
wildjames Apr 15, 2025
0e44d81
Merge branch 'main' into aea-5199-setup-notifications-lambda
wildjames Apr 15, 2025
a4e2c9a
Trigger PR title check again
wildjames Apr 15, 2025
6e645fa
Add mock event bridge type. Update dummy unit test
wildjames Apr 15, 2025
186ffef
Merge branch 'main' into aea-5199-setup-notifications-lambda
wildjames Apr 15, 2025
f9f3391
Refactor to not need permissions, mirroring cert checker lambda
wildjames Apr 15, 2025
61c72dc
Merge branch 'aea-5199-setup-notifications-lambda' of github.com:NHSD…
wildjames Apr 15, 2025
586aa34
typo in the version
wildjames Apr 16, 2025
ef9750d
Fix indentation
wildjames Apr 16, 2025
6c4bf0a
whitespace changes
wildjames Apr 16, 2025
2112fc2
using the wrong handler function
wildjames Apr 16, 2025
771de6d
Add SQS queue definition
wildjames Apr 16, 2025
6d5cfbe
Add messaging stack to main yaml
wildjames Apr 16, 2025
fba51c8
Fix import
wildjames Apr 16, 2025
1bffcb3
Retention period too long :(
wildjames Apr 16, 2025
be5e9d9
Empty function in PSU that will push data to SQS
wildjames Apr 16, 2025
f1a154d
Tests seembroken, but wrote an sqs client
wildjames Apr 16, 2025
b994b2b
fix test
wildjames Apr 17, 2025
d526e61
Add send message policy to the update prescription lambda
wildjames Apr 17, 2025
efbc621
Reset env between tests
wildjames Apr 17, 2025
ddbe840
Is it case sensitive?
wildjames Apr 17, 2025
328e1e0
Move permission definition
wildjames Apr 17, 2025
1cec26a
Merge branch 'main' into aea-5199-setup-notifications-lambda
wildjames Apr 17, 2025
f6c7829
add SQS policy to the nofity lambda
wildjames Apr 17, 2025
d4ac39a
Fix typo!
wildjames Apr 17, 2025
4b79e32
Forgot to specify arn export. Also, use stackname parameter
wildjames Apr 17, 2025
aa3ca5a
Nope, dont need the .Arn
wildjames Apr 17, 2025
544238a
Permissions for dealing with our customer-managed KMS
wildjames Apr 22, 2025
ff7be05
Add logic to catch failures of SQS
wildjames Apr 22, 2025
83de1b2
Log the message IDs that are getting pushed when debug is enabled
wildjames Apr 22, 2025
d0bd55b
Add missing permissions
wildjames Apr 22, 2025
367ee4d
Trigger build
wildjames Apr 22, 2025
e129789
Merge branch 'main' into aea-5199-setup-notifications-lambda
wildjames Apr 22, 2025
9261f45
Use a dedicated KMS - permissions are being difficult
wildjames Apr 22, 2025
6dc7c61
Forgot to add a policy
wildjames Apr 22, 2025
7a8b4e5
Merge branch 'main' into aea-5199-setup-notifications-lambda
wildjames Apr 22, 2025
7bfc023
Skip quality checks
wildjames Apr 22, 2025
b56af03
Merge branch 'aea-5199-setup-notifications-lambda' of github.com:NHSD…
wildjames Apr 22, 2025
d6d58cc
Make the notify lambda pull messages from SQS, and log them
wildjames Apr 22, 2025
8216f25
Update log message
wildjames Apr 22, 2025
6a2d224
Set up the consumer to be able to communicate with the table. Alos lo…
wildjames Apr 22, 2025
77821bc
Pass in static table name as a parameter
wildjames Apr 22, 2025
7c91533
Merge branch 'main' into aea-5199-setup-notifications-lambda
wildjames Apr 22, 2025
e39958a
Expand test coverage
wildjames Apr 22, 2025
61a897e
Merge branch 'aea-5199-setup-notifications-lambda' of github.com:NHSD…
wildjames Apr 22, 2025
adb055f
Minimal nhsnotifylambda dynamo unit test
wildjames Apr 23, 2025
804c06b
Expand test coverage
wildjames Apr 23, 2025
eb78c25
Start tests for the drainQueue functiton
wildjames Apr 23, 2025
35d8a92
Expand test coverage
wildjames Apr 23, 2025
9a55102
Merge branch 'main' into aea-5199-setup-notifications-lambda
wildjames Apr 23, 2025
ea0c3fe
Make a more official test for the handler
wildjames Apr 23, 2025
5da248d
Expand test coverage
wildjames Apr 23, 2025
90ccd53
Update type
wildjames Apr 23, 2025
338a135
Address some sonar things
wildjames Apr 23, 2025
17d6566
Move dataitem to a common types package
wildjames Apr 23, 2025
f27d70f
Minor tweaks from self-review
wildjames Apr 23, 2025
9cfb289
Use NHS number as the message ID
wildjames Apr 24, 2025
f0d35c5
Salt the nhs number and use it as the message ID.
wildjames Apr 24, 2025
6a77bde
Update log message
wildjames Apr 24, 2025
53abd70
Update tests to reflect logging change
wildjames Apr 24, 2025
440ac9e
Merge branch 'main' into aea-5274-deduplicate-notification-queue-by-n…
wildjames Apr 24, 2025
15ba4d2
Correctly grab request ID
wildjames Apr 24, 2025
501a5fd
Merge branch 'main' into aea-5199-setup-notifications-lambda
wildjames Apr 24, 2025
ba2d587
Merge branch 'aea-5199-setup-notifications-lambda' into aea-5274-dedu…
wildjames Apr 24, 2025
dd81780
Update log
wildjames Apr 24, 2025
0043ed4
Merge branch 'aea-5199-setup-notifications-lambda' into aea-5274-dedu…
wildjames Apr 24, 2025
00178b2
Remove log messages
wildjames Apr 24, 2025
67fb985
Use a FIFO queue, since it has deduplication IDs
wildjames Apr 24, 2025
989bb82
Minor adjustment to the failure catch logic to handle some elements o…
wildjames Apr 24, 2025
7fd8396
lengthen visibility timeout
wildjames Apr 24, 2025
1cf948a
Merge branch 'aea-5199-setup-notifications-lambda' into aea-5274-dedu…
wildjames Apr 24, 2025
178fc01
Update to deduplicate on both nhs number and ods code
wildjames Apr 25, 2025
9d9da72
Update test
wildjames Apr 25, 2025
21cf5f0
Resolve package lock conflict
wildjames Apr 28, 2025
5912e98
Merge branch 'aea-5199-setup-notifications-lambda' into aea-5274-dedu…
wildjames Apr 28, 2025
886c198
Rename fuinction. Comments
wildjames Apr 28, 2025
6b9dcbc
Resolve package lock conflict
wildjames Apr 28, 2025
d710874
Merge branch 'aea-5199-setup-notifications-lambda' into aea-5274-dedu…
wildjames Apr 28, 2025
f5a77bf
Create a whitelist checking function
wildjames Apr 28, 2025
c90555c
Update language usage
wildjames Apr 28, 2025
90e3e8e
Update language
wildjames Apr 28, 2025
21a1236
Update logging
wildjames Apr 28, 2025
de8033a
Update tests
wildjames Apr 28, 2025
839375f
Merge branch 'main' into aea-5274-deduplicate-notification-queue-by-n…
wildjames Apr 28, 2025
d950354
Move the deletion logic out to occur AFTER processing. Update tests t…
wildjames Apr 28, 2025
1c949b7
Update tests
wildjames Apr 28, 2025
0227196
Revert a line
wildjames Apr 28, 2025
7440946
Update mock import
wildjames Apr 28, 2025
73edbdc
Expand tests
wildjames Apr 28, 2025
2719d4f
Set the sqs salt value to some randomly generated string at deployment
wildjames Apr 29, 2025
8d10626
Merge branch 'main' into aea-5202-allowed-and-blocked-sites-and-systems
wildjames Apr 29, 2025
a22c919
Merge branch 'aea-5274-deduplicate-notification-queue-by-nhsnumber' i…
wildjames Apr 29, 2025
28adaa5
Define the enabled and disabled sites in a new Paramters template
wildjames Apr 29, 2025
bff40c5
Allow the block and enable lists to differ between prod and non-prod …
wildjames Apr 29, 2025
50e7fe5
Update tests
wildjames Apr 29, 2025
f08adba
Merge branch 'main' into aea-5202-allowed-and-blocked-sites-and-systems
wildjames Apr 29, 2025
888a1c8
Merge branch 'main' into aea-5202-allowed-and-blocked-sites-and-systems
wildjames Apr 29, 2025
b8b08a8
Fix typo
wildjames Apr 29, 2025
23c53d7
Merge branch 'aea-5202-allowed-and-blocked-sites-and-systems' of gith…
wildjames Apr 29, 2025
5939e0f
Refactor params a bit
wildjames Apr 29, 2025
e608771
Roll back a bit to find the source of the error
wildjames Apr 29, 2025
e3ef147
Comment out parameter
wildjames Apr 30, 2025
aa2a8d5
Make fallback salt a const
wildjames Apr 30, 2025
022e66f
Merge main into aea-5202-allowed-and-blocked-sites-and-systems
wildjames Apr 30, 2025
d015f13
last deployment worked. Try passing in parameters
wildjames Apr 30, 2025
b1574b1
Join array back into a single string
wildjames Apr 30, 2025
6bcd216
pass in the name and fetch the parameter values from ssm in the code
wildjames Apr 30, 2025
d9fcfce
Forgot to await
wildjames Apr 30, 2025
d0cea20
Revert change
wildjames Apr 30, 2025
17e46ea
Add logging message
wildjames Apr 30, 2025
ad32e9b
Remove await
wildjames Apr 30, 2025
055e4a0
Revert change to deploy workflow
wildjames Apr 30, 2025
d3d88f4
Merge branch 'main' into aea-5202-allowed-and-blocked-sites-and-systems
wildjames Apr 30, 2025
c0f0c50
Merge branch 'main' into aea-5202-allowed-and-blocked-sites-and-systems
wildjames Apr 30, 2025
358e203
Test fallback salt value
wildjames Apr 30, 2025
6663bac
Merge branch 'aea-5202-allowed-and-blocked-sites-and-systems' of gith…
wildjames Apr 30, 2025
3e5feb7
Minor tweak to tests
wildjames Apr 30, 2025
5c53015
Case insensitivity test!
wildjames Apr 30, 2025
e8c243e
Merge branch 'main' into aea-5202-allowed-and-blocked-sites-and-systems
wildjames May 2, 2025
6945694
Merge branch 'main' into aea-5202-allowed-and-blocked-sites-and-systems
wildjames May 2, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions SAMtemplates/functions/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@ Parameters:
Type: String
Default: none

EnabledSiteODSCodesParam:
Type: AWS::SSM::Parameter::Value<String>

EnabledSystemsParam:
Type: AWS::SSM::Parameter::Value<String>

BlockedSiteODSCodesParam:
Type: AWS::SSM::Parameter::Value<String>

LogLevel:
Type: String

Expand Down Expand Up @@ -83,6 +92,9 @@ Resources:
TABLE_NAME: !Ref PrescriptionStatusUpdatesTableName
NHS_NOTIFY_PRESCRIPTIONS_SQS_QUEUE_URL: !Ref NHSNotifyPrescriptionsSQSQueueUrl
SQS_SALT: !Sub "{{resolve:secretsmanager:${SQSSaltSecret}:SecretString:salt}}"
ENABLED_SITE_ODS_CODES: !Ref EnabledSiteODSCodesParam
ENABLED_SYSTEMS: !Ref EnabledSystemsParam
BLOCKED_SITE_ODS_CODES: !Ref BlockedSiteODSCodesParam
LOG_LEVEL: !Ref LogLevel
ENVIRONMENT: !Ref Environment
TEST_PRESCRIPTIONS_1: "None"
Expand Down
11 changes: 11 additions & 0 deletions SAMtemplates/main_template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,14 @@ Parameters:
Type: String

Resources:
Parameters:
Type: AWS::Serverless::Application
Properties:
Location: parameters/main.yaml
Parameters:
StackName: !Ref AWS::StackName
Environment: !Ref Environment

Tables:
Type: AWS::Serverless::Application
Properties:
Expand Down Expand Up @@ -136,6 +144,9 @@ Resources:
PrescriptionStatusUpdatesTableName: !GetAtt Tables.Outputs.PrescriptionStatusUpdatesTableName
PrescriptionNotificationStateTableName: !GetAtt Tables.Outputs.PrescriptionNotificationStateTableName
NHSNotifyPrescriptionsSQSQueueUrl: !GetAtt Messaging.Outputs.NHSNotifyPrescriptionsSQSQueueUrl
EnabledSiteODSCodesParam: !GetAtt Parameters.Outputs.EnabledSiteODSCodesParameterName
EnabledSystemsParam: !GetAtt Parameters.Outputs.EnabledSystemsParameterName
BlockedSiteODSCodesParam: !GetAtt Parameters.Outputs.BlockedSiteODSCodesParameterName
LogLevel: !Ref LogLevel
LogRetentionInDays: !Ref LogRetentionInDays
EnableSplunk: !Ref EnableSplunk
Expand Down
79 changes: 79 additions & 0 deletions SAMtemplates/parameters/main.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
AWSTemplateFormatVersion: '2010-09-09'
Description: >-
SSM Parameter Store entries. Values may differ between prod and non-prod environments

Parameters:
StackName:
Type: String

Environment:
Type: String

Conditions:
IsProd: !Equals [ !Ref Environment, prod ]

Resources:
EnabledSiteODSCodesParameter:
Type: AWS::SSM::Parameter
Properties:
Name: !Sub ${StackName}-PSUNotifyEnabledSiteODSCodes
Description: "List of site ODS codes for which notifications are enabled"
Type: String
Value: !If
- IsProd
- > # Prod notification enabled
FA565
- > # Non-prod
FA565

EnabledSystemsParameter:
Type: AWS::SSM::Parameter
Properties:
Name: !Sub ${StackName}-PSUNotifyEnabledSystems
Description: "List of application names for which notifications are enabled"
Type: String
Value: !If
- IsProd
- > # Prod notification enabled
Apotec Ltd - Apotec CRM - Production,
CrxPatientApp,
nhsPrescriptionApp,
Titan PSU Prod
- > # Non-prod
Internal Test System,
Apotec Ltd - Apotec CRM - Production,
CrxPatientApp,
nhsPrescriptionApp,
Titan PSU Prod

BlockedSiteODSCodesParameter:
Type: AWS::SSM::Parameter
Properties:
Name: !Sub ${StackName}-PSUNotifyBlockedSiteODSCodes
Description: "List of site ODS codes for which notifications are blocked"
Type: String
Value: !If
- IsProd
- > # Prod notification disabled
A83008
- > # Non-prod
A83008

Outputs:
EnabledSiteODSCodesParameterName:
Description: "Name of the SSM parameter holding enabled site ODS codes"
Value: !Ref EnabledSiteODSCodesParameter
Export:
Name: !Sub ${StackName}-PSUNotifyEnabledSiteODSCodesParam

EnabledSystemsParameterName:
Description: "Name of the SSM parameter holding enabled system names"
Value: !Ref EnabledSystemsParameter
Export:
Name: !Sub ${StackName}-PSUNotifyEnabledSystemsParam

BlockedSiteODSCodesParameterName:
Description: "Name of the SSM parameter holding blocked site ODS codes"
Value: !Ref BlockedSiteODSCodesParameter
Export:
Name: !Sub ${StackName}-PSUNotifyBlockedSiteODSCodesParam
26 changes: 13 additions & 13 deletions packages/common/commonTypes/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
export interface PSUDataItem {
LastModified: string
LineItemID: string
PatientNHSNumber: string
PharmacyODSCode: string
PrescriptionID: string
RepeatNo?: number
RequestID: string
Status: string
TaskID: string
TerminalStatus: string
ApplicationName: string
ExpiryTime: number
}
LastModified: string
LineItemID: string
PatientNHSNumber: string
PharmacyODSCode: string
PrescriptionID: string
RepeatNo?: number
RequestID: string
Status: string
TaskID: string
TerminalStatus: string
ApplicationName: string
ExpiryTime: number
}
3 changes: 3 additions & 0 deletions packages/updatePrescriptionStatus/.jest/setEnvVars.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@
process.env.NHS_NOTIFY_PRESCRIPTIONS_SQS_QUEUE_URL = "dummy_notify_sqs";
process.env.AWS_REGION = "eu-west-2";
process.env.SQS_SALT = "the quick brown fox something something"
process.env.ENABLED_SITE_ODS_CODES = "FA565"
process.env.ENABLED_SYSTEMS = "Internal Test System,Apotec Ltd - Apotec CRM - Production,CrxPatientApp,nhsPrescriptionApp,Titan PSU Prod"
process.env.BLOCKED_SITE_ODS_CODES = "A83008"
25 changes: 6 additions & 19 deletions packages/updatePrescriptionStatus/src/updatePrescriptionStatus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import httpHeaderNormalizer from "@middy/http-header-normalizer"
import errorHandler from "@nhs/fhir-middy-error-handler"
import {Bundle, BundleEntry, Task} from "fhir/r4"

import {PSUDataItem} from "@PrescriptionStatusUpdate_common/commonTypes"

import {transactionBundle, validateEntry} from "./validation/content"
import {getPreviousItem, persistDataItems} from "./utils/databaseClient"
import {jobWithTimeout, hasTimedOut} from "./utils/timeoutUtils"
Expand Down Expand Up @@ -42,21 +44,6 @@ export const TEST_PRESCRIPTIONS_1 = (process.env.TEST_PRESCRIPTIONS_1 ?? "")
export const TEST_PRESCRIPTIONS_2 = (process.env.TEST_PRESCRIPTIONS_2 ?? "")
.split(",").map(item => item.trim()) || []

export interface DataItem {
LastModified: string
LineItemID: string
PatientNHSNumber: string
PharmacyODSCode: string
PrescriptionID: string
RepeatNo?: number
RequestID: string
Status: string
TaskID: string
TerminalStatus: string
ApplicationName: string
ExpiryTime: number
}

const lambdaHandler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
logger.appendKeys({
"nhsd-correlation-id": event.headers["nhsd-correlation-id"],
Expand Down Expand Up @@ -260,16 +247,16 @@ export function buildDataItems(
requestEntries: Array<BundleEntry>,
xRequestID: string,
applicationName: string
): Array<DataItem> {
const dataItems: Array<DataItem> = []
): Array<PSUDataItem> {
const dataItems: Array<PSUDataItem> = []

for (const requestEntry of requestEntries) {
const task = requestEntry.resource as Task
logger.info("Building data item for task.", {task: task, id: task.id})

const repeatNo = task.input?.[0]?.valueInteger

const dataItem: DataItem = {
const dataItem: PSUDataItem = {
LastModified: task.lastModified!,
LineItemID: task.focus!.identifier!.value!.toUpperCase(),
PatientNHSNumber: task.for!.identifier!.value!,
Expand Down Expand Up @@ -300,7 +287,7 @@ function response(statusCode: number, responseEntries: Array<BundleEntry>) {
}
}

async function logTransitions(dataItems: Array<DataItem>): Promise<void> {
async function logTransitions(dataItems: Array<PSUDataItem>): Promise<void> {
for (const dataItem of dataItems) {
try {
const previousItem = await getPreviousItem(dataItem)
Expand Down
14 changes: 7 additions & 7 deletions packages/updatePrescriptionStatus/src/utils/databaseClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ import {
} from "@aws-sdk/client-dynamodb"
import {marshall, unmarshall} from "@aws-sdk/util-dynamodb"

import {DataItem} from "../updatePrescriptionStatus"
import {PSUDataItem} from "@PrescriptionStatusUpdate_common/commonTypes"
import {Timeout} from "./timeoutUtils"

const client = new DynamoDBClient()
const tableName = process.env.TABLE_NAME ?? "PrescriptionStatusUpdates"

function createTransactionCommand(dataItems: Array<DataItem>, logger: Logger): TransactWriteItemsCommand {
function createTransactionCommand(dataItems: Array<PSUDataItem>, logger: Logger): TransactWriteItemsCommand {
logger.info("Creating transaction command to write data items.")
const transactItems: Array<TransactWriteItem> = dataItems.map((d: DataItem): TransactWriteItem => {
const transactItems: Array<TransactWriteItem> = dataItems.map((d: PSUDataItem): TransactWriteItem => {
return {
Put: {
TableName: tableName,
Expand All @@ -32,7 +32,7 @@ function createTransactionCommand(dataItems: Array<DataItem>, logger: Logger): T
return new TransactWriteItemsCommand({TransactItems: transactItems})
}

export async function persistDataItems(dataItems: Array<DataItem>, logger: Logger): Promise<boolean | Timeout> {
export async function persistDataItems(dataItems: Array<PSUDataItem>, logger: Logger): Promise<boolean | Timeout> {
const transactionCommand = createTransactionCommand(dataItems, logger)
try {
logger.info("Sending TransactWriteItemsCommand to DynamoDB.", {command: transactionCommand})
Expand Down Expand Up @@ -72,7 +72,7 @@ export async function checkPrescriptionRecordExistence(
}
}

export async function getPreviousItem(currentItem: DataItem): Promise<DataItem | undefined> {
export async function getPreviousItem(currentItem: PSUDataItem): Promise<PSUDataItem | undefined> {
const query: QueryCommandInput = {
TableName: tableName,
KeyConditions: {
Expand All @@ -90,7 +90,7 @@ export async function getPreviousItem(currentItem: DataItem): Promise<DataItem |
}

let lastEvaluatedKey
let items: Array<DataItem> = []
let items: Array<PSUDataItem> = []
do {
if (lastEvaluatedKey) {
query.ExclusiveStartKey = lastEvaluatedKey
Expand All @@ -99,7 +99,7 @@ export async function getPreviousItem(currentItem: DataItem): Promise<DataItem |
if (result.Items) {
items = items.concat(
result.Items
.map((item) => unmarshall(item) as DataItem)
.map((item) => unmarshall(item) as PSUDataItem)
.filter((item) => item.TaskID !== currentItem.TaskID) // Can't do NE in the query so filter here
)
}
Expand Down
32 changes: 22 additions & 10 deletions packages/updatePrescriptionStatus/src/utils/sqsClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ import {SQSClient, SendMessageBatchCommand} from "@aws-sdk/client-sqs"

import {createHmac} from "crypto"

import {DataItem} from "../updatePrescriptionStatus"
import {PSUDataItem} from "@PrescriptionStatusUpdate_common/commonTypes"

import {checkSiteOrSystemIsNotifyEnabled} from "../validation/notificationSiteAndSystemFilters"

const sqsUrl: string | undefined = process.env.NHS_NOTIFY_PRESCRIPTIONS_SQS_QUEUE_URL
const sqsSalt: string = process.env.SQS_SALT ?? "DEVSALT"
const fallbackSalt = "DEV SALT"
const sqsSalt: string = process.env.SQS_SALT ?? fallbackSalt

// The AWS_REGION is always defined in lambda environments
const sqs = new SQSClient({region: process.env.AWS_REGION})
Expand All @@ -33,26 +36,26 @@ function chunkArray<T>(arr: Array<T>, size: number): Array<Array<T>> {
* @param hashFunction - Which hash function to use. HMAC compatible. Defaults to SHA-256
* @returns - A hex encoded string of the hash
*/
export function saltedHash(input: string, hashFunction: string = "sha256"): string {
if (sqsSalt === "DEVSALT") {
console.warn("Using the fallback salt value - please update the environment variable `SQS_SALT` to a random value.")
export function saltedHash(logger: Logger, input: string, hashFunction: string = "sha256"): string {
if (sqsSalt === fallbackSalt) {
logger.warn("Using the fallback salt value - please update the environment variable `SQS_SALT` to a random value.")
}
return createHmac(hashFunction, sqsSalt)
.update(input, "utf8")
.digest("hex")
}

/**
* Pushes an array of DataItems to the notifications SQS queue
* Pushes an array of PSUDataItem to the notifications SQS queue
* Uses SendMessageBatch to send up to 10 at a time
*
* @param requestId - The x-request-id header from the incoming event
* @param data - Array of DataItems to send to SQS
* @param data - Array of PSUDataItem to send to SQS
* @param logger - Logger instance
*/
export async function pushPrescriptionToNotificationSQS(
requestId: string,
data: Array<DataItem>,
data: Array<PSUDataItem>,
logger: Logger
) {
logger.info("Checking if any items require notifications", {numItemsToBeChecked: data.length, sqsUrl})
Expand All @@ -62,8 +65,17 @@ export async function pushPrescriptionToNotificationSQS(
throw new Error("Notifications SQS URL not configured")
}

// Only allow through sites and systems that are allowedSitesAndSystems
const allowedSitesAndSystemsData = checkSiteOrSystemIsNotifyEnabled(data)
logger.info(
"Filtered out sites and suppliers that are not enabled, or are explicitly disabled",
{
numItemsAllowed: allowedSitesAndSystemsData.length
}
)

// SQS batch calls are limited to 10 messages per request, so chunk the data
const batches = chunkArray(data, 10)
const batches = chunkArray(allowedSitesAndSystemsData, 10)

// Only these statuses will be pushed to the SQS
const updateStatuses: Array<string> = [
Expand All @@ -80,7 +92,7 @@ export async function pushPrescriptionToNotificationSQS(
MessageBody: JSON.stringify(item),
// FIFO
// We dedupe on both nhs number and ods code
MessageDeduplicationId: saltedHash(`${item.PatientNHSNumber}:${item.PharmacyODSCode}`),
MessageDeduplicationId: saltedHash(logger, `${item.PatientNHSNumber}:${item.PharmacyODSCode}`),
MessageGroupId: requestId
}))
// We could do a round of deduplications here, but benefits would be minimal and AWS SQS will do it for us anyway.
Expand Down
Loading