Skip to content

Conversation

@sh16011993
Copy link
Collaborator

@sh16011993 sh16011993 commented Jul 14, 2025

As a part of this PR, the following were completed:

  • Added DB migrations and added code logic to send notification for the following scenarios:
  1. Parent able to report their declaration
  2. Parent unable to report their declaration

Note: E2E tests will be part of the next PR.

Screenshots:

NOTE: The content for the below email notifications will have its wording revised by the business later. All the required variables from the business have been passed into the templates.

Parents able to report their declaration

Parent 1

image

Parent 2

image

Parent unable to report their declaration

image

Migration rollback:

image

@sh16011993 sh16011993 self-assigned this Jul 14, 2025
@sh16011993 sh16011993 added Camunda Workers DB DB migration involved labels Jul 14, 2025
@sh16011993 sh16011993 requested a review from Copilot July 14, 2025 23:03

This comment was marked as outdated.

@sh16011993 sh16011993 changed the title 4823 parent declare email notification #4823 - Parent Declare: Email Notification Jul 14, 2025
@sh16011993 sh16011993 changed the title #4823 - Parent Declare: Email Notification #4823 - Parent Declare: Email Notification (Part 1) Jul 15, 2025
@dheepak-aot dheepak-aot self-requested a review July 15, 2025 18:22
? "parent"
: "partner",
parentFullName: fullName,
applicationNumber: application.applicationNumber,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the application number is required by the business, can we have this AC updated?
image

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have mentioned it to @CarlyCotton

@dheepak-aot
Copy link
Collaborator

Good start @sh16011993 Please have a look at the comments.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements email notifications for parent declaration scenarios in a student information management system. The changes add support for notifying students when parent declaration is required for applications from 2025 program year onwards, covering both cases where parents can report and cannot report their declarations.

Key Changes:

  • Added two new notification message types for parent declaration scenarios
  • Implemented notification services and data models for both parent reporting scenarios
  • Integrated notification triggers into the supporting user creation workflow

Reviewed Changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
notification.model.ts Added enum values for new parent declaration notification types
notification.model.ts (services) Defined TypeScript interfaces for notification data structures
notification-actions.service.ts Implemented notification creation methods for both parent scenarios
supporting-user.controller.ts Integrated notification triggers into user creation workflow
Migration files Added database migrations to insert notification message configurations

supportingUserType: NotificationSupportingUserType;
}

export interface ParentDeclarationRequiredParentCanReportNotification {
Copy link

Copilot AI Jul 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The interfaces ParentDeclarationRequiredParentCanReportNotification and ParentDeclarationRequiredParentCannotReportNotification are identical. Consider creating a single interface like ParentDeclarationRequiredNotification to reduce code duplication.

Suggested change
export interface ParentDeclarationRequiredParentCanReportNotification {
export interface ParentDeclarationRequiredNotification {

Copilot uses AI. Check for mistakes.
Comment on lines +1254 to +1278
const auditUser = this.systemUsersService.systemUser;
const { templateId } =
await this.notificationMessageService.getNotificationMessageDetails(
NotificationMessageType.ParentDeclarationRequiredParentCanReportNotification,
);
const supportingUserInformationNotification = {
userId: notification.userId,
messageType:
NotificationMessageType.ParentDeclarationRequiredParentCanReportNotification,
messagePayload: {
email_address: notification.toAddress,
template_id: templateId,
personalisation: {
givenNames: notification.givenNames ?? "",
lastName: notification.lastName,
parentFullName: notification.parentFullName,
applicationNumber: notification.applicationNumber,
supportingUserType: notification.supportingUserType,
},
},
};
await this.notificationService.saveNotifications(
[supportingUserInformationNotification],
auditUser.id,
{ entityManager },
Copy link

Copilot AI Jul 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The methods saveParentDeclarationRequiredParentCanReportNotification and saveParentDeclarationRequiredParentCannotReportNotification contain nearly identical logic. Consider extracting a common helper method that accepts the notification type as a parameter to reduce code duplication.

Suggested change
const auditUser = this.systemUsersService.systemUser;
const { templateId } =
await this.notificationMessageService.getNotificationMessageDetails(
NotificationMessageType.ParentDeclarationRequiredParentCanReportNotification,
);
const supportingUserInformationNotification = {
userId: notification.userId,
messageType:
NotificationMessageType.ParentDeclarationRequiredParentCanReportNotification,
messagePayload: {
email_address: notification.toAddress,
template_id: templateId,
personalisation: {
givenNames: notification.givenNames ?? "",
lastName: notification.lastName,
parentFullName: notification.parentFullName,
applicationNumber: notification.applicationNumber,
supportingUserType: notification.supportingUserType,
},
},
};
await this.notificationService.saveNotifications(
[supportingUserInformationNotification],
auditUser.id,
{ entityManager },
await this.saveParentDeclarationRequiredNotification(
NotificationMessageType.ParentDeclarationRequiredParentCanReportNotification,
notification,
entityManager,

Copilot uses AI. Check for mistakes.
jobLogger.error(message);
return job.error(SUPPORTING_USER_FULL_NAME_NOT_RESOLVED, message);
}
}
Copy link

Copilot AI Jul 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment 'If the full name is not provided, use the student' appears to be incomplete or incorrect. The code logic doesn't show any fallback to using student information when full name is not provided.

Suggested change
}
}
// If the full name is not resolved, use the student's full name as a fallback.
if (!fullName) {
fullName = `${application.student.user.firstName} ${application.student.user.lastName}`;
}

Copilot uses AI. Check for mistakes.
Comment on lines 189 to 218
if (isAbleToReport) {
await this.notificationActionsService.saveParentDeclarationRequiredParentCanReportNotification(
{
givenNames: application.student.user.firstName,
lastName: application.student.user.lastName,
toAddress: application.student.user.email,
userId: application.student.user.id,
supportingUserType:
job.variables.supportingUserType === "Parent"
? "parent"
: "partner",
parentFullName: fullName,
applicationNumber: application.applicationNumber,
},
entityManager,
);
} else {
await this.notificationActionsService.saveParentDeclarationRequiredParentCannotReportNotification(
{
givenNames: application.student.user.firstName,
lastName: application.student.user.lastName,
toAddress: application.student.user.email,
userId: application.student.user.id,
supportingUserType:
job.variables.supportingUserType === "Parent"
? "parent"
: "partner",
parentFullName: fullName,
applicationNumber: application.applicationNumber,
},
Copy link

Copilot AI Jul 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The notification creation logic contains significant code duplication between the if and else blocks. Consider extracting the common notification data structure into a variable and only varying the notification service method call.

Suggested change
if (isAbleToReport) {
await this.notificationActionsService.saveParentDeclarationRequiredParentCanReportNotification(
{
givenNames: application.student.user.firstName,
lastName: application.student.user.lastName,
toAddress: application.student.user.email,
userId: application.student.user.id,
supportingUserType:
job.variables.supportingUserType === "Parent"
? "parent"
: "partner",
parentFullName: fullName,
applicationNumber: application.applicationNumber,
},
entityManager,
);
} else {
await this.notificationActionsService.saveParentDeclarationRequiredParentCannotReportNotification(
{
givenNames: application.student.user.firstName,
lastName: application.student.user.lastName,
toAddress: application.student.user.email,
userId: application.student.user.id,
supportingUserType:
job.variables.supportingUserType === "Parent"
? "parent"
: "partner",
parentFullName: fullName,
applicationNumber: application.applicationNumber,
},
const notificationData = {
givenNames: application.student.user.firstName,
lastName: application.student.user.lastName,
toAddress: application.student.user.email,
userId: application.student.user.id,
supportingUserType:
job.variables.supportingUserType === "Parent"
? "parent"
: "partner",
parentFullName: fullName,
applicationNumber: application.applicationNumber,
};
if (isAbleToReport) {
await this.notificationActionsService.saveParentDeclarationRequiredParentCanReportNotification(
notificationData,
entityManager,
);
} else {
await this.notificationActionsService.saveParentDeclarationRequiredParentCannotReportNotification(
notificationData,

Copilot uses AI. Check for mistakes.
@dheepak-aot
Copy link
Collaborator

Thanks for making the changes @sh16011993 . It is almost there. Added few comments.

Copy link
Contributor

@bidyashish bidyashish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please review @sh16011993

applicationNumber: string;
userId: number;
supportingUserType: NotificationSupportingUserType;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the need of same interface data with different name, ParentInformationRequiredFromParentNotification and ParentInformationRequiredFromParentNotification?
It can be just 1 interface

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For notifications specifically, we follow this pattern of creating a method with its interface irrespective of its data.

* @param entityManager entity manager to execute in transaction.
*/
async saveParentInformationRequiredFromParentNotification(
notification: ParentInformationRequiredFromParentNotification,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can be just 1 function as it is repeating.
async saveParentInformationRequiredFromParentNotification...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return job.error(SUPPORTING_USER_FULL_NAME_NOT_RESOLVED, message);
}
}
const isAbleToReport = job.variables.isAbleToReport;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const isAbleToReport = job.variables.isAbleToReport; can be reverted.
and used as previous isAbleToReport: job.variables.isAbleToReport,

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I created a constant because I had to use it in multiple places.

@sonarqubecloud
Copy link

Copy link
Contributor

@bidyashish bidyashish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please review

@github-actions
Copy link

Backend Unit Tests Coverage Report

Totals Coverage
Statements: 21.65% ( 4092 / 18903 )
Methods: 9.67% ( 234 / 2420 )
Lines: 25% ( 3539 / 14154 )
Branches: 13.7% ( 319 / 2329 )

@github-actions
Copy link

E2E Workflow Workers Coverage Report

Totals Coverage
Statements: 73.08% ( 725 / 992 )
Methods: 73.5% ( 86 / 117 )
Lines: 75.13% ( 568 / 756 )
Branches: 59.66% ( 71 / 119 )

@bidyashish bidyashish self-requested a review July 16, 2025 16:24
@github-actions
Copy link

E2E Queue Consumers Coverage Report

Totals Coverage
Statements: 86.43% ( 1548 / 1791 )
Methods: 84.62% ( 176 / 208 )
Lines: 88.75% ( 1278 / 1440 )
Branches: 65.73% ( 94 / 143 )

@github-actions
Copy link

E2E SIMS API Coverage Report

Totals Coverage
Statements: 73.37% ( 7198 / 9811 )
Methods: 70.83% ( 884 / 1248 )
Lines: 76.83% ( 5576 / 7258 )
Branches: 56.55% ( 738 / 1305 )

Copy link
Collaborator

@dheepak-aot dheepak-aot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for making the changes @sh16011993 Good job!

Copy link
Contributor

@bidyashish bidyashish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@sh16011993 sh16011993 added this pull request to the merge queue Jul 16, 2025
Merged via the queue into main with commit f180d01 Jul 16, 2025
22 checks passed
@sh16011993 sh16011993 deleted the 4823_parent_declare_email_notification branch July 16, 2025 18:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Camunda Workers DB DB migration involved

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants