11import { Logger } from "@aws-lambda-powertools/logger"
22
3- import { PostDatedSQSMessageWithExistingRecords } from "./types "
3+ import { PSUDataItem } from "@psu-common/commonTypes "
44
5+ import { PostDatedSQSMessageWithExistingRecords , PostDatedProcessingResult } from "./types"
6+
7+ // defaults to false
58const POST_DATED_OVERRIDE = process . env . POST_DATED_OVERRIDE === "true"
6- const POST_DATED_OVERRIDE_VALUE = process . env . POST_DATED_OVERRIDE_VALUE === "true"
9+
10+ // set from environment variable POST_DATED_OVERRIDE_VALUE
11+ const POST_DATED_OVERRIDE_VALUE_ENV = process . env . POST_DATED_OVERRIDE_VALUE ?? "ignore"
12+ let POST_DATED_OVERRIDE_VALUE : PostDatedProcessingResult
13+ switch ( POST_DATED_OVERRIDE_VALUE_ENV . toLowerCase ( ) ) {
14+ case "matured" :
15+ POST_DATED_OVERRIDE_VALUE = PostDatedProcessingResult . MATURED
16+ break
17+ case "immature" :
18+ POST_DATED_OVERRIDE_VALUE = PostDatedProcessingResult . IMMATURE
19+ break
20+ default :
21+ POST_DATED_OVERRIDE_VALUE = PostDatedProcessingResult . IGNORE
22+ break
23+ }
24+
25+ export function getMostRecentRecord (
26+ existingRecords : Array < PSUDataItem >
27+ ) : PSUDataItem {
28+ return existingRecords . reduce ( ( latest , record ) => {
29+ const latestTimestamp = latest . PostDatedLastModifiedSetAt
30+ ? new Date ( latest . PostDatedLastModifiedSetAt )
31+ : new Date ( latest . LastModified )
32+ const recordTimestamp = record . PostDatedLastModifiedSetAt
33+ ? new Date ( record . PostDatedLastModifiedSetAt )
34+ : new Date ( record . LastModified )
35+ return recordTimestamp > latestTimestamp ? record : latest
36+ } , existingRecords [ 0 ] )
37+ }
738
839/**
940 * Process a single post-dated prescription message.
@@ -13,15 +44,14 @@ const POST_DATED_OVERRIDE_VALUE = process.env.POST_DATED_OVERRIDE_VALUE === "tru
1344 * @param message - The SQS message containing post-dated prescription data and existing records
1445 * @returns Promise<boolean> - true if the post-dated prescription has matured, and false otherwise
1546 */
16- export async function processMessage (
47+ export function processMessage (
1748 logger : Logger ,
1849 message : PostDatedSQSMessageWithExistingRecords
19- ) : Promise < boolean > {
20- logger . info ( "Processing post-dated prescription message (dummy) " , {
50+ ) : string {
51+ logger . info ( "Processing post-dated prescription message" , {
2152 messageId : message . MessageId ,
2253 prescriptionData : message . prescriptionData ,
23- existingRecordsCount : message . existingRecords . length ,
24- existingRecordTaskIds : message . existingRecords . map ( ( r ) => r . TaskID )
54+ existingRecords : message . existingRecords
2555 } )
2656 if ( POST_DATED_OVERRIDE ) {
2757 logger . info ( "Post-dated override is enabled, returning override value" , {
@@ -30,24 +60,56 @@ export async function processMessage(
3060 return POST_DATED_OVERRIDE_VALUE
3161 }
3262
33- // TODO: Implement actual business logic for post-dated prescription processing
3463 // The existingRecords array contains all records from the DynamoDB table
3564 // that match this prescription's PrescriptionID
3665
3766 // NOTE: It is technically possible for the array to be empty if no existing records are found
38- // This SHOULD never happen in practice, but the code should handle it gracefully just in case
67+ // This SHOULD never happen in practice, but catch it anyway
68+ if ( message . existingRecords . length === 0 ) {
69+ logger . error ( "No existing records found for post-dated prescription, cannot process" , {
70+ badMessage : message
71+ } )
72+
73+ // throw new Error("No existing records found for post-dated prescription") // maybe?
74+ return PostDatedProcessingResult . IGNORE
75+ }
76+
77+ // We only care about the most recent submission for this prescription
78+ // If PostDatedLastModifiedSetAt IS set, it is the timestamp we received the submission
79+ // If it is NOT set, then LastModified is the timestamp we received the submission
80+ const mostRecentRecord = getMostRecentRecord ( message . existingRecords )
81+
82+ logger . info ( "Most recent NPPTS record for post-dated processing" , {
83+ mostRecentRecord
84+ } )
85+
86+ // Is it post-dated?
87+ if ( ! mostRecentRecord . PostDatedLastModifiedSetAt ) {
88+ logger . info (
89+ "Most recent record is not marked as post-dated, and will have been processed " +
90+ "by the standard logic already. Marking as to be ignored by the post-dated notifications lambda."
91+ )
92+ return PostDatedProcessingResult . IGNORE
93+ }
94+
95+ // Is it still RTC?
96+ const mostRecentStatus = mostRecentRecord . Status . toLowerCase ( )
97+ const notifiableStatuses : Array < string > = [ "ready to collect" , "ready to collect - partial" ]
98+ if ( ! notifiableStatuses . includes ( mostRecentStatus ) ) {
99+ logger . info ( "Most recent status in the NPPTS data store is not a notifiable status, so will be ignored" , {
100+ mostRecentStatus : mostRecentStatus
101+ } )
102+ return PostDatedProcessingResult . IGNORE
103+ }
39104
40- const mostRecentRecord = message . existingRecords . reduce ( ( latest , record ) => {
41- return new Date ( record . LastModified ) > new Date ( latest . LastModified ) ? record : latest
42- } , message . existingRecords [ 0 ] )
43105 const mostRecentLastModified = new Date ( mostRecentRecord . LastModified )
44- const desiredTransitionTime = new Date ( mostRecentRecord . PostDatedLastModifiedSetAt as string )
106+ const desiredTransitionTime = new Date ( mostRecentRecord . PostDatedLastModifiedSetAt )
45107 const currentTime = new Date ( )
46108 logger . info ( "Post-dated prescription timing details" , {
47109 mostRecentLastModified : mostRecentLastModified . toISOString ( ) ,
48110 desiredTransitionTime : desiredTransitionTime . toISOString ( ) ,
49111 currentTime : currentTime . toISOString ( )
50112 } )
51113
52- return true
114+ return PostDatedProcessingResult . MATURED
53115}
0 commit comments