Skip to content

Commit

Permalink
chore: address issues raised in PR
Browse files Browse the repository at this point in the history
  • Loading branch information
RichardBray committed Aug 16, 2023
1 parent f603ecb commit 1a998c7
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Then("an email for the {string} key date is sent to eligible providers", async f
{
jsonData: {
path: ["notes"],
equals: ["sendStartedProviderEmail"],
array_contains: ["sendStartedProviderEmail"],
},
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export function formatDate(date: Date = todayDateString) {
return date.toLocaleString("en-gb", options);
}

export function hasDataContainingReference(
export function isEmailSentBefore(
event: Event | Audit | undefined,
reminderType: ListAnnualReviewPostReminderType | ListItemAnnualReviewProviderReminderType
): boolean {
Expand All @@ -38,7 +38,7 @@ export function hasDataContainingReference(
if ("createdAt" in event) {
reminderHasBeenSent = subsequentEmails?.includes?.((event.jsonData as ListEventJsonData)?.reminderType as string);
} else {
reminderHasBeenSent = subsequentEmails?.includes?.((event.jsonData as Record<string, string>)?.notes);
reminderHasBeenSent = subsequentEmails?.includes?.((event.jsonData as Record<string, string>)?.notes[0]);
}

if (reminderHasBeenSent) {
Expand Down
46 changes: 22 additions & 24 deletions src/scheduler/workers/processListsBeforeAndDuringStart/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import type {
ListItemWithHistory,
} from "shared/types";
import type { MilestoneTillAnnualReview } from "../../batch/helpers";
import { formatDate, hasDataContainingReference } from "./helpers";
import { formatDate, isEmailSentBefore } from "./helpers";
import { createAnnualReviewProviderUrl } from "scheduler/workers/createAnnualReviewProviderUrl";
import {
sendAnnualReviewPostEmail,
Expand Down Expand Up @@ -47,28 +47,26 @@ async function processPostEmailsForList(
);
});

const sendResult = await Promise.allSettled(postEmailPromises);
const emailSent = sendResult.find((result) => result.status === "fulfilled" && result.value);
try {
await Promise.any(postEmailPromises);
logger.info(`Annual review email sent to post contacts ${list.jsonData.users}`);

if (!emailSent) {
await prisma.audit.create({
data: {
auditEvent: AuditEvent.REMINDER,
type: "list",
jsonData: {
eventName: "reminder",
annualReviewRef: list.jsonData.currentAnnualReview?.reference,
reminderType,
},
},
});
} catch (e) {
logger.error(
`processPostEmailsForList: Unable to send annual review email to post contacts ${list.jsonData.users} for list ${list.id} ${milestoneTillAnnualReview} before annual review start`
);
return;
}
logger.info(`Annual review email sent to post contacts ${list.jsonData.users}`);

await prisma.audit.create({
data: {
auditEvent: AuditEvent.REMINDER,
type: "list",
jsonData: {
eventName: "reminder",
annualReviewRef: list.jsonData.currentAnnualReview?.reference,
reminderType,
},
},
});
}

async function sendAnnualReviewStartEmail(list: List, listItem: ListItemWithHistory) {
Expand Down Expand Up @@ -97,7 +95,7 @@ async function processProviderEmailsForListItems(list: List, listItems: ListItem
const { result: events } = await findAllReminderEvents({ annualReviewReference, itemId: listItem.id });
if (events?.length) {
const event = events.pop();
isEmailSent = hasDataContainingReference(event, "sendStartedProviderEmail");
isEmailSent = isEmailSentBefore(event, "sendStartedProviderEmail");
}
}

Expand Down Expand Up @@ -167,7 +165,7 @@ export async function processList(list: List, listItemsForList: ListItemWithHist
end: subDays(endOfDay(new Date(annualReviewKeyDates?.POST_ONE_WEEK ?? "")), 1),
})
) {
isEmailSent = hasDataContainingReference(latestAudit as Audit, "sendOneMonthPostEmail");
isEmailSent = isEmailSentBefore(latestAudit as Audit, "sendOneMonthPostEmail");
if (!isEmailSent) {
await processPostEmailsForList(list, "POST_ONE_MONTH", "sendOneMonthPostEmail");
}
Expand All @@ -179,29 +177,29 @@ export async function processList(list: List, listItemsForList: ListItemWithHist
end: subDays(endOfDay(new Date(annualReviewKeyDates?.POST_ONE_DAY ?? "")), 1),
})
) {
isEmailSent = hasDataContainingReference(latestAudit as Audit, "sendOneWeekPostEmail");
isEmailSent = isEmailSentBefore(latestAudit as Audit, "sendOneWeekPostEmail");
if (!isEmailSent) {
await processPostEmailsForList(list, "POST_ONE_WEEK", "sendOneWeekPostEmail");
}
return;
}
if (isSameDay(today, new Date(annualReviewKeyDates?.POST_ONE_DAY ?? ""))) {
isEmailSent = hasDataContainingReference(latestAudit as Audit, "sendOneDayPostEmail");
isEmailSent = isEmailSentBefore(latestAudit as Audit, "sendOneDayPostEmail");
if (!isEmailSent) {
await processPostEmailsForList(list, "POST_ONE_DAY", "sendOneDayPostEmail");
}
return;
}
if (isSameDay(new Date(annualReviewKeyDates?.START ?? ""), today)) {
// email posts to notify of annual review start
isEmailSent = hasDataContainingReference(latestAudit as Audit, "sendStartedPostEmail");
isEmailSent = isEmailSentBefore(latestAudit as Audit, "sendStartedPostEmail");
if (!isEmailSent) {
await processPostEmailsForList(list, "START", "sendStartedPostEmail");
}

// update ListItem.isAnnualReview if today = the START milestone date
// email providers to notify of annual review start
isEmailSent = hasDataContainingReference(latestEvent as Event, "sendStartedProviderEmail");
isEmailSent = isEmailSentBefore(latestEvent as Event, "sendStartedProviderEmail");
if (isEmailSent) {
logger.info(`Annual review started email has already been sent to providers for list ${list.id}`);
return;
Expand Down
13 changes: 12 additions & 1 deletion src/server/models/listItem/listItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { listItemCreateInputFromWebhook } from "./listItemCreateInputFromWebhook
import pgescape from "pg-escape";
import { prisma } from "server/models/db/prisma-client";
import { logger } from "server/services/logger";
import { Status } from "@prisma/client";
import { AuditEvent, Status } from "@prisma/client";
import { merge } from "lodash";
import { EVENTS } from "./listItemEvent";
import { subMonths } from "date-fns";
Expand Down Expand Up @@ -458,6 +458,17 @@ export async function deleteListItem(id: number, userId: User["id"]): Promise<vo
id,
},
}),
prisma.audit.create({
data: {
auditEvent: AuditEvent.DELETED,
type: "listItem",
jsonData: {
eventName: "delete",
itemId: id,
userId,
},
},
}),
]);
} catch (e) {
logger.error(`deleteListItem Error ${e.message}`);
Expand Down
6 changes: 3 additions & 3 deletions src/server/services/govuk-notify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export async function sendAuthenticationEmail(email: string, authenticationLink:
reference: "",
});

