Skip to content

Commit f0d010f

Browse files
committed
refactor the db client
1 parent 4f47313 commit f0d010f

1 file changed

Lines changed: 49 additions & 39 deletions

File tree

packages/postDatedLambda/src/databaseClient.ts

Lines changed: 49 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ const client = new DynamoDBClient()
1313
const tableName = process.env.TABLE_NAME ?? "PrescriptionStatusUpdates"
1414
const pharmacyPrescriptionIndexName = "PharmacyODSCodePrescriptionIDIndexPostDatedIndex"
1515

16+
type PrescriptionLookupRequest = {
17+
lookupKey: string
18+
prescriptionID: string
19+
pharmacyODSCode: string
20+
}
21+
1622
export function createPrescriptionLookupKey(prescriptionID: string, pharmacyODSCode: string): string {
1723
return `${prescriptionID.toUpperCase()}#${pharmacyODSCode.toUpperCase()}`
1824
}
@@ -106,25 +112,54 @@ export async function fetchExistingRecordsForPrescriptions(
106112
logger: Logger
107113
): Promise<Array<PostDatedPrescriptionWithExistingRecords>> {
108114
logger.info("Fetching existing records for post-dated prescriptions", {
109-
prescriptionCount: postDatedItems.length
115+
prescriptionCount: postDatedItems.length,
116+
prescriptionIDs: postDatedItems.map((p) => p.PrescriptionID)
110117
})
118+
const lookupRequests = buildLookupRequests(postDatedItems)
119+
const existingRecordsMap = await buildExistingRecordsMap(lookupRequests, logger)
120+
121+
// Map each post-dated item to its corresponding existing records
122+
const results: Array<PostDatedPrescriptionWithExistingRecords> = postDatedItems.map(
123+
(postDatedData) => {
124+
const lookupKey = createPrescriptionLookupKey(postDatedData.PrescriptionID, postDatedData.PharmacyODSCode)
125+
const existingRecords = existingRecordsMap.get(lookupKey) ?? []
126+
127+
return {
128+
postDatedData,
129+
existingRecords
130+
}
131+
})
132+
133+
return results
134+
}
135+
136+
function buildLookupRequests(postDatedItems: Array<NotifyDataItem>): Array<PrescriptionLookupRequest> {
137+
// Run though a map to deduplicate lookups
138+
const lookups = new Map<string, PrescriptionLookupRequest>()
111139

112-
// The data table is indexed by both PrescriptionID and PharmacyODSCode, so build a map keyed by these
113-
// in combination. Should avoid duplicate queries this way.
114-
const uniquePrescriptionLookups = new Map<string, {prescriptionID: string; pharmacyODSCode: string}>()
115140
for (const item of postDatedItems) {
116141
const lookupKey = createPrescriptionLookupKey(item.PrescriptionID, item.PharmacyODSCode)
117-
if (!uniquePrescriptionLookups.has(lookupKey)) {
118-
uniquePrescriptionLookups.set(lookupKey, {
119-
prescriptionID: item.PrescriptionID,
120-
pharmacyODSCode: item.PharmacyODSCode
121-
})
122-
}
142+
143+
// dont worry about overwriting entries, since they'll be identical
144+
lookups.set(lookupKey, {
145+
lookupKey,
146+
prescriptionID: item.PrescriptionID,
147+
pharmacyODSCode: item.PharmacyODSCode
148+
})
123149
}
124150

151+
return Array.from(lookups.values())
152+
}
153+
154+
async function buildExistingRecordsMap(
155+
lookupRequests: Array<PrescriptionLookupRequest>,
156+
logger: Logger
157+
): Promise<Map<string, Array<PSUDataItem>>> {
125158
const existingRecordsMap = new Map<string, Array<PSUDataItem>>()
159+
160+
// await all lookups in parallel
126161
await Promise.all(
127-
Array.from(uniquePrescriptionLookups.entries()).map(async ([lookupKey, {prescriptionID, pharmacyODSCode}]) => {
162+
lookupRequests.map(async ({lookupKey, prescriptionID, pharmacyODSCode}) => {
128163
try {
129164
const records = await getExistingRecordsByPrescriptionID(prescriptionID, pharmacyODSCode, logger)
130165
existingRecordsMap.set(lookupKey, records)
@@ -134,30 +169,12 @@ export async function fetchExistingRecordsForPrescriptions(
134169
pharmacyODSCode,
135170
error
136171
})
137-
// Store empty array on error to allow processing to continue
138-
existingRecordsMap.set(lookupKey, [])
172+
existingRecordsMap.set(lookupKey, []) // Continue processing other prescriptions even when one fails
139173
}
140174
})
141175
)
142176

143-
// Map each post-dated item to its corresponding existing records
144-
const results: Array<PostDatedPrescriptionWithExistingRecords> = postDatedItems.map(
145-
(postDatedData) => {
146-
const lookupKey = createPrescriptionLookupKey(postDatedData.PrescriptionID, postDatedData.PharmacyODSCode)
147-
const existingRecords = existingRecordsMap.get(lookupKey) ?? []
148-
149-
return {
150-
postDatedData,
151-
existingRecords
152-
}
153-
})
154-
155-
logger.info("fetched existing prescription update records for all post-dated prescription IDs", {
156-
totalPrescriptions: postDatedItems.length,
157-
uniquePrescriptionLookups: existingRecordsMap.size
158-
})
159-
160-
return results
177+
return existingRecordsMap
161178
}
162179

163180
/**
@@ -172,10 +189,6 @@ export async function enrichMessagesWithExistingRecords(
172189
messages: Array<PostDatedSQSMessage>,
173190
logger: Logger
174191
): Promise<Array<PostDatedSQSMessageWithExistingRecords>> {
175-
if (messages.length === 0) {
176-
return []
177-
}
178-
179192
const postDatedItems = messages.map((m) => m.prescriptionData)
180193

181194
const prescriptionsWithRecords = await fetchExistingRecordsForPrescriptions(postDatedItems, logger)
@@ -189,10 +202,7 @@ export async function enrichMessagesWithExistingRecords(
189202
for (const msg of enrichedMessages) {
190203
logger.info("Prescription and most recent existing record", {
191204
prescriptionID: msg.prescriptionData.PrescriptionID,
192-
existingRecordCount: msg.existingRecords.length,
193-
mostRecentExistingRecord: msg.existingRecords.length > 0
194-
? msg.existingRecords[0]
195-
: null
205+
existingRecordCount: msg.existingRecords.length
196206
})
197207
}
198208

0 commit comments

Comments
 (0)