Repository: PA-NIHR-CRN/sponsor-engagement-web
Pull request #386: Feat/se 251 email
Author: login: AkADawg
Created: 2025-04-08T11:04:47Z | Merged: 2025-04-10T14:43:52Z

This PR:
- sends an email when the status of an email is logged as a failure in the DB.


Diff:
diff --git a/apps/invitation-monitor/package.json b/apps/invitation-monitor/package.json
index 496ca089e..ac5801313 100644
--- a/apps/invitation-monitor/package.json
+++ b/apps/invitation-monitor/package.json
@@ -17,6 +17,7 @@
     "@lifeomic/attempt": "3.1.0",
     "@nihr-ui/email": "*",
     "@nihr-ui/logger": "*",
+    "@nihr-ui/templates": "*",
     "database": "*",
     "dayjs": "1.11.13",
     "dotenv": "16.3.1"
@@ -38,6 +39,11 @@
     "entry": [
       "src/index.ts"
     ],
+    "noExternal": [
+      "@nihr-ui/logger",
+      "@nihr-ui/email",
+      "@nihr-ui/templates"
+    ],
     "splitting": false,
     "sourcemap": true,
     "clean": true
diff --git a/apps/invitation-monitor/src/invitation-monitor.ts b/apps/invitation-monitor/src/invitation-monitor.ts
index e68305e14..e7cf020bf 100644
--- a/apps/invitation-monitor/src/invitation-monitor.ts
+++ b/apps/invitation-monitor/src/invitation-monitor.ts
@@ -1,23 +1,25 @@
 import { Prisma } from 'database'
-import { emailDeliverabilityService } from '@nihr-ui/email'
+import { emailDeliverabilityService, emailService } from '@nihr-ui/email'
 import { config as dotEnvConfig } from 'dotenv'
 import { BounceType, EventType } from '@aws-sdk/client-sesv2'
 import utc from 'dayjs/plugin/utc'
 import dayjs from 'dayjs'
 import { logger } from '@nihr-ui/logger'
 import type { EmailStatusResult } from '@nihr-ui/email/email-deliverability-service'
+import { emailTemplates } from '@nihr-ui/templates/sponsor-engagement'
 import { retry } from '@lifeomic/attempt'
 import { PERMANENT_EMAIL_FAILURES, UserOrganisationInviteStatus } from './lib/constants'
 import { prismaClient } from './lib/prisma'
-import type { UserOrgnaisationInvitations } from './types'
+import type { UserOrganisationInvitations } from './types'
+import { getSponsorEngagementUrl } from './utils'
 
 dotEnvConfig()
 // eslint-disable-next-line import/no-named-as-default-member -- intentional to use this extend from dayjs obj
 dayjs.extend(utc)
 
-const fetchPendingEmails = async (pendingStatusId: number): Promise<UserOrgnaisationInvitations> => {
+const fetchPendingEmails = async (pendingStatusId: number): Promise<UserOrganisationInvitations> => {
   return prismaClient.userOrganisationInvitation.findMany({
-    where: { statusId: pendingStatusId },
+    where: { statusId: pendingStatusId, isDeleted: false },
     distinct: ['userOrganisationId'],
     orderBy: {
       createdAt: Prisma.SortOrder.desc,
@@ -26,6 +28,16 @@ const fetchPendingEmails = async (pendingStatusId: number): Promise<UserOrgnaisa
       id: true,
       messageId: true,
       timestamp: true,
+      sentBy: true,
+      userOrganisation: {
+        include: {
+          user: {
+            select: {
+              email: true,
+            },
+          },
+        },
+      },
     },
   })
 }
@@ -91,7 +103,7 @@ export const monitorInvitationEmails = async () => {
   const getEmailStatusPromises = pendingEmails.map((email) => fetchEmailStatus(email.messageId))
   const emailStatusResults = await Promise.allSettled(getEmailStatusPromises)
   const successIds = []
-  const failedIds = []
+  const failedEmailDetails: { id: number; userEmail: string; sentByEmail: string }[] = []
   const todayUTCDate = dayjs.utc()
 
   for (const email of pendingEmails) {
@@ -120,14 +132,28 @@ export const monitorInvitationEmails = async () => {
         (event) => event.Type === EventType.BOUNCE && event.Details?.Bounce?.BounceType === BounceType.PERMANENT
       )
     ) {
-      failedIds.push(id)
+      failedEmailDetails.push({
+        id,
+        userEmail: email.userOrganisation.user.email,
+        sentByEmail: email.sentBy.email,
+      })
     } else if (events.some((event) => PERMANENT_EMAIL_FAILURES.includes(event.Type ?? ''))) {
-      failedIds.push(id)
+      failedEmailDetails.push({
+        id,
+        userEmail: email.userOrganisation.user.email,
+        sentByEmail: email.sentBy.email,
+      })
     } else if (hoursSinceEmailSent > EMAIL_DELIVERY_THRESHOLD_HOURS) {
-      failedIds.push(id)
+      failedEmailDetails.push({
+        id,
+        userEmail: email.userOrganisation.user.email,
+        sentByEmail: email.sentBy.email,
+      })
     }
   }
 
+  const failedIds = failedEmailDetails.map((details) => details.id)
+
   const updateEmailStatusPromises = [
     updateEmailStatus(invitationStatuses[UserOrganisationInviteStatus.SUCCESS], successIds),
     updateEmailStatus(invitationStatuses[UserOrganisationInviteStatus.FAILURE], failedIds),
@@ -142,4 +168,38 @@ export const monitorInvitationEmails = async () => {
     numOfFailedEmailsUpdated.count,
     failedIds.length
   )
+
+  if (failedEmailDetails.length > 0) {
+    const emailInputs = failedEmailDetails.map(({ id, sentByEmail, userEmail }) => ({
+      to: sentByEmail,
+      subject: `The invitation email for a new Sponsor Contact has not been delivered successfully`,
+      htmlTemplate: emailTemplates['invitation-email-unsuccessful.html.hbs'],
+      textTemplate: emailTemplates['invitation-email-unsuccessful.text.hbs'],
+      templateData: {
+        recipientEmailAddress: userEmail,
+        sponsorEngagementToolLink: getSponsorEngagementUrl(),
+      },
+      identifier: id,
+    }))
+
+    const successfullySentIds: number[] = []
+
+    await emailService.sendBulkEmail(emailInputs, (_, identifier) => {
+      if (identifier) successfullySentIds.push(identifier)
+    })
+
+    logger.info('Successfully sent %s/%s emails', successfullySentIds.length, failedEmailDetails.length)
+
+    // Log `failureNotifiedAt` in DB for emails sent successfully
+    if (successfullySentIds.length > 0) {
+      await prismaClient.userOrganisationInvitation.updateMany({
+        where: {
+          id: { in: successfullySentIds },
+        },
+        data: {
+          failureNotifiedAt: todayUTCDate.toDate(),
+        },
+      })
+    }
+  }
 }
diff --git a/apps/invitation-monitor/src/mocks/user-organisation-invitations.ts b/apps/invitation-monitor/src/mocks/user-organisation-invitations.ts
index f3e310b54..5252af32d 100644
--- a/apps/invitation-monitor/src/mocks/user-organisation-invitations.ts
+++ b/apps/invitation-monitor/src/mocks/user-organisation-invitations.ts
@@ -1,6 +1,18 @@
 import { Mock } from 'ts-mockery'
-import type { UserOrganisationInvitation } from 'database'
+import type { UserOrganisationInvitations } from '../types'
 
-export const pendingEmails = Mock.of<UserOrganisationInvitation[]>([
-  { id: 1, messageId: '1-1-1', timestamp: new Date('2025-03-31') },
+export const pendingEmails = Mock.of<UserOrganisationInvitations>([
+  {
+    id: 1,
+    messageId: '1-1-1',
+    timestamp: new Date('2025-03-31'),
+    sentBy: {
+      email: 'sender@test.nihr.ac.uk',
+    },
+    userOrganisation: {
+      user: {
+        email: 'receiver@test.nihr.ac.uk',
+      },
+    },
+  },
 ])
diff --git a/apps/invitation-monitor/src/tests/index.spec.ts b/apps/invitation-monitor/src/tests/index.spec.ts
index a9cde1e87..d66fc6ea4 100644
--- a/apps/invitation-monitor/src/tests/index.spec.ts
+++ b/apps/invitation-monitor/src/tests/index.spec.ts
@@ -1,4 +1,4 @@
-import { emailDeliverabilityService } from '@nihr-ui/email'
+import { emailDeliverabilityService, emailService } from '@nihr-ui/email'
 import { BounceType, EventType, TooManyRequestsException } from '@aws-sdk/client-sesv2'
 import { monitorInvitationEmails } from '../invitation-monitor'
 import { prismaMock } from '../mocks/prisma'
@@ -14,6 +14,7 @@ const mockFetchStatusIds = () => {
 }
 
 const mockEmailDeliverabilityService = emailDeliverabilityService as jest.Mocked<typeof emailDeliverabilityService>
+const mockEmailService = emailService as jest.Mocked<typeof emailService>
 
 const mockGetCurrentDate = (numOfDaysToAdjust: number) => {
   const today = new Date(pendingEmails[0].timestamp)
@@ -25,9 +26,14 @@ const mockGetCurrentDate = (numOfDaysToAdjust: number) => {
 
 const originalEnv = { ...process.env }
 
+const mockUserOrgInvitationFindMany = () => {
+  prismaMock.userOrganisationInvitation.findMany.mockImplementation(jest.fn().mockResolvedValueOnce(pendingEmails))
+}
+
 describe('monitorInvitationEmails', () => {
   beforeEach(() => {
     jest.clearAllMocks()
+
     mockFetchStatusIds()
 
     process.env.INVITE_EMAIL_DELIVERY_THRESHOLD_HOURS = '72'
@@ -48,7 +54,8 @@ describe('monitorInvitationEmails', () => {
   })
 
   it(`should correctly set status of email in DB to 'Success' when AWS email status is 'Delivery'`, async () => {
-    prismaMock.userOrganisationInvitation.findMany.mockResolvedValueOnce(pendingEmails)
+    mockUserOrgInvitationFindMany()
+
     mockEmailDeliverabilityService.getEmailInsights.mockResolvedValueOnce({
       messageId: pendingEmails[0].messageId,
       insights: [mockAWSDeliveredInsight],
@@ -72,7 +79,7 @@ describe('monitorInvitationEmails', () => {
   })
 
   it('should not throw an error when request to fetch status from AWS fails', async () => {
-    prismaMock.userOrganisationInvitation.findMany.mockResolvedValueOnce(pendingEmails)
+    mockUserOrgInvitationFindMany()
 
     mockEmailDeliverabilityService.getEmailInsights.mockRejectedValueOnce(new Error())
 
@@ -83,7 +90,7 @@ describe('monitorInvitationEmails', () => {
   })
 
   it('should throw an error when DB request throws an error', async () => {
-    prismaMock.userOrganisationInvitation.findMany.mockResolvedValueOnce(pendingEmails)
+    mockUserOrgInvitationFindMany()
     mockEmailDeliverabilityService.getEmailInsights.mockResolvedValueOnce({
       messageId: pendingEmails[0].messageId,
       insights: [mockAWSDeliveredInsight],
@@ -99,6 +106,89 @@ describe('monitorInvitationEmails', () => {
     expect(prismaMock.userOrganisationInvitation.updateMany).toHaveBeenCalledTimes(1)
   })
 
+  it(`should send an email when email status is updated to 'Failure' within the DB`, async () => {
+    const todaysDate = mockGetCurrentDate(0)
+    jest.useFakeTimers().setSystemTime(todaysDate)
+
+    mockUserOrgInvitationFindMany()
+    mockEmailDeliverabilityService.getEmailInsights.mockResolvedValueOnce({
+      messageId: pendingEmails[0].messageId,
+      insights: [mockAWSBouncePermanentInsight],
+    })
+    mockEmailService.sendBulkEmail.mockImplementationOnce(async (_, onSuccess) => {
+      await onSuccess(
+        {
+          recipients: [pendingEmails[0].sentBy.email],
+          messageId: pendingEmails[0].messageId,
+        },
+        pendingEmails[0].id
+      )
+    })
+    prismaMock.userOrganisationInvitation.updateMany.mockResolvedValue({ count: 1 })
+
+    await monitorInvitationEmails()
+
+    // Send email
+    expect(mockEmailService.sendBulkEmail).toHaveBeenCalledTimes(1)
+    expect(mockEmailService.sendBulkEmail).toHaveBeenCalledWith(
+      [
+        {
+          to: pendingEmails[0].sentBy.email,
+          subject: `The invitation email for a new Sponsor Contact has not been delivered successfully`,
+          htmlTemplate: expect.any(Function),
+          textTemplate: expect.any(Function),
+          templateData: {
+            recipientEmailAddress: pendingEmails[0].userOrganisation.user.email,
+            sponsorEngagementToolLink: 'http://localhost:3000',
+          },
+          identifier: pendingEmails[0].id,
+        },
+      ],
+      expect.any(Function)
+    )
+
+    expect(prismaMock.userOrganisationInvitation.updateMany).toHaveBeenCalledTimes(2)
+
+    // Log failureNotifiedAt in DB
+    expect(prismaMock.userOrganisationInvitation.updateMany).toHaveBeenNthCalledWith(2, {
+      where: {
+        id: {
+          in: [pendingEmails[0].id],
+        },
+      },
+      data: {
+        failureNotifiedAt: todaysDate,
+      },
+    })
+
+    jest.useRealTimers()
+  })
+
+  it(`should not log 'failureNotifiedAt' field in DB when email status is updated to 'Failure' within the DB AND new email was not successfully sent`, async () => {
+    const todaysDate = mockGetCurrentDate(0)
+    jest.useFakeTimers().setSystemTime(todaysDate)
+
+    mockUserOrgInvitationFindMany()
+    mockEmailDeliverabilityService.getEmailInsights.mockResolvedValueOnce({
+      messageId: pendingEmails[0].messageId,
+      insights: [mockAWSBouncePermanentInsight],
+    })
+    mockEmailService.sendBulkEmail.mockResolvedValueOnce()
+    prismaMock.userOrganisationInvitation.updateMany.mockResolvedValue({ count: 1 })
+
+    await monitorInvitationEmails()
+
+    // Send email
+    expect(mockEmailService.sendBulkEmail).toHaveBeenCalledTimes(1)
+    expect(prismaMock.userOrganisationInvitation.updateMany).toHaveBeenCalledTimes(1) // Only once to update status
+    expect(prismaMock.userOrganisationInvitation.updateMany).toHaveBeenCalledWith({
+      data: {
+        statusId: 3,
+      },
+      where: { id: { in: [pendingEmails[0].id] } },
+    })
+  })
+
   describe('given email was sent within 72 hours', () => {
     beforeAll(() => {
       jest.useFakeTimers().setSystemTime(mockGetCurrentDate(1))
@@ -113,7 +203,7 @@ describe('monitorInvitationEmails', () => {
     })
 
     it('should not throw an error when when insights array is empty', async () => {
-      prismaMock.userOrganisationInvitation.findMany.mockResolvedValueOnce(pendingEmails)
+      mockUserOrgInvitationFindMany()
 
       mockEmailDeliverabilityService.getEmailInsights.mockResolvedValueOnce({
         messageId: pendingEmails[0].messageId,
@@ -126,7 +216,7 @@ describe('monitorInvitationEmails', () => {
     })
 
     it('should retry if initial request to fetch status from AWS fails due to too many requests', async () => {
-      prismaMock.userOrganisationInvitation.findMany.mockResolvedValueOnce(pendingEmails)
+      mockUserOrgInvitationFindMany()
 
       mockEmailDeliverabilityService.getEmailInsights.mockRejectedValueOnce(
         new TooManyRequestsException({ message: 'Oh no an error', $metadata: {} })
@@ -149,7 +239,7 @@ describe('monitorInvitationEmails', () => {
     })
 
     it(`should correctly set status of email in DB to 'Failure' when AWS email status is 'BOUNCE' and it has a 'PERMANENT' subtype`, async () => {
-      prismaMock.userOrganisationInvitation.findMany.mockResolvedValueOnce(pendingEmails)
+      mockUserOrgInvitationFindMany()
       mockEmailDeliverabilityService.getEmailInsights.mockResolvedValueOnce({
         messageId: pendingEmails[0].messageId,
         insights: [mockAWSBouncePermanentInsight],
@@ -173,7 +263,7 @@ describe('monitorInvitationEmails', () => {
     })
 
     it(`should not set status of email in DB to 'Failure' when AWS email status is 'BOUNCE' and it does not have a  'PERMANENT' subtype`, async () => {
-      prismaMock.userOrganisationInvitation.findMany.mockResolvedValueOnce(pendingEmails)
+      mockUserOrgInvitationFindMany()
       mockEmailDeliverabilityService.getEmailInsights.mockResolvedValueOnce({
         messageId: pendingEmails[0].messageId,
         insights: [
@@ -207,7 +297,7 @@ describe('monitorInvitationEmails', () => {
     it.each([EventType.REJECT, EventType.RENDERING_FAILURE])(
       `should correctly set status of email in DB to 'Failure' when AWS email status is %s`,
       async (failedEmailStatus: string) => {
-        prismaMock.userOrganisationInvitation.findMany.mockResolvedValueOnce(pendingEmails)
+        mockUserOrgInvitationFindMany()
         mockEmailDeliverabilityService.getEmailInsights.mockResolvedValueOnce({
           messageId: pendingEmails[0].messageId,
           insights: [
@@ -237,7 +327,7 @@ describe('monitorInvitationEmails', () => {
     )
 
     it(`should not update the status of email in DB when AWS email status is not 'Delivery' or in our pre-defined failed list`, async () => {
-      prismaMock.userOrganisationInvitation.findMany.mockResolvedValueOnce(pendingEmails)
+      mockUserOrgInvitationFindMany()
       mockEmailDeliverabilityService.getEmailInsights.mockResolvedValueOnce({
         messageId: pendingEmails[0].messageId,
         insights: [mockAWSSentInsight],
@@ -265,7 +355,7 @@ describe('monitorInvitationEmails', () => {
     })
 
     it(`should correctly set status of email in DB to 'Failure' when AWS email status is not 'Delivery' or in our pre-defined failed list`, async () => {
-      prismaMock.userOrganisationInvitation.findMany.mockResolvedValueOnce(pendingEmails)
+      mockUserOrgInvitationFindMany()
       mockEmailDeliverabilityService.getEmailInsights.mockResolvedValueOnce({
         messageId: pendingEmails[0].messageId,
         insights: [mockAWSSentInsight],
diff --git a/apps/invitation-monitor/src/types.ts b/apps/invitation-monitor/src/types.ts
index bb839aec7..fc7605524 100644
--- a/apps/invitation-monitor/src/types.ts
+++ b/apps/invitation-monitor/src/types.ts
@@ -1,9 +1,23 @@
 import type { Prisma } from 'database'
 
-export type UserOrgnaisationInvitations = Prisma.UserOrganisationInvitationGetPayload<{
+export type UserOrganisationInvitations = Prisma.UserOrganisationInvitationGetPayload<{
   select: {
     id: true
     messageId: true
     timestamp: true
+    sentBy: {
+      select: {
+        email: true
+      }
+    }
+    userOrganisation: {
+      include: {
+        user: {
+          select: {
+            email: true
+          }
+        }
+      }
+    }
   }
 }>[]
diff --git a/apps/invitation-monitor/src/utils.spec.ts b/apps/invitation-monitor/src/utils.spec.ts
new file mode 100644
index 000000000..47f1fe89e
--- /dev/null
+++ b/apps/invitation-monitor/src/utils.spec.ts
@@ -0,0 +1,38 @@
+import { getSponsorEngagementUrl } from './utils'
+
+describe('getSponsorEngagementUrl()', () => {
+  const originalEnv = process.env
+
+  beforeEach(() => {
+    process.env = { ...originalEnv }
+  })
+
+  afterAll(() => {
+    process.env = originalEnv
+  })
+
+  it('should return localhost URL with custom WEB_PORT when APP_ENV is not set', () => {
+    process.env.APP_ENV = undefined
+    process.env.WEB_PORT = '2000'
+
+    const result = getSponsorEngagementUrl()
+    expect(result).toBe('http://localhost:2000')
+  })
+
+  it('should return prod URL when APP_ENV is "prod"', () => {
+    process.env.APP_ENV = 'prod'
+
+    const result = getSponsorEngagementUrl()
+    expect(result).toBe('https://assessmystudy.nihr.ac.uk')
+  })
+
+  it.each(['uat', 'oat', 'test', 'dev'])(
+    'should return environment-specific URL when APP_ENV is %s',
+    (appEnvValue: string) => {
+      process.env.APP_ENV = appEnvValue
+
+      const result = getSponsorEngagementUrl()
+      expect(result).toBe(`https://${appEnvValue}.assessmystudy.nihr.ac.uk`)
+    }
+  )
+})
diff --git a/apps/invitation-monitor/src/utils.ts b/apps/invitation-monitor/src/utils.ts
new file mode 100644
index 000000000..9bf08b7c3
--- /dev/null
+++ b/apps/invitation-monitor/src/utils.ts
@@ -0,0 +1,13 @@
+export const getSponsorEngagementUrl = () => {
+  const env = process.env.APP_ENV
+
+  if (!env) {
+    return `http://localhost:${process.env.WEB_PORT ?? 3000}`
+  }
+
+  if (env === 'prod') {
+    return `https://assessmystudy.nihr.ac.uk`
+  }
+
+  return `https://${env}.assessmystudy.nihr.ac.uk`
+}
diff --git a/packages/email/email-service/email-service.spec.ts b/packages/email/email-service/email-service.spec.ts
index bdbd4c61f..775ca114a 100644
--- a/packages/email/email-service/email-service.spec.ts
+++ b/packages/email/email-service/email-service.spec.ts
@@ -187,15 +187,21 @@ describe('EmailService', () => {
 
     expect(onSuccessSpy).toHaveBeenCalledTimes(2)
 
-    expect(onSuccessSpy).toHaveBeenCalledWith({
-      messageId: 123,
-      recipients: ['recipient1@example.com', 'recipient2@example.com'],
-    })
+    expect(onSuccessSpy).toHaveBeenCalledWith(
+      {
+        messageId: 123,
+        recipients: ['recipient1@example.com', 'recipient2@example.com'],
+      },
+      undefined
+    )
 
-    expect(onSuccessSpy).toHaveBeenLastCalledWith({
-      messageId: 123,
-      recipients: ['recipient3@example.com', 'recipient4@example.com'],
-    })
+    expect(onSuccessSpy).toHaveBeenLastCalledWith(
+      {
+        messageId: 123,
+        recipients: ['recipient3@example.com', 'recipient4@example.com'],
+      },
+      undefined
+    )
 
     expect(logger.info).toHaveBeenCalledWith(
       'Email notification sent to %s with subject %s',
@@ -250,10 +256,13 @@ describe('EmailService', () => {
 
     expect(onSuccessSpy).toHaveBeenCalledTimes(1)
 
-    expect(onSuccessSpy).toHaveBeenLastCalledWith({
-      messageId: '123',
-      recipients: ['recipient3@example.com', 'recipient4@example.com'],
-    })
+    expect(onSuccessSpy).toHaveBeenLastCalledWith(
+      {
+        messageId: '123',
+        recipients: ['recipient3@example.com', 'recipient4@example.com'],
+      },
+      undefined
+    )
 
     expect(logger.info).toHaveBeenCalledWith(
       'Email notification sent to %s with subject %s',
diff --git a/packages/email/email-service/index.ts b/packages/email/email-service/index.ts
index 75699d1f0..a01a3264d 100644
--- a/packages/email/email-service/index.ts
+++ b/packages/email/email-service/index.ts
@@ -1,6 +1,7 @@
 import type { SES } from 'aws-sdk'
 import { logger } from '@nihr-ui/logger'
 import Bottleneck from 'bottleneck'
+import type { EmailInsightsList } from 'aws-sdk/clients/sesv2'
 import { EMAIL_CHARSET, EMAIL_FROM_ADDRESS } from '../constants'
 
 export interface EmailArgs {
@@ -9,6 +10,7 @@ export interface EmailArgs {
   htmlTemplate: (data: Record<string, unknown>) => string
   textTemplate: (data: Record<string, unknown>) => string
   templateData: Record<string, unknown>
+  identifier?: number
 }
 
 export interface EmailResult {
@@ -16,6 +18,11 @@ export interface EmailResult {
   recipients: string[]
 }
 
+export interface EmailStatusResult {
+  messageId: string
+  insights: EmailInsightsList
+}
+
 export class EmailService {
   constructor(private sesClient: SES) {}
 
@@ -70,7 +77,10 @@ export class EmailService {
     }
   }
 
-  sendBulkEmail = async (emails: EmailArgs[], onSuccess: (result: EmailResult) => Promise<void>) => {
+  sendBulkEmail = async (
+    emails: EmailArgs[],
+    onSuccess: (result: EmailResult, identifier?: number) => Promise<void> | void
+  ) => {
     const { MaxSendRate } = await this.sesClient.getSendQuota().promise()
 
     if (!MaxSendRate) {
@@ -90,7 +100,7 @@ export class EmailService {
       limiter.schedule(async () => {
         try {
           const result = await this.sendEmail(email)
-          return onSuccess(result)
+          return onSuccess(result, email.identifier)
         } catch (error) {
           logger.error(error)
         }
diff --git a/packages/templates/jest.config.json b/packages/templates/jest.config.json
index f108d30e8..86e4412aa 100644
--- a/packages/templates/jest.config.json
+++ b/packages/templates/jest.config.json
@@ -6,7 +6,7 @@
   "reporters": ["default", "jest-junit"],
   "testPathIgnorePatterns": [".vscode"],
   "coverageReporters": ["json-summary", "text", "html", "lcov"],
-  "coveragePathIgnorePatterns": ["node_modules"],
+  "coveragePathIgnorePatterns": ["node_modules", "packages/templates/sponsor-engagement/email/index.js"],
   "coverageThreshold": {
     "global": {
       "lines": 70,
diff --git a/packages/templates/sponsor-engagement/email/__snapshots__/index.spec.ts.snap b/packages/templates/sponsor-engagement/email/__snapshots__/index.spec.ts.snap
index 5f56be786..2b49c2f8a 100644
--- a/packages/templates/sponsor-engagement/email/__snapshots__/index.spec.ts.snap
+++ b/packages/templates/sponsor-engagement/email/__snapshots__/index.spec.ts.snap
@@ -127,7 +127,7 @@ exports[`Email template "assessment-reminder.html.hbs" displays correctly 1`] =
             <td style='width: 162px'>
               <p>
                 &nbsp;<img
-                  src='https://www.nihr.ac.uk/layout/4.0/assets/external/nihr-logo.png'
+                  src='https://nihr.widen.net/content/xazipspiv6/jpeg/nihr-logo.jpeg'
                   alt=''
                   width='206'
                   class='CToWUd'
@@ -138,51 +138,44 @@ exports[`Email template "assessment-reminder.html.hbs" displays correctly 1`] =
           </tr>
         </tbody>
       </table>
-
-      <p>
-        <a
-          href='https://www.nihr.ac.uk/explore-nihr/campaigns/nhs-75/?utm_source=gmail&amp;utm_medium=email&amp;utm_campaign=nhs75&amp;utm_term=signature&amp;utm_content=signature'
-          target='_blank'
-        ><img
-            src='https://www.nihr.ac.uk/layout/img/external/nhs75-shape-the-future-signature.png'
-            alt='NIHR, Supporting NHS75. Life changing research funded by the public. Click, get involved in our NHS75 campaign'
-            width='540'
-            height='101'
-            class='CToWUd'
-            data-bit='iit'
-          />
-        </a>
-      </p>
-
       <p>
         Follow us:
+        <!-- facebook logo -->
         <img
-          src='https://www.nihr.ac.uk/images/about-us/stay-up-to-date/f_logo_RGB-Blue_58.png'
+          src='https://nihr.widen.net/content/aqo4dnubmf/jpeg/f_logo_rgb-blue_58.jpeg'
           alt=''
           width='11'
           height='11'
           class='CToWUd'
           data-bit='iit'
         />
-        <a href='https://www.facebook.com/OfficialNIHR' target='_blank'>NIHR Facebook</a>&nbsp;|&nbsp;<img
-          src='https://www.nihr.ac.uk/images/about-us/stay-up-to-date/Twitter_Logo_Blue.png'
+        <a href='https://www.facebook.com/OfficialNIHR' target='_blank'>NIHR Facebook</a>
+        &nbsp;|&nbsp;
+        <!-- twitter logo -->
+        <img
+          src='https://nihr.widen.net/content/egucpu5vgs/jpeg/x-logo-black.jpeg'
           alt=''
           width='11'
           height='11'
           class='CToWUd'
           data-bit='iit'
         />
-        <a href='https://x.com/NIHRresearch' target='_blank' aria-label='NIHR X (formerly Twitter)'>NIHR X</a>&nbsp;|&nbsp;<img
-          src='https://www.nihr.ac.uk/images/about-us/stay-up-to-date/LI-In-Bug.png'
+        <a href='https://x.com/NIHRresearch' target='_blank' aria-label='NIHR X (formerly Twitter)'>NIHR X</a>
+        &nbsp;|&nbsp;
+        <!-- linkedin logo -->
+        <img
+          src='https://nihr.widen.net/content/xc1gslcvmt/jpeg/li-in-bug.jpeg'
           alt=''
           width='11'
           height='9'
           class='CToWUd'
           data-bit='iit'
-        /><a href='https://www.linkedin.com/company/nihr-research' target='_blank'>NIHR LinkedIn</a>
-        |
+        />
+        <a href='https://www.linkedin.com/company/nihr-research' target='_blank'>NIHR LinkedIn</a>
+        &nbsp;|&nbsp;
+        <!-- youtube logo -->
         <img
-          src='https://www.nihr.ac.uk/images/about-us/stay-up-to-date/youtube_logo_rgb_light.png'
+          src='https://nihr.widen.net/content/52cd9uokcy/jpeg/youtube_logo_rgb_light.jpeg'
           alt=''
           width='11'
           height='9'
@@ -190,9 +183,10 @@ exports[`Email template "assessment-reminder.html.hbs" displays correctly 1`] =
           data-bit='iit'
         />
         <a href='https://www.youtube.com/user/NIHRtv' target='_blank'>NIHR YouTube</a>
-        |
+        &nbsp;|&nbsp;
+        <!-- nihr link logo -->
         <img
-          src='https://www.nihr.ac.uk/layout/img/external/nihr-link-icon.png'
+          src='https://nihr.widen.net/content/5mhcdc6utg/jpeg/nihr-link-icon.jpeg'
           alt=''
           width='11'
           height='9'
@@ -241,8 +235,7 @@ patients, the public and health and care organisations across England.
 The NIHR RDN tracks the progress of research studies in its portfolio using data provided by Sponsors or their delegates
 on behalf of the Department of Health and Social Care (DHSC).
 
-The DHSC have published the Terms and Conditions for NIHR RDN support [http://terms-conditions-link], which outlines 
-the requirements for Sponsors to provide up-to-date study data and assessments of progress to the RDN. 
+The DHSC have published the Terms and Conditions for NIHR RDN support [http://terms-conditions-link], which outlines the requirements for Sponsors to provide up-to-date study data and assessments of progress to the RDN.
 
 The Sponsor Engagement Tool has been designed to support Sponsors and their delegates to meet the requirements outlined in 
 the T&Cs. Sponsors and their delegates should use the Sponsor Engagement Tool to review the data the RDN holds on their organisation’s portfolio of studies, 
@@ -296,14 +289,14 @@ exports[`Email template "contact-assigned.html.hbs" displays correctly 1`] = `
       </p>
 
       <p>
-        The DHSC have published the 
+        The DHSC have published the
         <a href='http://terms-conditions-link'>Terms and Conditions for NIHR RDN support</a>, which outlines the requirements for Sponsors to provide up-to-date study data and assessments of progress to the RDN.
       </p>
 
       <p>
         The Sponsor Engagement Tool has been designed to support Sponsors and their delegates to meet the requirements
         outlined in the T&Cs. Sponsors and their delegates should use the Sponsor Engagement Tool to review the data the
-        RDN holds on their organisation’s portfolio of studies and to provide study data updates and assessments to ensure
+        RDN holds on their organisation's portfolio of studies and to provide study data updates and assessments to ensure
         the data held by the RDN is complete and up-to-date.
       </p>
 
@@ -361,7 +354,7 @@ exports[`Email template "contact-assigned.html.hbs" displays correctly 1`] = `
       <h2>Nominate someone else to assess studies</h2>
 
       <p>
-        The NIHR RDN can give other people in your organisation access to this service. 
+        The NIHR RDN can give other people in your organisation access to this service.
         <a href='mailto:supportmystudy@nihr.ac.uk'>Contact supportmystudy@nihr.ac.uk</a>
         to add a new contact.
       </p>
@@ -370,7 +363,7 @@ exports[`Email template "contact-assigned.html.hbs" displays correctly 1`] = `
 
       <p>
         This email is not monitored, do not reply. If you’re not sure why you’ve received this email or need to be
-        removed from our list 
+        removed from our list
         <a href='mailto:supportmystudy@nihr.ac.uk'>contact supportmystudy@nihr.ac.uk</a>.
       </p>
     </div>
@@ -384,7 +377,7 @@ exports[`Email template "contact-assigned.html.hbs" displays correctly 1`] = `
             <td style='width: 162px'>
               <p>
                 &nbsp;<img
-                  src='https://www.nihr.ac.uk/layout/4.0/assets/external/nihr-logo.png'
+                  src='https://nihr.widen.net/content/xazipspiv6/jpeg/nihr-logo.jpeg'
                   alt=''
                   width='206'
                   class='CToWUd'
@@ -395,51 +388,44 @@ exports[`Email template "contact-assigned.html.hbs" displays correctly 1`] = `
           </tr>
         </tbody>
       </table>
-
-      <p>
-        <a
-          href='https://www.nihr.ac.uk/explore-nihr/campaigns/nhs-75/?utm_source=gmail&amp;utm_medium=email&amp;utm_campaign=nhs75&amp;utm_term=signature&amp;utm_content=signature'
-          target='_blank'
-        ><img
-            src='https://www.nihr.ac.uk/layout/img/external/nhs75-shape-the-future-signature.png'
-            alt='NIHR, Supporting NHS75. Life changing research funded by the public. Click, get involved in our NHS75 campaign'
-            width='540'
-            height='101'
-            class='CToWUd'
-            data-bit='iit'
-          />
-        </a>
-      </p>
-
       <p>
         Follow us:
+        <!-- facebook logo -->
         <img
-          src='https://www.nihr.ac.uk/images/about-us/stay-up-to-date/f_logo_RGB-Blue_58.png'
+          src='https://nihr.widen.net/content/aqo4dnubmf/jpeg/f_logo_rgb-blue_58.jpeg'
           alt=''
           width='11'
           height='11'
           class='CToWUd'
           data-bit='iit'
         />
-        <a href='https://www.facebook.com/OfficialNIHR' target='_blank'>NIHR Facebook</a>&nbsp;|&nbsp;<img
-          src='https://www.nihr.ac.uk/images/about-us/stay-up-to-date/Twitter_Logo_Blue.png'
+        <a href='https://www.facebook.com/OfficialNIHR' target='_blank'>NIHR Facebook</a>
+        &nbsp;|&nbsp;
+        <!-- twitter logo -->
+        <img
+          src='https://nihr.widen.net/content/egucpu5vgs/jpeg/x-logo-black.jpeg'
           alt=''
           width='11'
           height='11'
           class='CToWUd'
           data-bit='iit'
         />
-        <a href='https://x.com/NIHRresearch' target='_blank' aria-label='NIHR X (formerly Twitter)'>NIHR X</a>&nbsp;|&nbsp;<img
-          src='https://www.nihr.ac.uk/images/about-us/stay-up-to-date/LI-In-Bug.png'
+        <a href='https://x.com/NIHRresearch' target='_blank' aria-label='NIHR X (formerly Twitter)'>NIHR X</a>
+        &nbsp;|&nbsp;
+        <!-- linkedin logo -->
+        <img 
+          src='https://nihr.widen.net/content/xc1gslcvmt/jpeg/li-in-bug.jpeg'
           alt=''
           width='11'
           height='9'
           class='CToWUd'
           data-bit='iit'
-        /><a href='https://www.linkedin.com/company/nihr-research' target='_blank'>NIHR LinkedIn</a>
-        |
+        />
+        <a href='https://www.linkedin.com/company/nihr-research' target='_blank'>NIHR LinkedIn</a>
+        &nbsp;|&nbsp;
+        <!-- youtube logo -->
         <img
-          src='https://www.nihr.ac.uk/images/about-us/stay-up-to-date/youtube_logo_rgb_light.png'
+          src='https://nihr.widen.net/content/52cd9uokcy/jpeg/youtube_logo_rgb_light.jpeg'
           alt=''
           width='11'
           height='9'
@@ -447,9 +433,10 @@ exports[`Email template "contact-assigned.html.hbs" displays correctly 1`] = `
           data-bit='iit'
         />
         <a href='https://www.youtube.com/user/NIHRtv' target='_blank'>NIHR YouTube</a>
-        |
+        &nbsp;|&nbsp;
+        <!-- nihr link logo -->
         <img
-          src='https://www.nihr.ac.uk/layout/img/external/nihr-link-icon.png'
+          src='https://nihr.widen.net/content/5mhcdc6utg/jpeg/nihr-link-icon.jpeg'
           alt=''
           width='11'
           height='9'
@@ -533,10 +520,10 @@ exports[`Email template "contact-removed.html.hbs" displays correctly 1`] = `
 
       <h2>Not sure why you've been removed?</h2>
 
-      <p>If you think there’s been an error please 
+      <p>If you think there’s been an error please
         <a href='mailto:supportmystudy@nihr.ac.uk'>contact supportmystudy@nihr.ac.uk</a>.</p>
 
-      <p>If you’re not sure why you’ve received this email or need to be removed from our list 
+      <p>If you’re not sure why you’ve received this email or need to be removed from our list
         <a href='mailto:supportmystudy@nihr.ac.uk'>contact supportmystudy@nihr.ac.uk</a>.</p>
     </div>
 
@@ -549,7 +536,7 @@ exports[`Email template "contact-removed.html.hbs" displays correctly 1`] = `
             <td style='width: 162px'>
               <p>
                 &nbsp;<img
-                  src='https://www.nihr.ac.uk/layout/4.0/assets/external/nihr-logo.png'
+                  src='https://nihr.widen.net/content/xazipspiv6/jpeg/nihr-logo.jpeg'
                   alt=''
                   width='206'
                   class='CToWUd'
@@ -560,51 +547,44 @@ exports[`Email template "contact-removed.html.hbs" displays correctly 1`] = `
           </tr>
         </tbody>
       </table>
-
-      <p>
-        <a
-          href='https://www.nihr.ac.uk/explore-nihr/campaigns/nhs-75/?utm_source=gmail&amp;utm_medium=email&amp;utm_campaign=nhs75&amp;utm_term=signature&amp;utm_content=signature'
-          target='_blank'
-        ><img
-            src='https://www.nihr.ac.uk/layout/img/external/nhs75-shape-the-future-signature.png'
-            alt='NIHR, Supporting NHS75. Life changing research funded by the public. Click, get involved in our NHS75 campaign'
-            width='540'
-            height='101'
-            class='CToWUd'
-            data-bit='iit'
-          />
-        </a>
-      </p>
-
       <p>
         Follow us:
+        <!-- facebook logo -->
         <img
-          src='https://www.nihr.ac.uk/images/about-us/stay-up-to-date/f_logo_RGB-Blue_58.png'
+          src='https://nihr.widen.net/content/aqo4dnubmf/jpeg/f_logo_rgb-blue_58.jpeg'
           alt=''
           width='11'
           height='11'
           class='CToWUd'
           data-bit='iit'
         />
-        <a href='https://www.facebook.com/OfficialNIHR' target='_blank'>NIHR Facebook</a>&nbsp;|&nbsp;<img
-          src='https://www.nihr.ac.uk/images/about-us/stay-up-to-date/Twitter_Logo_Blue.png'
+        <a href='https://www.facebook.com/OfficialNIHR' target='_blank'>NIHR Facebook</a>
+        &nbsp;|&nbsp;
+        <!-- twitter logo -->
+        <img
+          src='https://nihr.widen.net/content/egucpu5vgs/jpeg/x-logo-black.jpeg'
           alt=''
           width='11'
           height='11'
           class='CToWUd'
           data-bit='iit'
         />
-        <a href='https://x.com/NIHRresearch' target='_blank' aria-label='NIHR X (formerly Twitter)'>NIHR X</a>&nbsp;|&nbsp;<img
-          src='https://www.nihr.ac.uk/images/about-us/stay-up-to-date/LI-In-Bug.png'
+        <a href='https://x.com/NIHRresearch' target='_blank' aria-label='NIHR X (formerly Twitter)'>NIHR X</a>
+        &nbsp;|&nbsp;
+        <!-- linkedin logo -->
+        <img 
+          src='https://nihr.widen.net/content/xc1gslcvmt/jpeg/li-in-bug.jpeg'
           alt=''
           width='11'
           height='9'
           class='CToWUd'
           data-bit='iit'
-        /><a href='https://www.linkedin.com/company/nihr-research' target='_blank'>NIHR LinkedIn</a>
-        |
+        />
+        <a href='https://www.linkedin.com/company/nihr-research' target='_blank'>NIHR LinkedIn</a>
+        &nbsp;|&nbsp;
+        <!-- youtube logo -->
         <img
-          src='https://www.nihr.ac.uk/images/about-us/stay-up-to-date/youtube_logo_rgb_light.png'
+          src='https://nihr.widen.net/content/52cd9uokcy/jpeg/youtube_logo_rgb_light.jpeg'
           alt=''
           width='11'
           height='9'
@@ -612,9 +592,10 @@ exports[`Email template "contact-removed.html.hbs" displays correctly 1`] = `
           data-bit='iit'
         />
         <a href='https://www.youtube.com/user/NIHRtv' target='_blank'>NIHR YouTube</a>
-        |
+        &nbsp;|&nbsp;
+        <!-- nihr link logo -->
         <img
-          src='https://www.nihr.ac.uk/layout/img/external/nihr-link-icon.png'
+          src='https://nihr.widen.net/content/5mhcdc6utg/jpeg/nihr-link-icon.jpeg'
           alt=''
           width='11'
           height='9'
@@ -652,3 +633,149 @@ If you think there’s been an error please contact supportmystudy@nihr.ac.uk.
 
 If you’re not sure why you’ve received this email or need to be removed from our list contact supportmystudy@nihr.ac.uk."
 `;
+
+exports[`Email template "invitation-email-unsuccessful.html.hbs" displays correctly 1`] = `
+"<html lang='en'>
+  <body>
+    <div>
+      <h1>
+        The invitation email you sent when adding a new contact to your organisation was not delivered successfully
+      </h1>
+
+      <p>Hello,</p>
+
+      <p>We are notifying you that your email sent to
+        test@test.nihr.ac.uk
+        was not delivered. This means the recipient's email address is likely invalid or unavailable at this time.
+      </p>
+
+      <p>Next steps:</p>
+
+      <p>Please login to the
+        <a href=''>Sponsor Engagement Tool</a>
+        and check you have used the correct email address. If it's incorrect, remove the contact, then re-add them.
+      </p>
+
+      <p>If you need further assistance please contact
+        <a href='mailto:supportmystudy@nihr.ac.uk'>supportmystudy@nihr.ac.uk</a>.</p>
+
+      <hr />
+
+      <p>
+        This email is not monitored, do not reply. If you’re not sure why you’ve received this email or need to be
+        removed from our list contact
+        <a href='mailto:supportmystudy@nihr.ac.uk'> supportmystudy@nihr.ac.uk</a>.
+      </p>
+
+    </div>
+
+    <br />
+
+    <div>
+      <table style='width: 540px; border-collapse: collapse'>
+        <tbody>
+          <tr>
+            <td style='width: 162px'>
+              <p>
+                &nbsp;<img
+                  src='https://nihr.widen.net/content/xazipspiv6/jpeg/nihr-logo.jpeg'
+                  alt=''
+                  width='206'
+                  class='CToWUd'
+                  data-bit='iit'
+                />
+              </p>
+            </td>
+          </tr>
+        </tbody>
+      </table>
+      <p>
+        Follow us:
+        <!-- facebook logo -->
+        <img
+          src='https://nihr.widen.net/content/aqo4dnubmf/jpeg/f_logo_rgb-blue_58.jpeg'
+          alt=''
+          width='11'
+          height='11'
+          class='CToWUd'
+          data-bit='iit'
+        />
+        <a href='https://www.facebook.com/OfficialNIHR' target='_blank'>NIHR Facebook</a>
+        &nbsp;|&nbsp;
+        <!-- twitter logo -->
+        <img
+          src='https://nihr.widen.net/content/egucpu5vgs/jpeg/x-logo-black.jpeg'
+          alt=''
+          width='11'
+          height='11'
+          class='CToWUd'
+          data-bit='iit'
+        />
+        <a href='https://x.com/NIHRresearch' target='_blank' aria-label='NIHR X (formerly Twitter)'>NIHR X</a>
+        &nbsp;|&nbsp;
+        <!-- linkedin logo -->
+        <img
+          src='https://nihr.widen.net/content/xc1gslcvmt/jpeg/li-in-bug.jpeg'
+          alt=''
+          width='11'
+          height='9'
+          class='CToWUd'
+          data-bit='iit'
+        />
+        <a href='https://www.linkedin.com/company/nihr-research' target='_blank'>NIHR LinkedIn</a>
+        &nbsp;|&nbsp;
+        <!-- youtube logo -->
+        <img
+          src='https://nihr.widen.net/content/52cd9uokcy/jpeg/youtube_logo_rgb_light.jpeg'
+          alt=''
+          width='11'
+          height='9'
+          class='CToWUd'
+          data-bit='iit'
+        />
+        <a href='https://www.youtube.com/user/NIHRtv' target='_blank'>NIHR YouTube</a>
+        &nbsp;|&nbsp;
+        <!-- nihr link logo -->
+        <img
+          src='https://nihr.widen.net/content/5mhcdc6utg/jpeg/nihr-link-icon.jpeg'
+          alt=''
+          width='11'
+          height='9'
+          class='CToWUd'
+          data-bit='iit'
+        />
+        <a
+          href='https://www.nihr.ac.uk/?utm_source=gmail&amp;utm_medium=email&amp;utm_campaign=ccsignature'
+          target='_blank'
+        >NIHR Website</a>
+      </p>
+      <br />
+      <br />
+      <p style='color: rgb(34, 34, 34); font-family: arial, sans-serif; background-color: rgb(255, 255, 255)'>
+        Confidential information may be contained in this message. If you are not the intended recipient, any reading,
+        printing, storage, disclosure, copying or any other action taken in respect of this e-mail is prohibited and may
+        be unlawful. If you are not the intended recipient, please notify the sender immediately by using the reply
+        function and then permanently delete what you have received.
+      </p>
+    </div>
+  </body>
+</html>"
+`;
+
+exports[`Email template "invitation-email-unsuccessful.text.hbs" displays correctly 1`] = `
+"# The invitation email you sent when adding a new contact to your organisation was not delivered successfully
+
+Hello,
+
+We are notifying you that your email sent to test@test.nihr.ac.uk was not delivered. 
+This means the recipient's email address is likely invalid or unavailable at this time.
+
+Next steps:
+
+Please login to the Sponsor Engagement Tool  () and check you have used the correct email address. If it's incorrect, remove the contact, then re-add them.
+
+If you need further assistance please contact supportmystudy@nihr.ac.uk.
+
+This email is not monitored, do not reply. If you’re not sure why you’ve received this email or need to be removed from
+our list contact supportmystudy@nihr.ac.uk."
+`;
diff --git a/packages/templates/sponsor-engagement/email/index.js b/packages/templates/sponsor-engagement/email/index.js
index e0a512587..b318e763d 100644
--- a/packages/templates/sponsor-engagement/email/index.js
+++ b/packages/templates/sponsor-engagement/email/index.js
@@ -1,615 +1,150 @@
-var handlebars = require('handlebars/runtime')
-var templates = {}
-templates['assessment-reminder.html.hbs'] = handlebars.template({
-  1: function (container, depth0, helpers, partials, data) {
-    return '            <li>' + container.escapeExpression(container.lambda(depth0, depth0)) + '</li>\n'
-  },
-  compiler: [8, '>= 4.3.0'],
-  main: function (container, depth0, helpers, partials, data) {
-    var stack1,
-      helper,
-      alias1 = depth0 != null ? depth0 : container.nullContext || {},
-      alias2 = container.hooks.helperMissing,
-      alias3 = 'function',
-      alias4 = container.escapeExpression,
-      lookupProperty =
-        container.lookupProperty ||
-        function (parent, propertyName) {
-          if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
-            return parent[propertyName]
-          }
-          return undefined
+var handlebars = require("handlebars/runtime"); var templates = {}
+templates['assessment-reminder.html.hbs'] = handlebars.template({"1":function(container,depth0,helpers,partials,data) {
+    return "            <li>"
+    + container.escapeExpression(container.lambda(depth0, depth0))
+    + "</li>\n";
+},"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
+    var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3="function", alias4=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
+        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
+          return parent[propertyName];
         }
+        return undefined
+    };
 
-    return (
-      "<html lang='en'>\n\n  <body>\n    <div>\n      <h1>NIHR RDN has invited you to assess the progress of your studies</h1>\n\n      <p style='font-size: 19px; font-weight:700; display: flex;'>\n        <img src='" +
-      alias4(
-        ((helper =
-          (helper =
-            lookupProperty(helpers, 'iconUrl') || (depth0 != null ? lookupProperty(depth0, 'iconUrl') : depth0)) != null
-            ? helper
-            : alias2),
-        typeof helper === alias3
-          ? helper.call(alias1, {
-              name: 'iconUrl',
-              hash: {},
-              data: data,
-              loc: { start: { line: 9, column: 18 }, end: { line: 9, column: 29 } },
-            })
-          : helper)
-      ) +
-      "' style='display:block; width: 35px; height: 35px;' />\n        <span style='margin-left: 10px; margin-top: 3px;'>There are one or more studies to assess</span>\n      </p>\n\n      <p>Hello,</p>\n\n      <p>You are a nominated contact for studies on the NIHR Research Delivery Network’s (RDN) research portfolio for:\n        <br />\n        <ul>\n" +
-      ((stack1 = lookupProperty(helpers, 'each').call(
-        alias1,
-        depth0 != null ? lookupProperty(depth0, 'organisationNames') : depth0,
-        {
-          name: 'each',
-          hash: {},
-          fn: container.program(1, data, 0),
-          inverse: container.noop,
-          data: data,
-          loc: { start: { line: 18, column: 10 }, end: { line: 20, column: 19 } },
+  return "<html lang='en'>\n\n  <body>\n    <div>\n      <h1>NIHR RDN has invited you to assess the progress of your studies</h1>\n\n      <p style='font-size: 19px; font-weight:700; display: flex;'>\n        <img src='"
+    + alias4(((helper = (helper = lookupProperty(helpers,"iconUrl") || (depth0 != null ? lookupProperty(depth0,"iconUrl") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"iconUrl","hash":{},"data":data,"loc":{"start":{"line":9,"column":18},"end":{"line":9,"column":29}}}) : helper)))
+    + "' style='display:block; width: 35px; height: 35px;' />\n        <span style='margin-left: 10px; margin-top: 3px;'>There are one or more studies to assess</span>\n      </p>\n\n      <p>Hello,</p>\n\n      <p>You are a nominated contact for studies on the NIHR Research Delivery Network’s (RDN) research portfolio for:\n        <br />\n        <ul>\n"
+    + ((stack1 = lookupProperty(helpers,"each").call(alias1,(depth0 != null ? lookupProperty(depth0,"organisationNames") : depth0),{"name":"each","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":18,"column":10},"end":{"line":20,"column":19}}})) != null ? stack1 : "")
+    + "        </ul>\n      </p>\n\n      <p>\n        One or more studies requires an update. Please sign in to the Sponsor Engagement Tool to provide these updates.\n      </p>\n\n      <p>As a nominated contact for your organisation, you will see all studies linked to your organisation. The Sponsor\n        Engagement Tool does not associate contacts to specific studies or groups of studies, only to the organisation.\n      </p>\n\n      <a\n        href='"
+    + alias4(((helper = (helper = lookupProperty(helpers,"signInLink") || (depth0 != null ? lookupProperty(depth0,"signInLink") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"signInLink","hash":{},"data":data,"loc":{"start":{"line":33,"column":14},"end":{"line":33,"column":28}}}) : helper)))
+    + "'\n        style='\n          box-sizing: border-box;\n          display: inline-block;\n          position: relative;\n          margin-top: 0;\n          margin-right: 0;\n          margin-left: 0;\n          margin-bottom: 22px;\n          padding: 8px 10px 7px;\n          border: 2px solid rgba(0, 0, 0, 0);\n          border-radius: 0;\n          color: #fff;\n          background-color: #00703c;\n          box-shadow: 0 2px 0 #002d18;\n          text-align: center;\n          vertical-align: top;\n          cursor: pointer;\n          -webkit-appearance: none;\n        '\n      >Sign in to assess studies</a>\n\n      <h2>Why am I being asked to assess studies?</h2>\n\n      <p>\n        The\n        <a href='"
+    + alias4(((helper = (helper = lookupProperty(helpers,"rdnLink") || (depth0 != null ? lookupProperty(depth0,"rdnLink") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"rdnLink","hash":{},"data":data,"loc":{"start":{"line":59,"column":17},"end":{"line":59,"column":28}}}) : helper)))
+    + "'>NIHR RDN</a>\n        supports Sponsors and their delegates to deliver high-quality research, for the benefit of patients, the public\n        and health and care organisations across England.\n      </p>\n\n      <p>\n        The NIHR RDN tracks the progress of research studies in its portfolio using data provided by Sponsors or their\n        delegates on behalf of the Department of Health and Social Care (DHSC).\n      </p>\n\n      <p>\n        For studies that have sites based in England, the DHSC have published the\n        <a href='"
+    + alias4(((helper = (helper = lookupProperty(helpers,"termsAndConditionsLink") || (depth0 != null ? lookupProperty(depth0,"termsAndConditionsLink") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"termsAndConditionsLink","hash":{},"data":data,"loc":{"start":{"line":71,"column":17},"end":{"line":71,"column":43}}}) : helper)))
+    + "'>Terms and Conditions for NIHR RDN support</a>, which outlines the\n        requirements for Sponsors to provide up-to-date study data and assessments of progress to the RDN.\n      </p>\n\n      <p>The Sponsor Engagement Tool has been designed to support Sponsors and their delegates to meet the requirements\n        outlined in the T&Cs. Sponsors and their delegates should use the Sponsor Engagement Tool to review the data the\n        RDN holds on their organisation’s portfolio of studies, to provide study data updates and assessments to ensure\n        the data held by the RDN is complete and up-to-date, and to manage contacts linked to their organisation.\n      </p>\n\n      <p>Sponsors or their delegates are prompted to review and assess the progress of studies when:</p>\n\n      <ul>\n        <li>A study falls behind a planned milestone or</li>\n        <li>A study appears to not be recruiting to target</li>\n        <li>And the last study assessment is over three months old</li>\n      </ul>\n\n      <p>\n        For studies that have sites based in England, Sponsors or their delegates can request\n        <a href='"
+    + alias4(((helper = (helper = lookupProperty(helpers,"requestSupportLink") || (depth0 != null ? lookupProperty(depth0,"requestSupportLink") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"requestSupportLink","hash":{},"data":data,"loc":{"start":{"line":91,"column":17},"end":{"line":91,"column":39}}}) : helper)))
+    + "'>NIHR RDN support</a>\n        with study delivery and performance at any time.\n      </p>\n\n      <p>\n        <strong>\n          Please note that providing regular study updates and assessments are requirements of the\n          <a href='"
+    + alias4(((helper = (helper = lookupProperty(helpers,"termsAndConditionsLink") || (depth0 != null ? lookupProperty(depth0,"termsAndConditionsLink") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"termsAndConditionsLink","hash":{},"data":data,"loc":{"start":{"line":98,"column":19},"end":{"line":98,"column":45}}}) : helper)))
+    + "'>Terms and Conditions for NIHR RDN support</a>. Failure to do so may\n          result in removal from the NIHR RDN Portfolio.\n        </strong>\n      </p>\n\n      <h2>Nominate someone else to assess research studies</h2>\n\n      <p>\n        You can give other people in your organisation access to this service by accessing the contacts section of the\n        Sponsor Engagement Tool. Within this section you can view all contacts linked to your organisation, add new\n        contacts, and remove any contacts who no longer need access to the service.\n      </p>\n\n      <hr />\n\n      <p>\n        This email is not monitored, do not reply. If you’re not sure why you’ve received this email or need to be\n        removed from our list\n        <a href='mailto:supportmystudy@nihr.ac.uk'>contact supportmystudy@nihr.ac.uk</a>.\n      </p>\n    </div>\n\n    <br />\n\n    <div>\n      <table style='width: 540px; border-collapse: collapse'>\n        <tbody>\n          <tr>\n            <td style='width: 162px'>\n              <p>\n                &nbsp;<img\n                  src='https://nihr.widen.net/content/xazipspiv6/jpeg/nihr-logo.jpeg'\n                  alt=''\n                  width='206'\n                  class='CToWUd'\n                  data-bit='iit'\n                />\n              </p>\n            </td>\n          </tr>\n        </tbody>\n      </table>\n      <p>\n        Follow us:\n        <!-- facebook logo -->\n        <img\n          src='https://nihr.widen.net/content/aqo4dnubmf/jpeg/f_logo_rgb-blue_58.jpeg'\n          alt=''\n          width='11'\n          height='11'\n          class='CToWUd'\n          data-bit='iit'\n        />\n        <a href='https://www.facebook.com/OfficialNIHR' target='_blank'>NIHR Facebook</a>\n        &nbsp;|&nbsp;\n        <!-- twitter logo -->\n        <img\n          src='https://nihr.widen.net/content/egucpu5vgs/jpeg/x-logo-black.jpeg'\n          alt=''\n          width='11'\n          height='11'\n          class='CToWUd'\n          data-bit='iit'\n        />\n        <a href='https://x.com/NIHRresearch' target='_blank' aria-label='NIHR X (formerly Twitter)'>NIHR X</a>\n        &nbsp;|&nbsp;\n        <!-- linkedin logo -->\n        <img\n          src='https://nihr.widen.net/content/xc1gslcvmt/jpeg/li-in-bug.jpeg'\n          alt=''\n          width='11'\n          height='9'\n          class='CToWUd'\n          data-bit='iit'\n        />\n        <a href='https://www.linkedin.com/company/nihr-research' target='_blank'>NIHR LinkedIn</a>\n        &nbsp;|&nbsp;\n        <!-- youtube logo -->\n        <img\n          src='https://nihr.widen.net/content/52cd9uokcy/jpeg/youtube_logo_rgb_light.jpeg'\n          alt=''\n          width='11'\n          height='9'\n          class='CToWUd'\n          data-bit='iit'\n        />\n        <a href='https://www.youtube.com/user/NIHRtv' target='_blank'>NIHR YouTube</a>\n        &nbsp;|&nbsp;\n        <!-- nihr link logo -->\n        <img\n          src='https://nihr.widen.net/content/5mhcdc6utg/jpeg/nihr-link-icon.jpeg'\n          alt=''\n          width='11'\n          height='9'\n          class='CToWUd'\n          data-bit='iit'\n        />\n        <a\n          href='https://www.nihr.ac.uk/?utm_source=gmail&amp;utm_medium=email&amp;utm_campaign=ccsignature'\n          target='_blank'\n        >NIHR Website</a>\n      </p>\n      <br />\n      <br />\n      <p style='color: rgb(34, 34, 34); font-family: arial, sans-serif; background-color: rgb(255, 255, 255)'>\n        Confidential information may be contained in this message. If you are not the intended recipient, any reading,\n        printing, storage, disclosure, copying or any other action taken in respect of this e-mail is prohibited and may\n        be unlawful. If you are not the intended recipient, please notify the sender immediately by using the reply\n        function and then permanently delete what you have received.\n      </p>\n    </div>\n  </body>\n\n</html>";
+},"useData":true})
+templates['assessment-reminder.text.hbs'] = handlebars.template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
+    var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3="function", alias4=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
+        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
+          return parent[propertyName];
         }
-      )) != null
-        ? stack1
-        : '') +
-      "        </ul>\n      </p>\n\n      <p>\n        One or more studies requires an update. Please sign in to the Sponsor Engagement Tool to provide these updates.\n      </p>\n\n      <p>As a nominated contact for your organisation, you will see all studies linked to your organisation. The Sponsor\n        Engagement Tool does not associate contacts to specific studies or groups of studies, only to the organisation.\n      </p>\n\n      <a\n        href='" +
-      alias4(
-        ((helper =
-          (helper =
-            lookupProperty(helpers, 'signInLink') ||
-            (depth0 != null ? lookupProperty(depth0, 'signInLink') : depth0)) != null
-            ? helper
-            : alias2),
-        typeof helper === alias3
-          ? helper.call(alias1, {
-              name: 'signInLink',
-              hash: {},
-              data: data,
-              loc: { start: { line: 33, column: 14 }, end: { line: 33, column: 28 } },
-            })
-          : helper)
-      ) +
-      "'\n        style='\n          box-sizing: border-box;\n          display: inline-block;\n          position: relative;\n          margin-top: 0;\n          margin-right: 0;\n          margin-left: 0;\n          margin-bottom: 22px;\n          padding: 8px 10px 7px;\n          border: 2px solid rgba(0, 0, 0, 0);\n          border-radius: 0;\n          color: #fff;\n          background-color: #00703c;\n          box-shadow: 0 2px 0 #002d18;\n          text-align: center;\n          vertical-align: top;\n          cursor: pointer;\n          -webkit-appearance: none;\n        '\n      >Sign in to assess studies</a>\n\n      <h2>Why am I being asked to assess studies?</h2>\n\n      <p>\n        The\n        <a href='" +
-      alias4(
-        ((helper =
-          (helper =
-            lookupProperty(helpers, 'rdnLink') || (depth0 != null ? lookupProperty(depth0, 'rdnLink') : depth0)) != null
-            ? helper
-            : alias2),
-        typeof helper === alias3
-          ? helper.call(alias1, {
-              name: 'rdnLink',
-              hash: {},
-              data: data,
-              loc: { start: { line: 59, column: 17 }, end: { line: 59, column: 28 } },
-            })
-          : helper)
-      ) +
-      "'>NIHR RDN</a>\n        supports Sponsors and their delegates to deliver high-quality research, for the benefit of patients, the public\n        and health and care organisations across England.\n      </p>\n\n      <p>\n        The NIHR RDN tracks the progress of research studies in its portfolio using data provided by Sponsors or their\n        delegates on behalf of the Department of Health and Social Care (DHSC).\n      </p>\n\n      <p>\n        For studies that have sites based in England, the DHSC have published the\n        <a href='" +
-      alias4(
-        ((helper =
-          (helper =
-            lookupProperty(helpers, 'termsAndConditionsLink') ||
-            (depth0 != null ? lookupProperty(depth0, 'termsAndConditionsLink') : depth0)) != null
-            ? helper
-            : alias2),
-        typeof helper === alias3
-          ? helper.call(alias1, {
-              name: 'termsAndConditionsLink',
-              hash: {},
-              data: data,
-              loc: { start: { line: 71, column: 17 }, end: { line: 71, column: 43 } },
-            })
-          : helper)
-      ) +
-      "'>Terms and Conditions for NIHR RDN support</a>, which outlines the\n        requirements for Sponsors to provide up-to-date study data and assessments of progress to the RDN.\n      </p>\n\n      <p>The Sponsor Engagement Tool has been designed to support Sponsors and their delegates to meet the requirements\n        outlined in the T&Cs. Sponsors and their delegates should use the Sponsor Engagement Tool to review the data the\n        RDN holds on their organisation’s portfolio of studies, to provide study data updates and assessments to ensure\n        the data held by the RDN is complete and up-to-date, and to manage contacts linked to their organisation.\n      </p>\n\n      <p>Sponsors or their delegates are prompted to review and assess the progress of studies when:</p>\n\n      <ul>\n        <li>A study falls behind a planned milestone or</li>\n        <li>A study appears to not be recruiting to target</li>\n        <li>And the last study assessment is over three months old</li>\n      </ul>\n\n      <p>\n        For studies that have sites based in England, Sponsors or their delegates can request\n        <a href='" +
-      alias4(
-        ((helper =
-          (helper =
-            lookupProperty(helpers, 'requestSupportLink') ||
-            (depth0 != null ? lookupProperty(depth0, 'requestSupportLink') : depth0)) != null
-            ? helper
-            : alias2),
-        typeof helper === alias3
-          ? helper.call(alias1, {
-              name: 'requestSupportLink',
-              hash: {},
-              data: data,
-              loc: { start: { line: 91, column: 17 }, end: { line: 91, column: 39 } },
-            })
-          : helper)
-      ) +
-      "'>NIHR RDN support</a>\n        with study delivery and performance at any time.\n      </p>\n\n      <p>\n        <strong>\n          Please note that providing regular study updates and assessments are requirements of the\n          <a href='" +
-      alias4(
-        ((helper =
-          (helper =
-            lookupProperty(helpers, 'termsAndConditionsLink') ||
-            (depth0 != null ? lookupProperty(depth0, 'termsAndConditionsLink') : depth0)) != null
-            ? helper
-            : alias2),
-        typeof helper === alias3
-          ? helper.call(alias1, {
-              name: 'termsAndConditionsLink',
-              hash: {},
-              data: data,
-              loc: { start: { line: 98, column: 19 }, end: { line: 98, column: 45 } },
-            })
-          : helper)
-      ) +
-      "'>Terms and Conditions for NIHR RDN support</a>. Failure to do so may\n          result in removal from the NIHR RDN Portfolio.\n        </strong>\n      </p>\n\n      <h2>Nominate someone else to assess research studies</h2>\n\n      <p>\n        You can give other people in your organisation access to this service by accessing the contacts section of the\n        Sponsor Engagement Tool. Within this section you can view all contacts linked to your organisation, add new\n        contacts, and remove any contacts who no longer need access to the service.\n      </p>\n\n      <hr />\n\n      <p>\n        This email is not monitored, do not reply. If you’re not sure why you’ve received this email or need to be\n        removed from our list\n        <a href='mailto:supportmystudy@nihr.ac.uk'>contact supportmystudy@nihr.ac.uk</a>.\n      </p>\n    </div>\n\n    <br />\n\n    <div>\n      <table style='width: 540px; border-collapse: collapse'>\n        <tbody>\n          <tr>\n            <td style='width: 162px'>\n              <p>\n                &nbsp;<img\n                  src='https://www.nihr.ac.uk/layout/4.0/assets/external/nihr-logo.png'\n                  alt=''\n                  width='206'\n                  class='CToWUd'\n                  data-bit='iit'\n                />\n              </p>\n            </td>\n          </tr>\n        </tbody>\n      </table>\n\n      <p>\n        <a\n          href='https://www.nihr.ac.uk/explore-nihr/campaigns/nhs-75/?utm_source=gmail&amp;utm_medium=email&amp;utm_campaign=nhs75&amp;utm_term=signature&amp;utm_content=signature'\n          target='_blank'\n        ><img\n            src='https://www.nihr.ac.uk/layout/img/external/nhs75-shape-the-future-signature.png'\n            alt='NIHR, Supporting NHS75. Life changing research funded by the public. Click, get involved in our NHS75 campaign'\n            width='540'\n            height='101'\n            class='CToWUd'\n            data-bit='iit'\n          />\n        </a>\n      </p>\n\n      <p>\n        Follow us:\n        <img\n          src='https://www.nihr.ac.uk/images/about-us/stay-up-to-date/f_logo_RGB-Blue_58.png'\n          alt=''\n          width='11'\n          height='11'\n          class='CToWUd'\n          data-bit='iit'\n        />\n        <a href='https://www.facebook.com/OfficialNIHR' target='_blank'>NIHR Facebook</a>&nbsp;|&nbsp;<img\n          src='https://www.nihr.ac.uk/images/about-us/stay-up-to-date/Twitter_Logo_Blue.png'\n          alt=''\n          width='11'\n          height='11'\n          class='CToWUd'\n          data-bit='iit'\n        />\n        <a href='https://x.com/NIHRresearch' target='_blank' aria-label='NIHR X (formerly Twitter)'>NIHR X</a>&nbsp;|&nbsp;<img\n          src='https://www.nihr.ac.uk/images/about-us/stay-up-to-date/LI-In-Bug.png'\n          alt=''\n          width='11'\n          height='9'\n          class='CToWUd'\n          data-bit='iit'\n        /><a href='https://www.linkedin.com/company/nihr-research' target='_blank'>NIHR LinkedIn</a>\n        |\n        <img\n          src='https://www.nihr.ac.uk/images/about-us/stay-up-to-date/youtube_logo_rgb_light.png'\n          alt=''\n          width='11'\n          height='9'\n          class='CToWUd'\n          data-bit='iit'\n        />\n        <a href='https://www.youtube.com/user/NIHRtv' target='_blank'>NIHR YouTube</a>\n        |\n        <img\n          src='https://www.nihr.ac.uk/layout/img/external/nihr-link-icon.png'\n          alt=''\n          width='11'\n          height='9'\n          class='CToWUd'\n          data-bit='iit'\n        />\n        <a\n          href='https://www.nihr.ac.uk/?utm_source=gmail&amp;utm_medium=email&amp;utm_campaign=ccsignature'\n          target='_blank'\n        >NIHR Website</a>\n      </p>\n      <br />\n      <br />\n      <p style='color: rgb(34, 34, 34); font-family: arial, sans-serif; background-color: rgb(255, 255, 255)'>\n        Confidential information may be contained in this message. If you are not the intended recipient, any reading,\n        printing, storage, disclosure, copying or any other action taken in respect of this e-mail is prohibited and may\n        be unlawful. If you are not the intended recipient, please notify the sender immediately by using the reply\n        function and then permanently delete what you have received.\n      </p>\n    </div>\n  </body>\n\n</html>"
-    )
-  },
-  useData: true,
-})
-templates['assessment-reminder.text.hbs'] = handlebars.template({
-  compiler: [8, '>= 4.3.0'],
-  main: function (container, depth0, helpers, partials, data) {
-    var helper,
-      alias1 = depth0 != null ? depth0 : container.nullContext || {},
-      alias2 = container.hooks.helperMissing,
-      alias3 = 'function',
-      alias4 = container.escapeExpression,
-      lookupProperty =
-        container.lookupProperty ||
-        function (parent, propertyName) {
-          if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
-            return parent[propertyName]
-          }
-          return undefined
+        return undefined
+    };
+
+  return "# Assess progress of research studies in NIHR RDN portfolio\n\nThere are one or more studies to assess\n\nSign-in ["
+    + alias4(((helper = (helper = lookupProperty(helpers,"signInLink") || (depth0 != null ? lookupProperty(depth0,"signInLink") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"signInLink","hash":{},"data":data,"loc":{"start":{"line":5,"column":9},"end":{"line":5,"column":23}}}) : helper)))
+    + "]\n\nHello,\n\nYou are a nominated contact for "
+    + alias4(((helper = (helper = lookupProperty(helpers,"organisationNames") || (depth0 != null ? lookupProperty(depth0,"organisationNames") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"organisationNames","hash":{},"data":data,"loc":{"start":{"line":9,"column":32},"end":{"line":9,"column":53}}}) : helper)))
+    + " for studies on the NIHR Research Delivery Network’s (RDN) research portfolio. One\nor more studies require an update. Please sign in to the Sponsor Engagement Tool to provide these updates.\n\nAs a nominated contact for your organisation, you will see all studies linked to your organisation. The Sponsor Engagement Tool\ndoes not associate contacts to specific studies or groups of studies, only to the organisation.\n\n# Why am I being asked to assess studies?\n\nThe NIHR RDN ["
+    + alias4(((helper = (helper = lookupProperty(helpers,"rdnLink") || (depth0 != null ? lookupProperty(depth0,"rdnLink") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"rdnLink","hash":{},"data":data,"loc":{"start":{"line":17,"column":14},"end":{"line":17,"column":25}}}) : helper)))
+    + "] supports Sponsors and their delegates to deliver high-quality research, for the benefit of\npatients, the public and health and care organisations across England.\n\nThe NIHR RDN tracks the progress of research studies in its portfolio using data provided by Sponsors or their delegates\non behalf of the Department of Health and Social Care (DHSC).\n\nThe DHSC have published the Terms and Conditions for NIHR RDN support ["
+    + alias4(((helper = (helper = lookupProperty(helpers,"termsAndConditionsLink") || (depth0 != null ? lookupProperty(depth0,"termsAndConditionsLink") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"termsAndConditionsLink","hash":{},"data":data,"loc":{"start":{"line":23,"column":71},"end":{"line":23,"column":97}}}) : helper)))
+    + "], which outlines the requirements for Sponsors to provide up-to-date study data and assessments of progress to the RDN.\n\nThe Sponsor Engagement Tool has been designed to support Sponsors and their delegates to meet the requirements outlined in \nthe T&Cs. Sponsors and their delegates should use the Sponsor Engagement Tool to review the data the RDN holds on their organisation’s portfolio of studies, \nto provide study data updates and assessments to ensure the data held by the RDN is complete and up-to-date, and to manage contacts linked to their organisation.\n\nSponsors or their delegates are prompted to review and assess the progress of studies when:\n\n- A study falls behind a planned milestone or\n- A study appears to not be recruiting to target\n- And the last study assessment is over three months old\n\nFor studies that have sites based in England, Sponsors or their delegates can request NIHR RDN support with study delivery and performance at any time. ["
+    + alias4(((helper = (helper = lookupProperty(helpers,"requestSupportLink") || (depth0 != null ? lookupProperty(depth0,"requestSupportLink") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"requestSupportLink","hash":{},"data":data,"loc":{"start":{"line":35,"column":153},"end":{"line":35,"column":175}}}) : helper)))
+    + "]\n\nPlease note that providing regular study updates and assessments are requirements of the Terms and Conditions for NIHR RDN support\n["
+    + alias4(((helper = (helper = lookupProperty(helpers,"termsAndConditionsLink") || (depth0 != null ? lookupProperty(depth0,"termsAndConditionsLink") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"termsAndConditionsLink","hash":{},"data":data,"loc":{"start":{"line":38,"column":1},"end":{"line":38,"column":27}}}) : helper)))
+    + "]. Failure to do so may result in removal from the NIHR RDN Portfolio.\n\n# Nominate someone else to assess research studies\n\nYou can give other people in your organisation access to this service by accessing the contacts section of the Sponsor Engagement Tool. \nWithin this section you can view all contacts linked to your organisation, add new contacts, and remove any contacts who no longer need access to the service.\n\nThis email is not monitored, do not reply. If you’re not sure why you’ve received this email or need to be removed from\nour list contact supportmystudy@nihr.ac.uk.";
+},"useData":true})
+templates['contact-assigned.html.hbs'] = handlebars.template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
+    var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3="function", alias4=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
+        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
+          return parent[propertyName];
+        }
+        return undefined
+    };
+
+  return "<html lang='en'>\n\n  <body>\n    <div>\n      <h1>NIHR RDN has invited you to assess the progress of your studies</h1>\n\n      <p>Hello,</p>\n\n      <p>\n        You have been nominated as a contact for\n        "
+    + alias4(((helper = (helper = lookupProperty(helpers,"organisationName") || (depth0 != null ? lookupProperty(depth0,"organisationName") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"organisationName","hash":{},"data":data,"loc":{"start":{"line":12,"column":8},"end":{"line":12,"column":28}}}) : helper)))
+    + "\n        on the NIHR Research Delivery Network’s (RDN) research portfolio.\n      </p>\n\n      <p>\n        The\n        <a href='"
+    + alias4(((helper = (helper = lookupProperty(helpers,"rdnLink") || (depth0 != null ? lookupProperty(depth0,"rdnLink") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"rdnLink","hash":{},"data":data,"loc":{"start":{"line":18,"column":17},"end":{"line":18,"column":28}}}) : helper)))
+    + "'>NIHR RDN</a>\n        supports Sponsors and their delegates to deliver high-quality research, for the benefit of patients, the public\n        and health and care organisations across England.\n      </p>\n\n      <p>\n        The NIHR RDN tracks the progress of research studies in its portfolio using data provided by Sponsors or their\n        delegates on behalf of the Department of Health and Social Care (DHSC).\n      </p>\n\n      <p>\n        The DHSC have published the\n        <a href='"
+    + alias4(((helper = (helper = lookupProperty(helpers,"termsAndConditionsLink") || (depth0 != null ? lookupProperty(depth0,"termsAndConditionsLink") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"termsAndConditionsLink","hash":{},"data":data,"loc":{"start":{"line":30,"column":17},"end":{"line":30,"column":43}}}) : helper)))
+    + "'>Terms and Conditions for NIHR RDN support</a>, which outlines the requirements for Sponsors to provide up-to-date study data and assessments of progress to the RDN.\n      </p>\n\n      <p>\n        The Sponsor Engagement Tool has been designed to support Sponsors and their delegates to meet the requirements\n        outlined in the T&Cs. Sponsors and their delegates should use the Sponsor Engagement Tool to review the data the\n        RDN holds on their organisation's portfolio of studies and to provide study data updates and assessments to ensure\n        the data held by the RDN is complete and up-to-date.\n      </p>\n\n      <p>\n        Please sign in to the Sponsor Engagement Tool to provide updates on studies.\n      </p>\n\n      <a\n        href='"
+    + alias4(((helper = (helper = lookupProperty(helpers,"signInLink") || (depth0 != null ? lookupProperty(depth0,"signInLink") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"signInLink","hash":{},"data":data,"loc":{"start":{"line":45,"column":14},"end":{"line":45,"column":28}}}) : helper)))
+    + "'\n        style='\n          box-sizing: border-box;\n          display: inline-block;\n          position: relative;\n          margin-top: 0;\n          margin-right: 0;\n          margin-left: 0;\n          margin-bottom: 22px;\n          padding: 8px 10px 7px;\n          border: 2px solid rgba(0, 0, 0, 0);\n          border-radius: 0;\n          color: #fff;\n          background-color: #00703c;\n          box-shadow: 0 2px 0 #002d18;\n          text-align: center;\n          vertical-align: top;\n          cursor: pointer;\n          -webkit-appearance: none;\n        '\n      >Sign in to assess studies</a>\n\n      <h2>Why am I being asked to assess studies?</h2>\n\n      <p>Sponsors or their delegates are asked to review and assess the progress of studies when:</p>\n\n      <ul>\n        <li>A study falls behind a planned milestone or</li>\n        <li> A study appears to not be recruiting to target</li>\n        <li> And the last study assessment is over three months old</li>\n      </ul>\n\n      <p>\n        Sponsors or their delegates can request\n        <a href='"
+    + alias4(((helper = (helper = lookupProperty(helpers,"requestSupportLink") || (depth0 != null ? lookupProperty(depth0,"requestSupportLink") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"requestSupportLink","hash":{},"data":data,"loc":{"start":{"line":79,"column":17},"end":{"line":79,"column":39}}}) : helper)))
+    + "'>NIHR RDN support</a>\n        with study delivery and performance at any time.\n      </p>\n\n      <p>\n        <strong>\n          Please note that providing regular study data updates and assessments are requirements of the\n          <a href='"
+    + alias4(((helper = (helper = lookupProperty(helpers,"termsAndConditionsLink") || (depth0 != null ? lookupProperty(depth0,"termsAndConditionsLink") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"termsAndConditionsLink","hash":{},"data":data,"loc":{"start":{"line":86,"column":19},"end":{"line":86,"column":45}}}) : helper)))
+    + "'>Terms and Conditions for NIHR RDN support</a>. Failure to do so may\n          result in removal from the NIHR RDN Portfolio.\n        </strong>\n      </p>\n\n      <h2>Nominate someone else to assess studies</h2>\n\n      <p>\n        The NIHR RDN can give other people in your organisation access to this service.\n        <a href='mailto:supportmystudy@nihr.ac.uk'>Contact supportmystudy@nihr.ac.uk</a>\n        to add a new contact.\n      </p>\n\n      <hr />\n\n      <p>\n        This email is not monitored, do not reply. If you’re not sure why you’ve received this email or need to be\n        removed from our list\n        <a href='mailto:supportmystudy@nihr.ac.uk'>contact supportmystudy@nihr.ac.uk</a>.\n      </p>\n    </div>\n\n    <br />\n\n    <div>\n      <table style='width: 540px; border-collapse: collapse'>\n        <tbody>\n          <tr>\n            <td style='width: 162px'>\n              <p>\n                &nbsp;<img\n                  src='https://nihr.widen.net/content/xazipspiv6/jpeg/nihr-logo.jpeg'\n                  alt=''\n                  width='206'\n                  class='CToWUd'\n                  data-bit='iit'\n                />\n              </p>\n            </td>\n          </tr>\n        </tbody>\n      </table>\n      <p>\n        Follow us:\n        <!-- facebook logo -->\n        <img\n          src='https://nihr.widen.net/content/aqo4dnubmf/jpeg/f_logo_rgb-blue_58.jpeg'\n          alt=''\n          width='11'\n          height='11'\n          class='CToWUd'\n          data-bit='iit'\n        />\n        <a href='https://www.facebook.com/OfficialNIHR' target='_blank'>NIHR Facebook</a>\n        &nbsp;|&nbsp;\n        <!-- twitter logo -->\n        <img\n          src='https://nihr.widen.net/content/egucpu5vgs/jpeg/x-logo-black.jpeg'\n          alt=''\n          width='11'\n          height='11'\n          class='CToWUd'\n          data-bit='iit'\n        />\n        <a href='https://x.com/NIHRresearch' target='_blank' aria-label='NIHR X (formerly Twitter)'>NIHR X</a>\n        &nbsp;|&nbsp;\n        <!-- linkedin logo -->\n        <img \n          src='https://nihr.widen.net/content/xc1gslcvmt/jpeg/li-in-bug.jpeg'\n          alt=''\n          width='11'\n          height='9'\n          class='CToWUd'\n          data-bit='iit'\n        />\n        <a href='https://www.linkedin.com/company/nihr-research' target='_blank'>NIHR LinkedIn</a>\n        &nbsp;|&nbsp;\n        <!-- youtube logo -->\n        <img\n          src='https://nihr.widen.net/content/52cd9uokcy/jpeg/youtube_logo_rgb_light.jpeg'\n          alt=''\n          width='11'\n          height='9'\n          class='CToWUd'\n          data-bit='iit'\n        />\n        <a href='https://www.youtube.com/user/NIHRtv' target='_blank'>NIHR YouTube</a>\n        &nbsp;|&nbsp;\n        <!-- nihr link logo -->\n        <img\n          src='https://nihr.widen.net/content/5mhcdc6utg/jpeg/nihr-link-icon.jpeg'\n          alt=''\n          width='11'\n          height='9'\n          class='CToWUd'\n          data-bit='iit'\n        />\n        <a\n          href='https://www.nihr.ac.uk/?utm_source=gmail&amp;utm_medium=email&amp;utm_campaign=ccsignature'\n          target='_blank'\n        >NIHR Website</a>\n      </p>\n      <br />\n      <br />\n      <p style='color: rgb(34, 34, 34); font-family: arial, sans-serif; background-color: rgb(255, 255, 255)'>\n        Confidential information may be contained in this message. If you are not the intended recipient, any reading,\n        printing, storage, disclosure, copying or any other action taken in respect of this e-mail is prohibited and may\n        be unlawful. If you are not the intended recipient, please notify the sender immediately by using the reply\n        function and then permanently delete what you have received.\n      </p>\n    </div>\n  </body>\n\n</html>";
+},"useData":true})
+templates['contact-assigned.text.hbs'] = handlebars.template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
+    var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3="function", alias4=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
+        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
+          return parent[propertyName];
         }
+        return undefined
+    };
 
-    return (
-      '# Assess progress of research studies in NIHR RDN portfolio\n\nThere are one or more studies to assess\n\nSign-in [' +
-      alias4(
-        ((helper =
-          (helper =
-            lookupProperty(helpers, 'signInLink') ||
-            (depth0 != null ? lookupProperty(depth0, 'signInLink') : depth0)) != null
-            ? helper
-            : alias2),
-        typeof helper === alias3
-          ? helper.call(alias1, {
-              name: 'signInLink',
-              hash: {},
-              data: data,
-              loc: { start: { line: 5, column: 9 }, end: { line: 5, column: 23 } },
-            })
-          : helper)
-      ) +
-      ']\n\nHello,\n\nYou are a nominated contact for ' +
-      alias4(
-        ((helper =
-          (helper =
-            lookupProperty(helpers, 'organisationNames') ||
-            (depth0 != null ? lookupProperty(depth0, 'organisationNames') : depth0)) != null
-            ? helper
-            : alias2),
-        typeof helper === alias3
-          ? helper.call(alias1, {
-              name: 'organisationNames',
-              hash: {},
-              data: data,
-              loc: { start: { line: 9, column: 32 }, end: { line: 9, column: 53 } },
-            })
-          : helper)
-      ) +
-      ' for studies on the NIHR Research Delivery Network’s (RDN) research portfolio. One\nor more studies require an update. Please sign in to the Sponsor Engagement Tool to provide these updates.\n\nAs a nominated contact for your organisation, you will see all studies linked to your organisation. The Sponsor Engagement Tool\ndoes not associate contacts to specific studies or groups of studies, only to the organisation.\n\n# Why am I being asked to assess studies?\n\nThe NIHR RDN [' +
-      alias4(
-        ((helper =
-          (helper =
-            lookupProperty(helpers, 'rdnLink') || (depth0 != null ? lookupProperty(depth0, 'rdnLink') : depth0)) != null
-            ? helper
-            : alias2),
-        typeof helper === alias3
-          ? helper.call(alias1, {
-              name: 'rdnLink',
-              hash: {},
-              data: data,
-              loc: { start: { line: 17, column: 14 }, end: { line: 17, column: 25 } },
-            })
-          : helper)
-      ) +
-      '] supports Sponsors and their delegates to deliver high-quality research, for the benefit of\npatients, the public and health and care organisations across England.\n\nThe NIHR RDN tracks the progress of research studies in its portfolio using data provided by Sponsors or their delegates\non behalf of the Department of Health and Social Care (DHSC).\n\nThe DHSC have published the Terms and Conditions for NIHR RDN support [' +
-      alias4(
-        ((helper =
-          (helper =
-            lookupProperty(helpers, 'termsAndConditionsLink') ||
-            (depth0 != null ? lookupProperty(depth0, 'termsAndConditionsLink') : depth0)) != null
-            ? helper
-            : alias2),
-        typeof helper === alias3
-          ? helper.call(alias1, {
-              name: 'termsAndConditionsLink',
-              hash: {},
-              data: data,
-              loc: { start: { line: 23, column: 71 }, end: { line: 23, column: 97 } },
-            })
-          : helper)
-      ) +
-      '], which outlines \nthe requirements for Sponsors to provide up-to-date study data and assessments of progress to the RDN. \n\nThe Sponsor Engagement Tool has been designed to support Sponsors and their delegates to meet the requirements outlined in \nthe T&Cs. Sponsors and their delegates should use the Sponsor Engagement Tool to review the data the RDN holds on their organisation’s portfolio of studies, \nto provide study data updates and assessments to ensure the data held by the RDN is complete and up-to-date, and to manage contacts linked to their organisation.\n\nSponsors or their delegates are prompted to review and assess the progress of studies when:\n\n- A study falls behind a planned milestone or\n- A study appears to not be recruiting to target\n- And the last study assessment is over three months old\n\nFor studies that have sites based in England, Sponsors or their delegates can request NIHR RDN support with study delivery and performance at any time. [' +
-      alias4(
-        ((helper =
-          (helper =
-            lookupProperty(helpers, 'requestSupportLink') ||
-            (depth0 != null ? lookupProperty(depth0, 'requestSupportLink') : depth0)) != null
-            ? helper
-            : alias2),
-        typeof helper === alias3
-          ? helper.call(alias1, {
-              name: 'requestSupportLink',
-              hash: {},
-              data: data,
-              loc: { start: { line: 36, column: 153 }, end: { line: 36, column: 175 } },
-            })
-          : helper)
-      ) +
-      ']\n\nPlease note that providing regular study updates and assessments are requirements of the Terms and Conditions for NIHR RDN support\n[' +
-      alias4(
-        ((helper =
-          (helper =
-            lookupProperty(helpers, 'termsAndConditionsLink') ||
-            (depth0 != null ? lookupProperty(depth0, 'termsAndConditionsLink') : depth0)) != null
-            ? helper
-            : alias2),
-        typeof helper === alias3
-          ? helper.call(alias1, {
-              name: 'termsAndConditionsLink',
-              hash: {},
-              data: data,
-              loc: { start: { line: 38, column: 1 }, end: { line: 38, column: 27 } },
-            })
-          : helper)
-      ) +
-      ']. Failure to do so may result in removal from the NIHR RDN Portfolio.\n\n# Nominate someone else to assess research studies\n\nYou can give other people in your organisation access to this service by accessing the contacts section of the Sponsor Engagement Tool. \nWithin this section you can view all contacts linked to your organisation, add new contacts, and remove any contacts who no longer need access to the service.\n\nThis email is not monitored, do not reply. If you’re not sure why you’ve received this email or need to be removed from\nour list contact supportmystudy@nihr.ac.uk.'
-    )
-  },
-  useData: true,
-})
-templates['contact-assigned.html.hbs'] = handlebars.template({
-  compiler: [8, '>= 4.3.0'],
-  main: function (container, depth0, helpers, partials, data) {
-    var helper,
-      alias1 = depth0 != null ? depth0 : container.nullContext || {},
-      alias2 = container.hooks.helperMissing,
-      alias3 = 'function',
-      alias4 = container.escapeExpression,
-      lookupProperty =
-        container.lookupProperty ||
-        function (parent, propertyName) {
-          if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
-            return parent[propertyName]
-          }
-          return undefined
+  return "# NIHR RDN has invited you to assess the progress of your studies\n\nHello,\n\nYou have been nominated as a contact for "
+    + alias4(((helper = (helper = lookupProperty(helpers,"organisationName") || (depth0 != null ? lookupProperty(depth0,"organisationName") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"organisationName","hash":{},"data":data,"loc":{"start":{"line":5,"column":41},"end":{"line":5,"column":61}}}) : helper)))
+    + " studies on the NIHR Research Delivery Network's (RDN) research portfolio.\n\nThe NIHR RDN supports Sponsors and their delegates to deliver high-quality research, for the benefit of patients, the public and health and care organisations across England.\n\nThe NIHR RDN tracks the progress of research studies in its portfolio using data provided by Sponsors or their delegates on behalf of the Department of Health and Social Care (DHSC).\n\nThe DHSC have published the Terms and Conditions for NIHR RDN support ("
+    + alias4(((helper = (helper = lookupProperty(helpers,"termsAndConditionsLink") || (depth0 != null ? lookupProperty(depth0,"termsAndConditionsLink") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"termsAndConditionsLink","hash":{},"data":data,"loc":{"start":{"line":11,"column":71},"end":{"line":11,"column":97}}}) : helper)))
+    + "), which outlines the requirements for Sponsors to provide up-to-date study data and assessments of progress to the RDN.\n\nThe Sponsor Engagement Tool has been designed to support Sponsors and their delegates to meet the requirements outlined in the T&Cs. \nSponsors and their delegates should use the Sponsor Engagement Tool to review the data the RDN holds on their organisation’s portfolio \nof studies and to provide study data updates and assessments to ensure the data held by the RDN is complete and up-to-date.\n\nPlease sign in to the Sponsor Engagement Tool to provide updates on studies. ("
+    + alias4(((helper = (helper = lookupProperty(helpers,"signInLink") || (depth0 != null ? lookupProperty(depth0,"signInLink") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"signInLink","hash":{},"data":data,"loc":{"start":{"line":17,"column":78},"end":{"line":17,"column":92}}}) : helper)))
+    + ")\n\n# Why am I being asked to assess studies?\n\nSponsors or their delegates are asked to review and assess the progress of studies when:\n\n- A study falls behind a planned milestone or\n- A study appears to not be recruiting to target\n- And the last study assessment is over three months old\n\nSponsors or their delegates can request NIHR RDN support with study delivery and performance at any time. ("
+    + alias4(((helper = (helper = lookupProperty(helpers,"requestSupportLink") || (depth0 != null ? lookupProperty(depth0,"requestSupportLink") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"requestSupportLink","hash":{},"data":data,"loc":{"start":{"line":27,"column":107},"end":{"line":27,"column":129}}}) : helper)))
+    + ")\n\nPlease note that providing regular study data updates and assessments are requirements of the Terms and Conditions for NIHR RDN support. \nFailure to do so may result in removal from the NIHR RDN Portfolio.("
+    + alias4(((helper = (helper = lookupProperty(helpers,"termsAndConditionsLink") || (depth0 != null ? lookupProperty(depth0,"termsAndConditionsLink") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"termsAndConditionsLink","hash":{},"data":data,"loc":{"start":{"line":30,"column":68},"end":{"line":30,"column":94}}}) : helper)))
+    + ")\n\n# Nominate someone else to assess studies\n\nThe NIHR RDN can give other people in your organisation access to this service. Contact supportmystudy@nihr.ac.uk to add\na new contact.\n\nThis email is not monitored, do not reply. If you’re not sure why you’ve received this email or need to be removed from\nour list, please contact supportmystudy@nihr.ac.uk.\n";
+},"useData":true})
+templates['contact-removed.html.hbs'] = handlebars.template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
+    var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3="function", alias4=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
+        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
+          return parent[propertyName];
         }
+        return undefined
+    };
 
-    return (
-      "<html lang='en'>\n\n  <body>\n    <div>\n      <h1>NIHR RDN has invited you to assess the progress of your studies</h1>\n\n      <p>Hello,</p>\n\n      <p>\n        You have been nominated as a contact for\n        " +
-      alias4(
-        ((helper =
-          (helper =
-            lookupProperty(helpers, 'organisationName') ||
-            (depth0 != null ? lookupProperty(depth0, 'organisationName') : depth0)) != null
-            ? helper
-            : alias2),
-        typeof helper === alias3
-          ? helper.call(alias1, {
-              name: 'organisationName',
-              hash: {},
-              data: data,
-              loc: { start: { line: 12, column: 8 }, end: { line: 12, column: 28 } },
-            })
-          : helper)
-      ) +
-      "\n        on the NIHR Research Delivery Network’s (RDN) research portfolio.\n      </p>\n\n      <p>\n        The\n        <a href='" +
-      alias4(
-        ((helper =
-          (helper =
-            lookupProperty(helpers, 'rdnLink') || (depth0 != null ? lookupProperty(depth0, 'rdnLink') : depth0)) != null
-            ? helper
-            : alias2),
-        typeof helper === alias3
-          ? helper.call(alias1, {
-              name: 'rdnLink',
-              hash: {},
-              data: data,
-              loc: { start: { line: 18, column: 17 }, end: { line: 18, column: 28 } },
-            })
-          : helper)
-      ) +
-      "'>NIHR RDN</a>\n        supports Sponsors and their delegates to deliver high-quality research, for the benefit of patients, the public\n        and health and care organisations across England.\n      </p>\n\n      <p>\n        The NIHR RDN tracks the progress of research studies in its portfolio using data provided by Sponsors or their\n        delegates on behalf of the Department of Health and Social Care (DHSC).\n      </p>\n\n      <p>\n        The DHSC have published the \n        <a href='" +
-      alias4(
-        ((helper =
-          (helper =
-            lookupProperty(helpers, 'termsAndConditionsLink') ||
-            (depth0 != null ? lookupProperty(depth0, 'termsAndConditionsLink') : depth0)) != null
-            ? helper
-            : alias2),
-        typeof helper === alias3
-          ? helper.call(alias1, {
-              name: 'termsAndConditionsLink',
-              hash: {},
-              data: data,
-              loc: { start: { line: 30, column: 17 }, end: { line: 30, column: 43 } },
-            })
-          : helper)
-      ) +
-      "'>Terms and Conditions for NIHR RDN support</a>, which outlines the requirements for Sponsors to provide up-to-date study data and assessments of progress to the RDN.\n      </p>\n\n      <p>\n        The Sponsor Engagement Tool has been designed to support Sponsors and their delegates to meet the requirements\n        outlined in the T&Cs. Sponsors and their delegates should use the Sponsor Engagement Tool to review the data the\n        RDN holds on their organisation’s portfolio of studies and to provide study data updates and assessments to ensure\n        the data held by the RDN is complete and up-to-date.\n      </p>\n\n      <p>\n        Please sign in to the Sponsor Engagement Tool to provide updates on studies.\n      </p>\n\n      <a\n        href='" +
-      alias4(
-        ((helper =
-          (helper =
-            lookupProperty(helpers, 'signInLink') ||
-            (depth0 != null ? lookupProperty(depth0, 'signInLink') : depth0)) != null
-            ? helper
-            : alias2),
-        typeof helper === alias3
-          ? helper.call(alias1, {
-              name: 'signInLink',
-              hash: {},
-              data: data,
-              loc: { start: { line: 45, column: 14 }, end: { line: 45, column: 28 } },
-            })
-          : helper)
-      ) +
-      "'\n        style='\n          box-sizing: border-box;\n          display: inline-block;\n          position: relative;\n          margin-top: 0;\n          margin-right: 0;\n          margin-left: 0;\n          margin-bottom: 22px;\n          padding: 8px 10px 7px;\n          border: 2px solid rgba(0, 0, 0, 0);\n          border-radius: 0;\n          color: #fff;\n          background-color: #00703c;\n          box-shadow: 0 2px 0 #002d18;\n          text-align: center;\n          vertical-align: top;\n          cursor: pointer;\n          -webkit-appearance: none;\n        '\n      >Sign in to assess studies</a>\n\n      <h2>Why am I being asked to assess studies?</h2>\n\n      <p>Sponsors or their delegates are asked to review and assess the progress of studies when:</p>\n\n      <ul>\n        <li>A study falls behind a planned milestone or</li>\n        <li> A study appears to not be recruiting to target</li>\n        <li> And the last study assessment is over three months old</li>\n      </ul>\n\n      <p>\n        Sponsors or their delegates can request\n        <a href='" +
-      alias4(
-        ((helper =
-          (helper =
-            lookupProperty(helpers, 'requestSupportLink') ||
-            (depth0 != null ? lookupProperty(depth0, 'requestSupportLink') : depth0)) != null
-            ? helper
-            : alias2),
-        typeof helper === alias3
-          ? helper.call(alias1, {
-              name: 'requestSupportLink',
-              hash: {},
-              data: data,
-              loc: { start: { line: 79, column: 17 }, end: { line: 79, column: 39 } },
-            })
-          : helper)
-      ) +
-      "'>NIHR RDN support</a>\n        with study delivery and performance at any time.\n      </p>\n\n      <p>\n        <strong>\n          Please note that providing regular study data updates and assessments are requirements of the\n          <a href='" +
-      alias4(
-        ((helper =
-          (helper =
-            lookupProperty(helpers, 'termsAndConditionsLink') ||
-            (depth0 != null ? lookupProperty(depth0, 'termsAndConditionsLink') : depth0)) != null
-            ? helper
-            : alias2),
-        typeof helper === alias3
-          ? helper.call(alias1, {
-              name: 'termsAndConditionsLink',
-              hash: {},
-              data: data,
-              loc: { start: { line: 86, column: 19 }, end: { line: 86, column: 45 } },
-            })
-          : helper)
-      ) +
-      "'>Terms and Conditions for NIHR RDN support</a>. Failure to do so may\n          result in removal from the NIHR RDN Portfolio.\n        </strong>\n      </p>\n\n      <h2>Nominate someone else to assess studies</h2>\n\n      <p>\n        The NIHR RDN can give other people in your organisation access to this service. \n        <a href='mailto:supportmystudy@nihr.ac.uk'>Contact supportmystudy@nihr.ac.uk</a>\n        to add a new contact.\n      </p>\n\n      <hr />\n\n      <p>\n        This email is not monitored, do not reply. If you’re not sure why you’ve received this email or need to be\n        removed from our list \n        <a href='mailto:supportmystudy@nihr.ac.uk'>contact supportmystudy@nihr.ac.uk</a>.\n      </p>\n    </div>\n\n    <br />\n\n    <div>\n      <table style='width: 540px; border-collapse: collapse'>\n        <tbody>\n          <tr>\n            <td style='width: 162px'>\n              <p>\n                &nbsp;<img\n                  src='https://www.nihr.ac.uk/layout/4.0/assets/external/nihr-logo.png'\n                  alt=''\n                  width='206'\n                  class='CToWUd'\n                  data-bit='iit'\n                />\n              </p>\n            </td>\n          </tr>\n        </tbody>\n      </table>\n\n      <p>\n        <a\n          href='https://www.nihr.ac.uk/explore-nihr/campaigns/nhs-75/?utm_source=gmail&amp;utm_medium=email&amp;utm_campaign=nhs75&amp;utm_term=signature&amp;utm_content=signature'\n          target='_blank'\n        ><img\n            src='https://www.nihr.ac.uk/layout/img/external/nhs75-shape-the-future-signature.png'\n            alt='NIHR, Supporting NHS75. Life changing research funded by the public. Click, get involved in our NHS75 campaign'\n            width='540'\n            height='101'\n            class='CToWUd'\n            data-bit='iit'\n          />\n        </a>\n      </p>\n\n      <p>\n        Follow us:\n        <img\n          src='https://www.nihr.ac.uk/images/about-us/stay-up-to-date/f_logo_RGB-Blue_58.png'\n          alt=''\n          width='11'\n          height='11'\n          class='CToWUd'\n          data-bit='iit'\n        />\n        <a href='https://www.facebook.com/OfficialNIHR' target='_blank'>NIHR Facebook</a>&nbsp;|&nbsp;<img\n          src='https://www.nihr.ac.uk/images/about-us/stay-up-to-date/Twitter_Logo_Blue.png'\n          alt=''\n          width='11'\n          height='11'\n          class='CToWUd'\n          data-bit='iit'\n        />\n        <a href='https://x.com/NIHRresearch' target='_blank' aria-label='NIHR X (formerly Twitter)'>NIHR X</a>&nbsp;|&nbsp;<img\n          src='https://www.nihr.ac.uk/images/about-us/stay-up-to-date/LI-In-Bug.png'\n          alt=''\n          width='11'\n          height='9'\n          class='CToWUd'\n          data-bit='iit'\n        /><a href='https://www.linkedin.com/company/nihr-research' target='_blank'>NIHR LinkedIn</a>\n        |\n        <img\n          src='https://www.nihr.ac.uk/images/about-us/stay-up-to-date/youtube_logo_rgb_light.png'\n          alt=''\n          width='11'\n          height='9'\n          class='CToWUd'\n          data-bit='iit'\n        />\n        <a href='https://www.youtube.com/user/NIHRtv' target='_blank'>NIHR YouTube</a>\n        |\n        <img\n          src='https://www.nihr.ac.uk/layout/img/external/nihr-link-icon.png'\n          alt=''\n          width='11'\n          height='9'\n          class='CToWUd'\n          data-bit='iit'\n        />\n        <a\n          href='https://www.nihr.ac.uk/?utm_source=gmail&amp;utm_medium=email&amp;utm_campaign=ccsignature'\n          target='_blank'\n        >NIHR Website</a>\n      </p>\n      <br />\n      <br />\n      <p style='color: rgb(34, 34, 34); font-family: arial, sans-serif; background-color: rgb(255, 255, 255)'>\n        Confidential information may be contained in this message. If you are not the intended recipient, any reading,\n        printing, storage, disclosure, copying or any other action taken in respect of this e-mail is prohibited and may\n        be unlawful. If you are not the intended recipient, please notify the sender immediately by using the reply\n        function and then permanently delete what you have received.\n      </p>\n    </div>\n  </body>\n\n</html>"
-    )
-  },
-  useData: true,
-})
-templates['contact-assigned.text.hbs'] = handlebars.template({
-  compiler: [8, '>= 4.3.0'],
-  main: function (container, depth0, helpers, partials, data) {
-    var helper,
-      alias1 = depth0 != null ? depth0 : container.nullContext || {},
-      alias2 = container.hooks.helperMissing,
-      alias3 = 'function',
-      alias4 = container.escapeExpression,
-      lookupProperty =
-        container.lookupProperty ||
-        function (parent, propertyName) {
-          if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
-            return parent[propertyName]
-          }
-          return undefined
+  return "<html lang='en'>\n  <body>\n    <div>\n      <h1>NIHR RDN has removed you as a reviewer for "
+    + alias4(((helper = (helper = lookupProperty(helpers,"organisationName") || (depth0 != null ? lookupProperty(depth0,"organisationName") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"organisationName","hash":{},"data":data,"loc":{"start":{"line":5,"column":53},"end":{"line":5,"column":73}}}) : helper)))
+    + "</h1>\n\n      <p>Hello,</p>\n\n      <p>You have been removed as a reviewer of research studies for\n        "
+    + alias4(((helper = (helper = lookupProperty(helpers,"organisationName") || (depth0 != null ? lookupProperty(depth0,"organisationName") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"organisationName","hash":{},"data":data,"loc":{"start":{"line":10,"column":8},"end":{"line":10,"column":28}}}) : helper)))
+    + ". You will no longer be able to review and assess study progress.\n      </p>\n\n      <hr />\n\n      <h2>Not sure why you've been removed?</h2>\n\n      <p>If you think there’s been an error please\n        <a href='mailto:supportmystudy@nihr.ac.uk'>contact supportmystudy@nihr.ac.uk</a>.</p>\n\n      <p>If you’re not sure why you’ve received this email or need to be removed from our list\n        <a href='mailto:supportmystudy@nihr.ac.uk'>contact supportmystudy@nihr.ac.uk</a>.</p>\n    </div>\n\n    <br />\n\n    <div>\n      <table style='width: 540px; border-collapse: collapse'>\n        <tbody>\n          <tr>\n            <td style='width: 162px'>\n              <p>\n                &nbsp;<img\n                  src='https://nihr.widen.net/content/xazipspiv6/jpeg/nihr-logo.jpeg'\n                  alt=''\n                  width='206'\n                  class='CToWUd'\n                  data-bit='iit'\n                />\n              </p>\n            </td>\n          </tr>\n        </tbody>\n      </table>\n      <p>\n        Follow us:\n        <!-- facebook logo -->\n        <img\n          src='https://nihr.widen.net/content/aqo4dnubmf/jpeg/f_logo_rgb-blue_58.jpeg'\n          alt=''\n          width='11'\n          height='11'\n          class='CToWUd'\n          data-bit='iit'\n        />\n        <a href='https://www.facebook.com/OfficialNIHR' target='_blank'>NIHR Facebook</a>\n        &nbsp;|&nbsp;\n        <!-- twitter logo -->\n        <img\n          src='https://nihr.widen.net/content/egucpu5vgs/jpeg/x-logo-black.jpeg'\n          alt=''\n          width='11'\n          height='11'\n          class='CToWUd'\n          data-bit='iit'\n        />\n        <a href='https://x.com/NIHRresearch' target='_blank' aria-label='NIHR X (formerly Twitter)'>NIHR X</a>\n        &nbsp;|&nbsp;\n        <!-- linkedin logo -->\n        <img \n          src='https://nihr.widen.net/content/xc1gslcvmt/jpeg/li-in-bug.jpeg'\n          alt=''\n          width='11'\n          height='9'\n          class='CToWUd'\n          data-bit='iit'\n        />\n        <a href='https://www.linkedin.com/company/nihr-research' target='_blank'>NIHR LinkedIn</a>\n        &nbsp;|&nbsp;\n        <!-- youtube logo -->\n        <img\n          src='https://nihr.widen.net/content/52cd9uokcy/jpeg/youtube_logo_rgb_light.jpeg'\n          alt=''\n          width='11'\n          height='9'\n          class='CToWUd'\n          data-bit='iit'\n        />\n        <a href='https://www.youtube.com/user/NIHRtv' target='_blank'>NIHR YouTube</a>\n        &nbsp;|&nbsp;\n        <!-- nihr link logo -->\n        <img\n          src='https://nihr.widen.net/content/5mhcdc6utg/jpeg/nihr-link-icon.jpeg'\n          alt=''\n          width='11'\n          height='9'\n          class='CToWUd'\n          data-bit='iit'\n        />\n        <a\n          href='https://www.nihr.ac.uk/?utm_source=gmail&amp;utm_medium=email&amp;utm_campaign=ccsignature'\n          target='_blank'\n        >NIHR Website</a>\n      </p>\n      <br />\n      <br />\n      <p style='color: rgb(34, 34, 34); font-family: arial, sans-serif; background-color: rgb(255, 255, 255)'>\n        Confidential information may be contained in this message. If you are not the intended recipient, any reading,\n        printing, storage, disclosure, copying or any other action taken in respect of this e-mail is prohibited and may\n        be unlawful. If you are not the intended recipient, please notify the sender immediately by using the reply\n        function and then permanently delete what you have received.\n      </p>\n    </div>\n  </body>\n\n</html>";
+},"useData":true})
+templates['contact-removed.text.hbs'] = handlebars.template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
+    var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3="function", alias4=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
+        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
+          return parent[propertyName];
         }
+        return undefined
+    };
 
-    return (
-      '# NIHR RDN has invited you to assess the progress of your studies\n\nHello,\n\nYou have been nominated as a contact for ' +
-      alias4(
-        ((helper =
-          (helper =
-            lookupProperty(helpers, 'organisationName') ||
-            (depth0 != null ? lookupProperty(depth0, 'organisationName') : depth0)) != null
-            ? helper
-            : alias2),
-        typeof helper === alias3
-          ? helper.call(alias1, {
-              name: 'organisationName',
-              hash: {},
-              data: data,
-              loc: { start: { line: 5, column: 41 }, end: { line: 5, column: 61 } },
-            })
-          : helper)
-      ) +
-      " studies on the NIHR Research Delivery Network's (RDN) research portfolio.\n\nThe NIHR RDN supports Sponsors and their delegates to deliver high-quality research, for the benefit of patients, the public and health and care organisations across England.\n\nThe NIHR RDN tracks the progress of research studies in its portfolio using data provided by Sponsors or their delegates on behalf of the Department of Health and Social Care (DHSC).\n\nThe DHSC have published the Terms and Conditions for NIHR RDN support (" +
-      alias4(
-        ((helper =
-          (helper =
-            lookupProperty(helpers, 'termsAndConditionsLink') ||
-            (depth0 != null ? lookupProperty(depth0, 'termsAndConditionsLink') : depth0)) != null
-            ? helper
-            : alias2),
-        typeof helper === alias3
-          ? helper.call(alias1, {
-              name: 'termsAndConditionsLink',
-              hash: {},
-              data: data,
-              loc: { start: { line: 11, column: 71 }, end: { line: 11, column: 97 } },
-            })
-          : helper)
-      ) +
-      '), which outlines the requirements for Sponsors to provide up-to-date study data and assessments of progress to the RDN.\n\nThe Sponsor Engagement Tool has been designed to support Sponsors and their delegates to meet the requirements outlined in the T&Cs. \nSponsors and their delegates should use the Sponsor Engagement Tool to review the data the RDN holds on their organisation’s portfolio \nof studies and to provide study data updates and assessments to ensure the data held by the RDN is complete and up-to-date.\n\nPlease sign in to the Sponsor Engagement Tool to provide updates on studies. (' +
-      alias4(
-        ((helper =
-          (helper =
-            lookupProperty(helpers, 'signInLink') ||
-            (depth0 != null ? lookupProperty(depth0, 'signInLink') : depth0)) != null
-            ? helper
-            : alias2),
-        typeof helper === alias3
-          ? helper.call(alias1, {
-              name: 'signInLink',
-              hash: {},
-              data: data,
-              loc: { start: { line: 17, column: 78 }, end: { line: 17, column: 92 } },
-            })
-          : helper)
-      ) +
-      ')\n\n# Why am I being asked to assess studies?\n\nSponsors or their delegates are asked to review and assess the progress of studies when:\n\n- A study falls behind a planned milestone or\n- A study appears to not be recruiting to target\n- And the last study assessment is over three months old\n\nSponsors or their delegates can request NIHR RDN support with study delivery and performance at any time. (' +
-      alias4(
-        ((helper =
-          (helper =
-            lookupProperty(helpers, 'requestSupportLink') ||
-            (depth0 != null ? lookupProperty(depth0, 'requestSupportLink') : depth0)) != null
-            ? helper
-            : alias2),
-        typeof helper === alias3
-          ? helper.call(alias1, {
-              name: 'requestSupportLink',
-              hash: {},
-              data: data,
-              loc: { start: { line: 27, column: 107 }, end: { line: 27, column: 129 } },
-            })
-          : helper)
-      ) +
-      ')\n\nPlease note that providing regular study data updates and assessments are requirements of the Terms and Conditions for NIHR RDN support. \nFailure to do so may result in removal from the NIHR RDN Portfolio.(' +
-      alias4(
-        ((helper =
-          (helper =
-            lookupProperty(helpers, 'termsAndConditionsLink') ||
-            (depth0 != null ? lookupProperty(depth0, 'termsAndConditionsLink') : depth0)) != null
-            ? helper
-            : alias2),
-        typeof helper === alias3
-          ? helper.call(alias1, {
-              name: 'termsAndConditionsLink',
-              hash: {},
-              data: data,
-              loc: { start: { line: 30, column: 68 }, end: { line: 30, column: 94 } },
-            })
-          : helper)
-      ) +
-      ')\n\n# Nominate someone else to assess studies\n\nThe NIHR RDN can give other people in your organisation access to this service. Contact supportmystudy@nihr.ac.uk to add\na new contact.\n\nThis email is not monitored, do not reply. If you’re not sure why you’ve received this email or need to be removed from\nour list, please contact supportmystudy@nihr.ac.uk.\n'
-    )
-  },
-  useData: true,
-})
-templates['contact-removed.html.hbs'] = handlebars.template({
-  compiler: [8, '>= 4.3.0'],
-  main: function (container, depth0, helpers, partials, data) {
-    var helper,
-      alias1 = depth0 != null ? depth0 : container.nullContext || {},
-      alias2 = container.hooks.helperMissing,
-      alias3 = 'function',
-      alias4 = container.escapeExpression,
-      lookupProperty =
-        container.lookupProperty ||
-        function (parent, propertyName) {
-          if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
-            return parent[propertyName]
-          }
-          return undefined
+  return "# NIHR RDN has removed you as a reviewer for "
+    + alias4(((helper = (helper = lookupProperty(helpers,"organisationName") || (depth0 != null ? lookupProperty(depth0,"organisationName") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"organisationName","hash":{},"data":data,"loc":{"start":{"line":1,"column":45},"end":{"line":1,"column":65}}}) : helper)))
+    + "\n\nHello, You have been removed as a reviewer of research studies for "
+    + alias4(((helper = (helper = lookupProperty(helpers,"organisationName") || (depth0 != null ? lookupProperty(depth0,"organisationName") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"organisationName","hash":{},"data":data,"loc":{"start":{"line":3,"column":67},"end":{"line":3,"column":87}}}) : helper)))
+    + ". You will no longer be able to\nreview and assess study progress.\n\n# Not sure why you've been removed?\n\nIf you think there’s been an error please contact supportmystudy@nihr.ac.uk.\n\nIf you’re not sure why you’ve received this email or need to be removed from our list contact supportmystudy@nihr.ac.uk.";
+},"useData":true})
+templates['invitation-email-unsuccessful.html.hbs'] = handlebars.template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
+    var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3="function", alias4=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
+        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
+          return parent[propertyName];
         }
+        return undefined
+    };
 
-    return (
-      "<html lang='en'>\n  <body>\n    <div>\n      <h1>NIHR RDN has removed you as a reviewer for " +
-      alias4(
-        ((helper =
-          (helper =
-            lookupProperty(helpers, 'organisationName') ||
-            (depth0 != null ? lookupProperty(depth0, 'organisationName') : depth0)) != null
-            ? helper
-            : alias2),
-        typeof helper === alias3
-          ? helper.call(alias1, {
-              name: 'organisationName',
-              hash: {},
-              data: data,
-              loc: { start: { line: 5, column: 53 }, end: { line: 5, column: 73 } },
-            })
-          : helper)
-      ) +
-      '</h1>\n\n      <p>Hello,</p>\n\n      <p>You have been removed as a reviewer of research studies for\n        ' +
-      alias4(
-        ((helper =
-          (helper =
-            lookupProperty(helpers, 'organisationName') ||
-            (depth0 != null ? lookupProperty(depth0, 'organisationName') : depth0)) != null
-            ? helper
-            : alias2),
-        typeof helper === alias3
-          ? helper.call(alias1, {
-              name: 'organisationName',
-              hash: {},
-              data: data,
-              loc: { start: { line: 10, column: 8 }, end: { line: 10, column: 28 } },
-            })
-          : helper)
-      ) +
-      ". You will no longer be able to review and assess study progress.\n      </p>\n\n      <hr />\n\n      <h2>Not sure why you've been removed?</h2>\n\n      <p>If you think there’s been an error please \n        <a href='mailto:supportmystudy@nihr.ac.uk'>contact supportmystudy@nihr.ac.uk</a>.</p>\n\n      <p>If you’re not sure why you’ve received this email or need to be removed from our list \n        <a href='mailto:supportmystudy@nihr.ac.uk'>contact supportmystudy@nihr.ac.uk</a>.</p>\n    </div>\n\n    <br />\n\n    <div>\n      <table style='width: 540px; border-collapse: collapse'>\n        <tbody>\n          <tr>\n            <td style='width: 162px'>\n              <p>\n                &nbsp;<img\n                  src='https://www.nihr.ac.uk/layout/4.0/assets/external/nihr-logo.png'\n                  alt=''\n                  width='206'\n                  class='CToWUd'\n                  data-bit='iit'\n                />\n              </p>\n            </td>\n          </tr>\n        </tbody>\n      </table>\n\n      <p>\n        <a\n          href='https://www.nihr.ac.uk/explore-nihr/campaigns/nhs-75/?utm_source=gmail&amp;utm_medium=email&amp;utm_campaign=nhs75&amp;utm_term=signature&amp;utm_content=signature'\n          target='_blank'\n        ><img\n            src='https://www.nihr.ac.uk/layout/img/external/nhs75-shape-the-future-signature.png'\n            alt='NIHR, Supporting NHS75. Life changing research funded by the public. Click, get involved in our NHS75 campaign'\n            width='540'\n            height='101'\n            class='CToWUd'\n            data-bit='iit'\n          />\n        </a>\n      </p>\n\n      <p>\n        Follow us:\n        <img\n          src='https://www.nihr.ac.uk/images/about-us/stay-up-to-date/f_logo_RGB-Blue_58.png'\n          alt=''\n          width='11'\n          height='11'\n          class='CToWUd'\n          data-bit='iit'\n        />\n        <a href='https://www.facebook.com/OfficialNIHR' target='_blank'>NIHR Facebook</a>&nbsp;|&nbsp;<img\n          src='https://www.nihr.ac.uk/images/about-us/stay-up-to-date/Twitter_Logo_Blue.png'\n          alt=''\n          width='11'\n          height='11'\n          class='CToWUd'\n          data-bit='iit'\n        />\n        <a href='https://x.com/NIHRresearch' target='_blank' aria-label='NIHR X (formerly Twitter)'>NIHR X</a>&nbsp;|&nbsp;<img\n          src='https://www.nihr.ac.uk/images/about-us/stay-up-to-date/LI-In-Bug.png'\n          alt=''\n          width='11'\n          height='9'\n          class='CToWUd'\n          data-bit='iit'\n        /><a href='https://www.linkedin.com/company/nihr-research' target='_blank'>NIHR LinkedIn</a>\n        |\n        <img\n          src='https://www.nihr.ac.uk/images/about-us/stay-up-to-date/youtube_logo_rgb_light.png'\n          alt=''\n          width='11'\n          height='9'\n          class='CToWUd'\n          data-bit='iit'\n        />\n        <a href='https://www.youtube.com/user/NIHRtv' target='_blank'>NIHR YouTube</a>\n        |\n        <img\n          src='https://www.nihr.ac.uk/layout/img/external/nihr-link-icon.png'\n          alt=''\n          width='11'\n          height='9'\n          class='CToWUd'\n          data-bit='iit'\n        />\n        <a\n          href='https://www.nihr.ac.uk/?utm_source=gmail&amp;utm_medium=email&amp;utm_campaign=ccsignature'\n          target='_blank'\n        >NIHR Website</a>\n      </p>\n      <br />\n      <br />\n      <p style='color: rgb(34, 34, 34); font-family: arial, sans-serif; background-color: rgb(255, 255, 255)'>\n        Confidential information may be contained in this message. If you are not the intended recipient, any reading,\n        printing, storage, disclosure, copying or any other action taken in respect of this e-mail is prohibited and may\n        be unlawful. If you are not the intended recipient, please notify the sender immediately by using the reply\n        function and then permanently delete what you have received.\n      </p>\n    </div>\n  </body>\n\n</html>"
-    )
-  },
-  useData: true,
-})
-templates['contact-removed.text.hbs'] = handlebars.template({
-  compiler: [8, '>= 4.3.0'],
-  main: function (container, depth0, helpers, partials, data) {
-    var helper,
-      alias1 = depth0 != null ? depth0 : container.nullContext || {},
-      alias2 = container.hooks.helperMissing,
-      alias3 = 'function',
-      alias4 = container.escapeExpression,
-      lookupProperty =
-        container.lookupProperty ||
-        function (parent, propertyName) {
-          if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
-            return parent[propertyName]
-          }
-          return undefined
+  return "<html lang='en'>\n  <body>\n    <div>\n      <h1>\n        The invitation email you sent when adding a new contact to your organisation was not delivered successfully\n      </h1>\n\n      <p>Hello,</p>\n\n      <p>We are notifying you that your email sent to\n        "
+    + alias4(((helper = (helper = lookupProperty(helpers,"recipientEmailAddress") || (depth0 != null ? lookupProperty(depth0,"recipientEmailAddress") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"recipientEmailAddress","hash":{},"data":data,"loc":{"start":{"line":12,"column":8},"end":{"line":12,"column":33}}}) : helper)))
+    + "\n        was not delivered. This means the recipient's email address is likely invalid or unavailable at this time.\n      </p>\n\n      <p>Next steps:</p>\n\n      <p>Please login to the\n        <a href='"
+    + alias4(((helper = (helper = lookupProperty(helpers,"sponsorEngagementToolLink") || (depth0 != null ? lookupProperty(depth0,"sponsorEngagementToolLink") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"sponsorEngagementToolLink","hash":{},"data":data,"loc":{"start":{"line":19,"column":17},"end":{"line":19,"column":46}}}) : helper)))
+    + "'>Sponsor Engagement Tool</a>\n        and check you have used the correct email address. If it's incorrect, remove the contact, then re-add them.\n      </p>\n\n      <p>If you need further assistance please contact\n        <a href='mailto:supportmystudy@nihr.ac.uk'>supportmystudy@nihr.ac.uk</a>.</p>\n\n      <hr />\n\n      <p>\n        This email is not monitored, do not reply. If you’re not sure why you’ve received this email or need to be\n        removed from our list contact\n        <a href='mailto:supportmystudy@nihr.ac.uk'> supportmystudy@nihr.ac.uk</a>.\n      </p>\n\n    </div>\n\n    <br />\n\n    <div>\n      <table style='width: 540px; border-collapse: collapse'>\n        <tbody>\n          <tr>\n            <td style='width: 162px'>\n              <p>\n                &nbsp;<img\n                  src='https://nihr.widen.net/content/xazipspiv6/jpeg/nihr-logo.jpeg'\n                  alt=''\n                  width='206'\n                  class='CToWUd'\n                  data-bit='iit'\n                />\n              </p>\n            </td>\n          </tr>\n        </tbody>\n      </table>\n      <p>\n        Follow us:\n        <!-- facebook logo -->\n        <img\n          src='https://nihr.widen.net/content/aqo4dnubmf/jpeg/f_logo_rgb-blue_58.jpeg'\n          alt=''\n          width='11'\n          height='11'\n          class='CToWUd'\n          data-bit='iit'\n        />\n        <a href='https://www.facebook.com/OfficialNIHR' target='_blank'>NIHR Facebook</a>\n        &nbsp;|&nbsp;\n        <!-- twitter logo -->\n        <img\n          src='https://nihr.widen.net/content/egucpu5vgs/jpeg/x-logo-black.jpeg'\n          alt=''\n          width='11'\n          height='11'\n          class='CToWUd'\n          data-bit='iit'\n        />\n        <a href='https://x.com/NIHRresearch' target='_blank' aria-label='NIHR X (formerly Twitter)'>NIHR X</a>\n        &nbsp;|&nbsp;\n        <!-- linkedin logo -->\n        <img\n          src='https://nihr.widen.net/content/xc1gslcvmt/jpeg/li-in-bug.jpeg'\n          alt=''\n          width='11'\n          height='9'\n          class='CToWUd'\n          data-bit='iit'\n        />\n        <a href='https://www.linkedin.com/company/nihr-research' target='_blank'>NIHR LinkedIn</a>\n        &nbsp;|&nbsp;\n        <!-- youtube logo -->\n        <img\n          src='https://nihr.widen.net/content/52cd9uokcy/jpeg/youtube_logo_rgb_light.jpeg'\n          alt=''\n          width='11'\n          height='9'\n          class='CToWUd'\n          data-bit='iit'\n        />\n        <a href='https://www.youtube.com/user/NIHRtv' target='_blank'>NIHR YouTube</a>\n        &nbsp;|&nbsp;\n        <!-- nihr link logo -->\n        <img\n          src='https://nihr.widen.net/content/5mhcdc6utg/jpeg/nihr-link-icon.jpeg'\n          alt=''\n          width='11'\n          height='9'\n          class='CToWUd'\n          data-bit='iit'\n        />\n        <a\n          href='https://www.nihr.ac.uk/?utm_source=gmail&amp;utm_medium=email&amp;utm_campaign=ccsignature'\n          target='_blank'\n        >NIHR Website</a>\n      </p>\n      <br />\n      <br />\n      <p style='color: rgb(34, 34, 34); font-family: arial, sans-serif; background-color: rgb(255, 255, 255)'>\n        Confidential information may be contained in this message. If you are not the intended recipient, any reading,\n        printing, storage, disclosure, copying or any other action taken in respect of this e-mail is prohibited and may\n        be unlawful. If you are not the intended recipient, please notify the sender immediately by using the reply\n        function and then permanently delete what you have received.\n      </p>\n    </div>\n  </body>\n</html>";
+},"useData":true})
+templates['invitation-email-unsuccessful.text.hbs'] = handlebars.template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
+    var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3="function", alias4=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
+        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
+          return parent[propertyName];
         }
+        return undefined
+    };
 
-    return (
-      '# NIHR RDN has removed you as a reviewer for ' +
-      alias4(
-        ((helper =
-          (helper =
-            lookupProperty(helpers, 'organisationName') ||
-            (depth0 != null ? lookupProperty(depth0, 'organisationName') : depth0)) != null
-            ? helper
-            : alias2),
-        typeof helper === alias3
-          ? helper.call(alias1, {
-              name: 'organisationName',
-              hash: {},
-              data: data,
-              loc: { start: { line: 1, column: 45 }, end: { line: 1, column: 65 } },
-            })
-          : helper)
-      ) +
-      '\n\nHello, You have been removed as a reviewer of research studies for ' +
-      alias4(
-        ((helper =
-          (helper =
-            lookupProperty(helpers, 'organisationName') ||
-            (depth0 != null ? lookupProperty(depth0, 'organisationName') : depth0)) != null
-            ? helper
-            : alias2),
-        typeof helper === alias3
-          ? helper.call(alias1, {
-              name: 'organisationName',
-              hash: {},
-              data: data,
-              loc: { start: { line: 3, column: 67 }, end: { line: 3, column: 87 } },
-            })
-          : helper)
-      ) +
-      ". You will no longer be able to\nreview and assess study progress.\n\n# Not sure why you've been removed?\n\nIf you think there’s been an error please contact supportmystudy@nihr.ac.uk.\n\nIf you’re not sure why you’ve received this email or need to be removed from our list contact supportmystudy@nihr.ac.uk."
-    )
-  },
-  useData: true,
-})
-module.exports = templates
+  return "# The invitation email you sent when adding a new contact to your organisation was not delivered successfully\n\nHello,\n\nWe are notifying you that your email sent to "
+    + alias4(((helper = (helper = lookupProperty(helpers,"recipientEmailAddress") || (depth0 != null ? lookupProperty(depth0,"recipientEmailAddress") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"recipientEmailAddress","hash":{},"data":data,"loc":{"start":{"line":5,"column":45},"end":{"line":5,"column":70}}}) : helper)))
+    + " was not delivered. \nThis means the recipient's email address is likely invalid or unavailable at this time.\n\nNext steps:\n\nPlease login to the Sponsor Engagement Tool  ("
+    + alias4(((helper = (helper = lookupProperty(helpers,"sponsorEngagementToolLink") || (depth0 != null ? lookupProperty(depth0,"sponsorEngagementToolLink") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"sponsorEngagementToolLink","hash":{},"data":data,"loc":{"start":{"line":10,"column":46},"end":{"line":10,"column":75}}}) : helper)))
+    + ") and check you have used the correct email address. If it's incorrect, remove the contact, then re-add them.\n\nIf you need further assistance please contact supportmystudy@nihr.ac.uk.\n\nThis email is not monitored, do not reply. If you’re not sure why you’ve received this email or need to be removed from\nour list contact supportmystudy@nihr.ac.uk.";
+},"useData":true})
+module.exports = templates
\ No newline at end of file
diff --git a/packages/templates/sponsor-engagement/email/index.spec.ts b/packages/templates/sponsor-engagement/email/index.spec.ts
index 6f685863c..a485e7263 100644
--- a/packages/templates/sponsor-engagement/email/index.spec.ts
+++ b/packages/templates/sponsor-engagement/email/index.spec.ts
@@ -15,6 +15,8 @@ test.each(templateKeys)('Email template %p displays correctly', (key) => {
       termsAndConditionsLink: 'http://terms-conditions-link',
       organisationName: 'Mocked org name',
       organisationNames: ['Mocked org name', 'Mocked second org name'],
+      sponsorEngagementTool: 'http://localhost:3000',
+      recipientEmailAddress: 'test@test.nihr.ac.uk',
     })
   ).toMatchSnapshot()
 })
diff --git a/packages/templates/sponsor-engagement/email/invitation-email-unsuccessful.html.hbs b/packages/templates/sponsor-engagement/email/invitation-email-unsuccessful.html.hbs
new file mode 100644
index 000000000..c8a84c63b
--- /dev/null
+++ b/packages/templates/sponsor-engagement/email/invitation-email-unsuccessful.html.hbs
@@ -0,0 +1,127 @@
+<html lang='en'>
+  <body>
+    {{! Main content }}
+    <div>
+      <h1>
+        The invitation email you sent when adding a new contact to your organisation was not delivered successfully
+      </h1>
+
+      <p>Hello,</p>
+
+      <p>We are notifying you that your email sent to
+        {{recipientEmailAddress}}
+        was not delivered. This means the recipient's email address is likely invalid or unavailable at this time.
+      </p>
+
+      <p>Next steps:</p>
+
+      <p>Please login to the
+        <a href='{{sponsorEngagementToolLink}}'>Sponsor Engagement Tool</a>
+        and check you have used the correct email address. If it's incorrect, remove the contact, then re-add them.
+      </p>
+
+      <p>If you need further assistance please contact
+        <a href='mailto:supportmystudy@nihr.ac.uk'>supportmystudy@nihr.ac.uk</a>.</p>
+
+      <hr />
+
+      <p>
+        This email is not monitored, do not reply. If you’re not sure why you’ve received this email or need to be
+        removed from our list contact
+        <a href='mailto:supportmystudy@nihr.ac.uk'> supportmystudy@nihr.ac.uk</a>.
+      </p>
+
+    </div>
+
+    <br />
+
+    {{! Email signature }}
+    <div>
+      <table style='width: 540px; border-collapse: collapse'>
+        <tbody>
+          <tr>
+            <td style='width: 162px'>
+              <p>
+                &nbsp;<img
+                  src='https://nihr.widen.net/content/xazipspiv6/jpeg/nihr-logo.jpeg'
+                  alt=''
+                  width='206'
+                  class='CToWUd'
+                  data-bit='iit'
+                />
+              </p>
+            </td>
+          </tr>
+        </tbody>
+      </table>
+      <p>
+        Follow us:
+        <!-- facebook logo -->
+        <img
+          src='https://nihr.widen.net/content/aqo4dnubmf/jpeg/f_logo_rgb-blue_58.jpeg'
+          alt=''
+          width='11'
+          height='11'
+          class='CToWUd'
+          data-bit='iit'
+        />
+        <a href='https://www.facebook.com/OfficialNIHR' target='_blank'>NIHR Facebook</a>
+        &nbsp;|&nbsp;
+        <!-- twitter logo -->
+        <img
+          src='https://nihr.widen.net/content/egucpu5vgs/jpeg/x-logo-black.jpeg'
+          alt=''
+          width='11'
+          height='11'
+          class='CToWUd'
+          data-bit='iit'
+        />
+        <a href='https://x.com/NIHRresearch' target='_blank' aria-label='NIHR X (formerly Twitter)'>NIHR X</a>
+        &nbsp;|&nbsp;
+        <!-- linkedin logo -->
+        <img
+          src='https://nihr.widen.net/content/xc1gslcvmt/jpeg/li-in-bug.jpeg'
+          alt=''
+          width='11'
+          height='9'
+          class='CToWUd'
+          data-bit='iit'
+        />
+        <a href='https://www.linkedin.com/company/nihr-research' target='_blank'>NIHR LinkedIn</a>
+        &nbsp;|&nbsp;
+        <!-- youtube logo -->
+        <img
+          src='https://nihr.widen.net/content/52cd9uokcy/jpeg/youtube_logo_rgb_light.jpeg'
+          alt=''
+          width='11'
+          height='9'
+          class='CToWUd'
+          data-bit='iit'
+        />
+        <a href='https://www.youtube.com/user/NIHRtv' target='_blank'>NIHR YouTube</a>
+        &nbsp;|&nbsp;
+        <!-- nihr link logo -->
+        <img
+          src='https://nihr.widen.net/content/5mhcdc6utg/jpeg/nihr-link-icon.jpeg'
+          alt=''
+          width='11'
+          height='9'
+          class='CToWUd'
+          data-bit='iit'
+        />
+        <a
+          href='https://www.nihr.ac.uk/?utm_source=gmail&amp;utm_medium=email&amp;utm_campaign=ccsignature'
+          target='_blank'
+        >NIHR Website</a>
+      </p>
+      <br />
+      <br />
+      <p style='color: rgb(34, 34, 34); font-family: arial, sans-serif; background-color: rgb(255, 255, 255)'>
+        Confidential information may be contained in this message. If you are not the intended recipient, any reading,
+        printing, storage, disclosure, copying or any other action taken in respect of this e-mail is prohibited and may
+        be unlawful. If you are not the intended recipient, please notify the sender immediately by using the reply
+        function and then permanently delete what you have received.
+      </p>
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/packages/templates/sponsor-engagement/email/invitation-email-unsuccessful.text.hbs b/packages/templates/sponsor-engagement/email/invitation-email-unsuccessful.text.hbs
new file mode 100644
index 000000000..4ed6ac935
--- /dev/null
+++ b/packages/templates/sponsor-engagement/email/invitation-email-unsuccessful.text.hbs
@@ -0,0 +1,15 @@
+# The invitation email you sent when adding a new contact to your organisation was not delivered successfully
+
+Hello,
+
+We are notifying you that your email sent to {{recipientEmailAddress}} was not delivered. 
+This means the recipient's email address is likely invalid or unavailable at this time.
+
+Next steps:
+
+Please login to the Sponsor Engagement Tool  ({{sponsorEngagementToolLink}}) and check you have used the correct email address. If it's incorrect, remove the contact, then re-add them.
+
+If you need further assistance please contact supportmystudy@nihr.ac.uk.
+
+This email is not monitored, do not reply. If you’re not sure why you’ve received this email or need to be removed from
+our list contact supportmystudy@nihr.ac.uk.
\ No newline at end of file
diff --git a/packages/templates/sponsor-engagement/index.spec.ts b/packages/templates/sponsor-engagement/index.spec.ts
index 64e3aa8c3..47f4ee2a1 100644
--- a/packages/templates/sponsor-engagement/index.spec.ts
+++ b/packages/templates/sponsor-engagement/index.spec.ts
@@ -7,6 +7,8 @@ const expectedTemplates = [
   'contact-assigned.text.hbs',
   'contact-removed.html.hbs',
   'contact-removed.text.hbs',
+  'invitation-email-unsuccessful.html.hbs',
+  'invitation-email-unsuccessful.text.hbs',
 ] as const
 
 describe('sponsor engagement templates', () => {


Reviews:
user: login: kevinofficer
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-09T15:27:23Z
user: login: con-nihr
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-10T14:33:07Z
user: login: con-nihr
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-10T14:43:03Z

Review comments:
diff_hunk: @@ -0,0 +1,204 @@
+import { Prisma } from 'database'
+import { emailService } from '@nihr-ui/email'
+import { config as dotEnvConfig } from 'dotenv'
+import { BounceType, EventType, TooManyRequestsException } from '@aws-sdk/client-sesv2'
+import utc from 'dayjs/plugin/utc'
+import dayjs from 'dayjs'
+import { logger } from '@nihr-ui/logger'
+import type { EmailStatusResult } from '@nihr-ui/email/email-service'
+import { emailTemplates } from '@nihr-ui/templates/sponsor-engagement'
+import { EMAIL_DELIVERY_THRESHOLD_HOURS, PERMANENT_EMAIL_FAILURES, UserOrganisationInviteStatus } from './lib/constants'
+import { prismaClient } from './lib/prisma'
+import type { UserOrgnaisationInvitations } from './types'
+import { getSponsorEngagementUrl } from './utils'
+
+dotEnvConfig()
+dayjs.extend(utc)
+
+const fetchPendingEmails = async (pendingStatusId: number): Promise<UserOrgnaisationInvitations> => {
+  return prismaClient.userOrganisationInvitation.findMany({
+    where: { statusId: pendingStatusId, isDeleted: false },
+    distinct: ['userOrganisationId'],
+    orderBy: {
+      createdAt: Prisma.SortOrder.desc,
+    },
+    select: {
+      id: true,
+      messageId: true,
+      timestamp: true,
+      sentBy: true,
+      userOrganisation: {
+        include: {
+          user: {
+            select: {
+              email: true,
+            },
+          },
+        },
+      },
+    },
+  })
+}
+
+const updateEmailStatus = async (statusId: number, idsToUpdate: string[]) => {
+  if (idsToUpdate.length === 0) return { count: 0 }
+
+  return prismaClient.userOrganisationInvitation.updateMany({
+    data: {
+      statusId,
+    },
+    where: { messageId: { in: idsToUpdate } },
+  })
+}
+
+const fetchEmailStatus = async (
+  emailMessageId: string,
+  retryCount: number,
+  maxRetries = 1
+): Promise<EmailStatusResult | null> => {
+  if (retryCount > maxRetries) return null
+
+  try {
+    const { messageId, insights } = await emailService.getEmailInsights(emailMessageId)
+
+    return { messageId, insights }
+  } catch (error) {
+    logger.error('Error occurred fetching email status for messageId %s, retry count %s', emailMessageId, retryCount)
+
+    if (error instanceof TooManyRequestsException) {
+      logger.error('Rate limit exceeded. Trying again... ')
+
+      await new Promise((resolve) => {
+        setTimeout(resolve, 1000) // Delay 1 second
+      })
+
+      return fetchEmailStatus(emailMessageId, retryCount + 1)
+    }
+
+    logger.error(error)
+
+    return null
+  }
+}
+
+const processEmails = async () => {
+  // Fetch status ids for each email status
+  const { id: pendingStatusId } = await prismaClient.sysRefInvitationStatus.findFirstOrThrow({
+    where: { name: UserOrganisationInviteStatus.PENDING },
+  })
+
+  const { id: successStatusId } = await prismaClient.sysRefInvitationStatus.findFirstOrThrow({
+    where: { name: UserOrganisationInviteStatus.SUCCESS },
+  })
+
+  const { id: failedStatusId } = await prismaClient.sysRefInvitationStatus.findFirstOrThrow({
+    where: { name: UserOrganisationInviteStatus.FAILURE },
+  })
+
+  const pendingEmails = await fetchPendingEmails(pendingStatusId)
+
+  logger.info('Succesfully fetched %s pending emails', pendingEmails.length)
+
+  if (pendingEmails.length === 0) {
+    return
+  }
+
+  const getEmailStatusPromises = pendingEmails.map((email) => fetchEmailStatus(email.messageId, 0))
+  const emailStatusResults = await Promise.all(getEmailStatusPromises)
+  const successfulMessageIds = []
+  const failedEmailDetails: { messageId: string; userEmail: string; sentByEmail: string }[] = []
+  const todayUTCDate = dayjs.utc()
+
+  for (const email of pendingEmails) {
+    const messageId = email.messageId
+    const emailDetails = emailStatusResults.find((results) => results?.messageId === email.messageId)
+
+    if (!emailDetails) {
+      logger.info('No information for email with messageId %s', email.messageId)
+
+      continue
+    }
+
+    const { insights } = emailDetails
+    const events = insights[0]?.Events ?? []
+
+    events.sort((a, b) => new Date(b.Timestamp ?? 0).getTime() - new Date(a.Timestamp ?? 0).getTime())
+
+    const latestEvent = events[0]
+    const hoursSinceEmailSent = todayUTCDate.diff(email.timestamp.toISOString(), 'hours', true)
+
+    if (latestEvent.Type === EventType.DELIVERY) {
+      successfulMessageIds.push(messageId)
+    } else if (
+      latestEvent.Type === EventType.BOUNCE &&
+      latestEvent.Details?.Bounce?.BounceType === BounceType.PERMANENT
+    ) {
+      failedEmailDetails.push({
+        messageId,
+        userEmail: email.userOrganisation.user.email,
+        sentByEmail: email.sentBy.email,
+      })
path: apps/invitation-monitor/src/invitation-monitor.ts
user: login: kevinofficer
body: @AkADawg looks like these are causing your (or some) linting failures
created_at: 2025-04-09T15:27:23Z
author_association: COLLABORATOR
diff_hunk: @@ -1,6 +1,18 @@
 import { Mock } from 'ts-mockery'
-import type { UserOrganisationInvitation } from 'database'
+import type { UserOrgnaisationInvitations } from '../types'
path: apps/invitation-monitor/src/mocks/user-organisation-invitations.ts
user: login: con-nihr
body: Typo here
UserOrgnaisationInvitations-> UserOrganisationInvitations
created_at: 2025-04-10T14:28:01Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,11 @@
+export const getSponsorEngagementUrl = () => {
+  const env = process.env.APP_ENV
+
+  if (!env) return `http://localhost:${process.env.WEB_PORT ?? 3000}`
path: apps/invitation-monitor/src/utils.ts
user: login: con-nihr
body: Braces preferred over single line statements.
created_at: 2025-04-10T14:31:39Z
author_association: CONTRIBUTOR

PR comments:
user: login: github-actions[bot]
created_at: 2025-04-10T14:20:57Z
body: <!-- Jest Coverage Comment: unit-tests -->
# Unit tests coverage



| Title | Lines | Statements | Branches | Functions |
| --- | --- | --- | --- | --- |
| Web App | <a href="https://github.com/PA-NIHR-CRN/sponsor-engagement-web/blob/a65e9a02252f876d7298df45ce78c72cf2387c5a/README.md"><img alt="Coverage: 93%" src="https://img.shields.io/badge/Coverage-93%25-brightgreen.svg" /></a><br/> | 93.43% (2236/2393) | 83.82% (736/878) | 92.54% (385/416) |
| Ingest App | <a href="https://github.com/PA-NIHR-CRN/sponsor-engagement-web/blob/a65e9a02252f876d7298df45ce78c72cf2387c5a/README.md"><img alt="Coverage: 97%" src="https://img.shields.io/badge/Coverage-97%25-brightgreen.svg" /></a><br/> | 97.9% (281/287) | 85.71% (66/77) | 100% (86/86) |
| UI Package | <a href="https://github.com/PA-NIHR-CRN/sponsor-engagement-web/blob/a65e9a02252f876d7298df45ce78c72cf2387c5a/README.md"><img alt="Coverage: 98%" src="https://img.shields.io/badge/Coverage-98%25-brightgreen.svg" /></a><br/> | 99.04% (208/210) | 93.33% (42/45) | 96.96% (32/33) |
| Email Package | <a href="https://github.com/PA-NIHR-CRN/sponsor-engagement-web/blob/a65e9a02252f876d7298df45ce78c72cf2387c5a/README.md"><img alt="Coverage: 100%" src="https://img.shields.io/badge/Coverage-100%25-brightgreen.svg" /></a><br/> | 100% (2/2) | 100% (0/0) | 100% (0/0) |
| Auth Package | <a href="https://github.com/PA-NIHR-CRN/sponsor-engagement-web/blob/a65e9a02252f876d7298df45ce78c72cf2387c5a/README.md"><img alt="Coverage: 98%" src="https://img.shields.io/badge/Coverage-98%25-brightgreen.svg" /></a><br/> | 98.63% (72/73) | 91.17% (31/34) | 95.23% (20/21) |

author_association: NONE
user: login: sonarqubecloud[bot]
created_at: 2025-04-10T14:42:45Z
body: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=PA-NIHR-CRN_sponsor-engagement-web&pullRequest=386) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [2 New issues](https://sonarcloud.io/project/issues?id=PA-NIHR-CRN_sponsor-engagement-web&pullRequest=386&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=PA-NIHR-CRN_sponsor-engagement-web&pullRequest=386&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=PA-NIHR-CRN_sponsor-engagement-web&pullRequest=386&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=PA-NIHR-CRN_sponsor-engagement-web&pullRequest=386&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=PA-NIHR-CRN_sponsor-engagement-web&pullRequest=386&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=PA-NIHR-CRN_sponsor-engagement-web&pullRequest=386)


author_association: NONE