-
Notifications
You must be signed in to change notification settings - Fork 13
#4823 - Parent Declare: Email Notification (Part 1) #4927
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
...s/src/migrations/1752517099854-InsertParentDeclarationRequiredParentCanReportNotification.ts
Show resolved
Hide resolved
...s/src/migrations/1752517099854-InsertParentDeclarationRequiredParentCanReportNotification.ts
Outdated
Show resolved
Hide resolved
.../packages/backend/apps/workers/src/controllers/supporting-user/supporting-user.controller.ts
Outdated
Show resolved
Hide resolved
.../packages/backend/apps/workers/src/controllers/supporting-user/supporting-user.controller.ts
Outdated
Show resolved
Hide resolved
| ? "parent" | ||
| : "partner", | ||
| parentFullName: fullName, | ||
| applicationNumber: application.applicationNumber, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
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
.../packages/backend/apps/workers/src/controllers/supporting-user/supporting-user.controller.ts
Outdated
Show resolved
Hide resolved
...ackages/backend/libs/services/src/notifications/notification/notification-actions.service.ts
Outdated
Show resolved
Hide resolved
...ackages/backend/libs/services/src/notifications/notification/notification-actions.service.ts
Outdated
Show resolved
Hide resolved
...ackages/backend/libs/services/src/notifications/notification/notification-actions.service.ts
Outdated
Show resolved
Hide resolved
sources/packages/backend/libs/services/src/notifications/notification/notification.model.ts
Outdated
Show resolved
Hide resolved
|
Good start @sh16011993 Please have a look at the comments. |
There was a problem hiding this 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 { |
Copilot
AI
Jul 15, 2025
There was a problem hiding this comment.
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.
| export interface ParentDeclarationRequiredParentCanReportNotification { | |
| export interface ParentDeclarationRequiredNotification { |
| 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 }, |
Copilot
AI
Jul 15, 2025
There was a problem hiding this comment.
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.
| 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, |
| jobLogger.error(message); | ||
| return job.error(SUPPORTING_USER_FULL_NAME_NOT_RESOLVED, message); | ||
| } | ||
| } |
Copilot
AI
Jul 15, 2025
There was a problem hiding this comment.
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.
| } | |
| } | |
| // 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}`; | |
| } |
| 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, | ||
| }, |
Copilot
AI
Jul 15, 2025
There was a problem hiding this comment.
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.
| 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, |
...ps/db-migrations/src/sql/NotificationMessages/Insert-parent-declaration-required-message.sql
Show resolved
Hide resolved
...rations/src/sql/NotificationMessages/Rollback-insert-parent-declaration-required-message.sql
Outdated
Show resolved
Hide resolved
.../packages/backend/apps/workers/src/controllers/supporting-user/supporting-user.controller.ts
Outdated
Show resolved
Hide resolved
|
Thanks for making the changes @sh16011993 . It is almost there. Added few comments. |
bidyashish
left a comment
There was a problem hiding this 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; | ||
| } |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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...
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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,
There was a problem hiding this comment.
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.
|
bidyashish
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please review
dheepak-aot
left a comment
There was a problem hiding this 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!
bidyashish
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM




As a part of this PR, the following were completed:
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
Parent 2
Parent unable to report their declaration
Migration rollback: