-
Notifications
You must be signed in to change notification settings - Fork 13
#4873 - Ministry: ability to delete restrictions - UI Changes #5205
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
#4873 - Ministry: ability to delete restrictions - UI Changes #5205
Conversation
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 the ability for ministry users to delete provincial student restrictions through both API and UI changes. The implementation includes soft-deletion functionality with audit trails and proper permission controls.
- Adds soft-delete capability for provincial restrictions with note requirements and audit tracking
- Updates UI components to display restriction status including deleted state and show delete actions
- Renames role from plural to singular form to comply with business requirements
Reviewed Changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| StudentRestrictions.vue | Adds delete restriction capability prop |
| Restrictions.vue | Simplifies status chip usage for institution restrictions |
| roles.ts | Renames role from plural to singular form |
| RestrictionContract.ts | Adds Deleted status enum value |
| Restriction.dto.ts | Updates DTOs with resolved/deleted tracking fields |
| RestrictionApi.ts | Adds delete restriction API method |
| RestrictionService.ts | Adds delete restriction service method |
| useRestriction.ts | Updates restriction status logic to handle deleted state |
| StatusChipRestriction.vue | Changes from status prop to isActive/deletedAt props |
| StudentRestrictions.vue | Implements delete functionality with modal and permission checks |
| ViewRestriction.vue | Updates to show resolved/deleted information from new fields |
| HistoryBypassedRestrictions.vue | Updates status chip usage |
| student-restriction-shared.service.ts | Removes error constants (moved to shared location) |
| error-code.constants.ts | Adds restriction-related error constants |
| student-restriction.service.ts | Implements delete restriction logic with concurrency handling |
| institution-restriction.service.ts | Updates import for moved error constant |
| restriction.controller.service.ts | Updates to return new resolved/deleted fields |
| restriction.aest.controller.ts | Adds delete endpoint with proper error handling |
| restriction.dto.ts | Adds delete restriction DTO |
| error-code.constants.ts | Adds restriction deletion error constants |
| roles.enum.ts | Updates role name to singular form |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
sources/packages/backend/apps/api/src/services/restriction/student-restriction.service.ts
Outdated
Show resolved
Hide resolved
sources/packages/web/src/components/common/students/StudentRestrictions.vue
Outdated
Show resolved
Hide resolved
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…i' of https://github.com/bcgov/SIMS into feature/#4873-ministry-ability-to-delete-restrictions-ui
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
Copilot reviewed 21 out of 21 changed files in this pull request and generated 3 comments.
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
sources/packages/web/src/components/common/students/StudentRestrictions.vue
Outdated
Show resolved
Hide resolved
sources/packages/backend/apps/api/src/services/restriction/student-restriction.service.ts
Show resolved
Hide resolved
| updatedBy: string; | ||
| resolvedBy: string; | ||
| deletedBy?: string; | ||
| deletedAt?: Date; |
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.
Minor. deletedAt comes from the summary API out DTO.
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.
Removed.
| @ApiUnprocessableEntityResponse({ | ||
| description: "Provincial restriction is already set as deleted.", | ||
| }) | ||
| @Patch("student/:studentId/student-restriction/:studentRestrictionId/delete") |
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 can see that existing APIs use student id on APIs that resolve and get restriction detail.
Are we keeping student id here to follow the existing APIs? or is there a different reason?
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.
Following the existing API pattern.
| await this.dataSource.transaction(async (transactionalEntityManager) => { | ||
| const now = new Date(); | ||
| const auditUser = { id: auditUserId } as User; | ||
| const note = await this.noteSharedService.createStudentNote( | ||
| studentId, | ||
| NoteType.Restriction, | ||
| noteDescription, | ||
| auditUserId, | ||
| transactionalEntityManager, | ||
| ); | ||
| const updateResult = await transactionalEntityManager | ||
| .getRepository(StudentRestriction) | ||
| .update( | ||
| { id: restriction.id, deletedAt: IsNull() }, | ||
| { | ||
| deletionNote: note, | ||
| deletedAt: now, | ||
| deletedBy: auditUser, | ||
| modifier: auditUser, | ||
| updatedAt: now, | ||
| }, | ||
| ); |
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 discussion about setting isActive to false while deleting a restriction(to reduce legacy integration side effects). Is it dropped to keep the deletion process simple?
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.
Not dropped, but not part of this ticket ACs. After multiple requests from DEVs to have it added, it ended up not being added here. Hence, I believe that it will be part of the other one.
| resolvedAt: institutionRestriction.updatedAt, | ||
| createdBy: getUserFullName(institutionRestriction.creator), | ||
| updatedBy: getUserFullName(institutionRestriction.modifier), | ||
| // Currently mapping modifier to resolvedBy as there is no resolvedBy for | ||
| // institutions restrictions but the API shares the same DTO. | ||
| resolvedBy: getUserFullName(institutionRestriction.modifier), |
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.
👍
| if (options?.extendedDetails) { | ||
| return { | ||
| ...restrictionDetail, | ||
| resolvedAt: studentRestriction.resolvedAt, | ||
| deletedAt: studentRestriction.deletedAt, | ||
| resolvedBy: getUserFullName(studentRestriction.resolvedBy) || undefined, | ||
| deletedBy: getUserFullName(studentRestriction.deletedBy) || undefined, | ||
| resolutionNote: studentRestriction.resolutionNote?.description, | ||
| deletionNote: studentRestriction.deletionNote?.description, | ||
| }; | ||
| } |
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.
👍
| {{ item.restrictionCode }} | ||
| </template> | ||
| <template #[`item.restrictionStatus`]="{ item }"> | ||
| <status-chip-restriction |
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 happens to a bypass record when the student restriction associated to that is deleted? this was something we weren't sure about how typeorm is handling it.
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.
Will be investigated and shared, not part of this PR.
sources/packages/web/src/components/common/restriction/ViewRestriction.vue
Outdated
Show resolved
Hide resolved
sources/packages/web/src/components/common/restriction/ViewRestriction.vue
Outdated
Show resolved
Hide resolved
| (props.restrictionData.isActive || | ||
| props.restrictionData.resolutionNote), | ||
| ); | ||
| (props.restrictionData.isActive || props.restrictionData.resolutionNote) |
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.
.restrictionData.isActive and restrictionData.resolutionNote are mutually exclusive.
Condition can be appended as (props.restrictionData.resolutionNote || !restrictionData.deletedAt) which will achieve the same?
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 mentioned code was already in place. I believe that it is better to read by keeping the existing logic and dealing with the deleted logic at the top.
Not willing to put effort into this.
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.
By effort, if you are saying the effort to validate different situations, it's fair enough. It is not a blocker as the code here works.
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.
Yes, this code was the same code that had issues recently. Effort-wise and I did not see an improvement in the suggested code, hence keeping it as it is since it was not considered as a blocker.
| @click="viewStudentRestriction(slotProps.data.restrictionId)" | ||
| >View</v-btn | ||
| > | ||
| <check-permission-role :role="Role.StudentDeleteRestriction"> |
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.
Minor. the vif can be added to check-permission-role to avoid check permission role component from being created.
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.
Moved v-if.
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 am not able to see the changes yet.
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.
Missing a push, it should be updated now.
| updatedBy: string; | ||
| resolvedBy: string; | ||
| deletedBy?: string; | ||
| deletedAt?: Date; |
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.
same here on deleteAt repeating.
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.
Just changed it.
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.
Great work enabling delete restrictions and other updates. I could see just 2 minor comments left.
|



API Related Changes
student-delete-restrictionstostudent-delete-restrictionto comply with the business AC.resolvedAt,resolvedBy,deletedAt,deletedBy.modifier/updatedAtas before.UI Related Changes
deletedAt; the only purpose would be to display the correct status for records that will not be shown.ApiProcessErrorfor possible concurrency error while deleting a restriction that is already deleted.New deleted status for the Ministry
Please note that the restriction badge on the top, as shown below, does not consider the deleted records (as expected).
Resolved and later deleted restriction
Never resolved, and deleted restriction
Resolved restriction getting data from the new columns
Feferal restriction does not have "Delete" available
New delete modal