return "id" in result && result.id !== undefined;
return result.statusText === "Created";
} catch (error) {
logger.error(`sendAuthenticationEmail Error: ${error.message}`);
return false;
Expand All @@ -60,7 +60,7 @@ export async function sendApplicationConfirmationEmail(
reference: "",
});

return "id" in result && result.id !== undefined;
return result.statusText === "Created";
} catch (error) {
logger.error(`sendApplicationConfirmationEmail Error: ${error.message}`);
return false;
Expand All @@ -87,7 +87,7 @@ export async function sendDataPublishedEmail(
reference: "",
});

return "id" in result && result.id !== undefined;
return result.statusText === "Created";
} catch (error) {
logger.error(`sendDataPublishedEmail Error: ${error.message}`);
return false;
Expand Down
11 changes: 9 additions & 2 deletions src/shared/getNotifyClient.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import { NotifyClient } from "notifications-node-client";
import type { SendEmailResponse } from "notifications-node-client";
import * as config from "server/config";
import { get } from "lodash";

let notifyClient: NotifyClient | undefined;

type DeepPartial<T> = T extends object
? {
[P in keyof T]?: DeepPartial<T[P]>;
}
: T;

export function getNotifyClient() {
if (config.isSmokeTest) {
return new FakeNotifyClient();
Expand All @@ -20,8 +27,8 @@ export function getNotifyClient() {
}

class FakeNotifyClient {
sendEmail() {
return { id: "Created" };
sendEmail(): { statusText: string; data: DeepPartial<SendEmailResponse> } {
return { statusText: "test", data: { id: "Created" } };
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ declare module "notifications-node-client" {
is_csv: boolean;
}

type Response<T> = Promise<{ status: number; data: T | ErrorResponse }>;
type Response<T> = Promise<{ status: number; statusText: string; data: T | ErrorResponse }>;

interface ErrorResponse {
status_code: number;
Expand Down

0 comments on commit 1a998c7

Please sign in to comment.