Skip to content

#5099 - Bypass Program Suspension Restriction: UI#5859

Merged
sh16011993 merged 22 commits intomainfrom
feature/#5099-bypass-program-suspension-restriction-ui
Mar 12, 2026
Merged

#5099 - Bypass Program Suspension Restriction: UI#5859
sh16011993 merged 22 commits intomainfrom
feature/#5099-bypass-program-suspension-restriction-ui

Conversation

@sh16011993
Copy link
Collaborator

@sh16011993 sh16011993 commented Mar 6, 2026

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

History of Bypassed Restrictions:

image

Bypass Restriction Modal Dialog:

image

Bypassed Institution Restriction View:

image

Added / Updated the following e2e tests:

ApplicationRestrictionBypassAESTController(e2e)-getAvailableRestrictionsToBypass.
√ Should list all the active restrictions and not the ones already bypassed for a part-time application when there are some restrictions bypassed and some others not.

image

ApplicationRestrictionBypassAESTController(e2e)-bypassRestriction
√ Should be able to create a bypass when there is not an active bypass for the same institution restriction.
√ Should throw an HTTP error while creating a bypass when there is an active bypass for the same active institution restriction.
√ Should throw an HTTP error while creating a bypass when institution restriction is not active.

image

ApplicationRestrictionBypassAESTController(e2e)-getApplicationRestrictionBypass.
√ Should get an institution application restriction bypass for a submitted part-time application when there is an application restriction bypass with the required id.

image

@sh16011993 sh16011993 marked this pull request as draft March 6, 2026 01:07
@sh16011993 sh16011993 self-assigned this Mar 6, 2026
- EOL formatting changed from CRLF to LF
- Fixed the failing e2e tests
- Fixed failing e2e tests
- Fixed the failing e2e tests
@sh16011993 sh16011993 marked this pull request as ready for review March 6, 2026 23:54
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

Extends the “application restriction bypass” feature so AEST users can bypass both student and institution restrictions, and updates the web UI to display/select restriction type (Student vs Institution) when creating/viewing bypasses.

Changes:

  • Updated API/service contracts and logic to support bypassing institution restrictions in addition to student restrictions.
  • Enhanced UI modal and supporting components to display restriction type and submit the new payload shape.
  • Updated/added e2e tests for the new “available restrictions to bypass” and “bypass restriction” scenarios.

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
sources/packages/web/src/views/aest/institution/Restrictions.vue Switched from RestrictionEntityType to RestrictedParty when passing restriction party type.
sources/packages/web/src/types/vuetify.ts Modified shared SelectItemType to include restriction party type.
sources/packages/web/src/types/contracts/RestrictionContract.ts Renamed enum RestrictionEntityType to RestrictedParty and fixed comment punctuation.
sources/packages/web/src/services/http/dto/ApplicationRestrictionBypass.dto.ts Updated web DTOs to support both student/institution restrictions and new field names.
sources/packages/web/src/services/http/ApplicationRestrictionBypassApi.ts Renamed API method and updated return type for available restrictions.
sources/packages/web/src/services/ApplicationRestrictionBypassService.ts Renamed service method and updated types to align with API changes.
sources/packages/web/src/components/generic/StatusChipClientType.vue New chip component to label restriction party type.
sources/packages/web/src/components/common/students/StudentRestrictions.vue Updated imports/returned bindings for RestrictedParty.
sources/packages/web/src/components/aest/students/bypassedRestrictions/BypassRestrictionModal.vue Updated modal to select restriction + show party type chip; updated payload fields.
sources/packages/backend/libs/sims-db/src/entities/institution-restriction.model.ts Added relation from institution restriction to application restriction bypasses.
sources/packages/backend/apps/api/src/services/application-restriction-bypass/application-restriction-bypass.service.ts Added institution restriction support in option listing and bypass creation validations/persistence.
sources/packages/backend/apps/api/src/services/application-restriction-bypass/application-restriction-bypass.models.ts Updated internal models to be restriction-party aware.
sources/packages/backend/apps/api/src/route-controllers/application-restriction-bypass/models/application-restriction-bypass.dto.ts Updated API DTOs for new payload/response shapes including restriction party type.
sources/packages/backend/apps/api/src/route-controllers/application-restriction-bypass/application-restriction-bypass.aest.controller.ts Updated endpoints/response mapping and error handling for institution restrictions.
sources/packages/backend/apps/api/src/route-controllers/application-restriction-bypass/tests/e2e/application-restriction-bypass.aest.controller.getAvailableRestricitionsToBypass.e2e-spec.ts Expanded e2e coverage for listing available restrictions, including institution restrictions.
sources/packages/backend/apps/api/src/route-controllers/application-restriction-bypass/tests/e2e/application-restriction-bypass.aest.controller.getApplicationRestrictionBypass.e2e-spec.ts Updated assertions for new response shape (restrictionId, restrictionType).
sources/packages/backend/apps/api/src/route-controllers/application-restriction-bypass/tests/e2e/application-restriction-bypass.aest.controller.bypassRestriction.e2e-spec.ts Added institution restriction bypass creation and error scenarios.
sources/packages/backend/apps/api/src/constants/error-code.constants.ts Added new error codes for institution restriction bypass scenarios.
Comments suppressed due to low confidence (1)

sources/packages/backend/apps/api/src/route-controllers/application-restriction-bypass/tests/e2e/application-restriction-bypass.aest.controller.getAvailableRestricitionsToBypass.e2e-spec.ts:30

  • Test file name contains a typo (getAvailableRestricitionsToBypass) and does not match the project’s e2e naming convention ([feature].[client-type].controller.[method].e2e-spec.ts) or the controller method name getAvailableRestrictionsToBypass. Please rename the file to keep conventions consistent and make tests easier to locate.
describe("ApplicationRestrictionBypassAESTController(e2e)-getAvailableRestrictionsToBypass.", () => {
  let app: INestApplication;
  let db: E2EDataSources;

Comment on lines +325 to +349
if (institutionApplication) {
const bypassedInstitutionRestrictionIds = new Set(
institutionApplication.currentAssessment.offering.institutionLocation.institution.restrictions
.flatMap(
(institutionRestriction) =>
institutionRestriction.applicationRestrictionBypasses,
)
.filter((bypass) => bypass.isActive)
.map((bypass) => bypass.institutionRestriction.id),
);

return studentRestrictionsThatAreNotBypassed
.filter((studentRestriction) =>
allowedRestrictionActions.some((actionType) =>
studentRestriction.restriction.actionType.includes(actionType),
),
)
.map((studentRestriction) => ({
studentRestrictionId: studentRestriction.id,
restrictionCode: studentRestriction.restriction.restrictionCode,
studentRestrictionCreatedAt: studentRestriction.createdAt,
}))
.sort((a, b) => a.restrictionCode.localeCompare(b.restrictionCode));
const institutionRestrictionsThatAreNotBypassed =
institutionApplication.currentAssessment.offering.institutionLocation.institution.restrictions.filter(
(institutionRestriction) =>
!bypassedInstitutionRestrictionIds.has(institutionRestriction.id),
);
mappedInstitutionRestrictionsNotBypassed =
institutionRestrictionsThatAreNotBypassed.map(
(institutionRestriction) => ({
restrictionId: institutionRestriction.id,
restrictionCode: institutionRestriction.restriction.restrictionCode,
restrictionCreatedAt: institutionRestriction.createdAt,
restrictionType: RestrictedParty.Institution,
}),
);
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

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

Institution restrictions are currently returned as bypass options without filtering by the allowed restriction action types for the application’s offering intensity (unlike student restrictions, which are filtered). If institution restrictions can include non-disbursement-blocking action types, this will expose/allow bypasses that should not be available. Consider applying the same allowedRestrictionActions filter using institutionRestriction.restriction.actionType (the query already selects actionType).

Copilot uses AI. Check for mistakes.
- Addressed the copilot review comments
@weskubo-cgi weskubo-cgi self-requested a review March 9, 2026 19:23
@dheepak-aot dheepak-aot self-requested a review March 9, 2026 19:56
Comment on lines +135 to +139
const remitRestriction = await db.restriction.findOne({
where: {
restrictionCode: RestrictionCode.REMIT,
},
});
Copy link
Collaborator

Choose a reason for hiding this comment

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

Remit restriction must technically not be valid to create a bypass as it does not block disbursement.

I believe there is an existing GAP in API not validating the restriction actions while creating bypass.

@dheepak-aot
Copy link
Collaborator

Thanks for making the changes. Added few more comments.

- Review Comments
- Review Comments
* @returns allowed restriction actions.
*/
private getAllowedRestrictionActions(
offeringIntensity: string,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please use the type OfferingIntensity

RestrictionActionType.StopPartTimeDisbursement,
];
default:
return [];
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please throw error on default. throw new Error("Invalid offering intensity.")

})
bypassRemovedDate?: Date;

getBypassRestriction(): StudentRestriction | InstitutionRestriction {
Copy link
Collaborator

@dheepak-aot dheepak-aot Mar 12, 2026

Choose a reason for hiding this comment

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

Please add comments to the method. Same for other method as well.

Comment on lines +165 to +169
if (this.studentRestriction && this.institutionRestriction) {
throw new Error(
"Cannot have both student restriction and institution restriction associated with a restriction bypass.",
);
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

This condition is not necessary as both restrictions cannot co-exist in DB together.

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 and addressing the validation missing for action types on bypass create. Looks good. Added few last comments to wrap up.

- Review Comments
@github-actions
Copy link

Backend Unit Tests Coverage Report

Totals Coverage
Statements: 20.2% ( 4565 / 22600 )
Methods: 9.53% ( 262 / 2750 )
Lines: 24.52% ( 3917 / 15974 )
Branches: 9.96% ( 386 / 3876 )

@sonarqubecloud
Copy link

@github-actions
Copy link

E2E Workflow Workers Coverage Report

Totals Coverage
Statements: 48.61% ( 2712 / 5579 )
Methods: 38.57% ( 285 / 739 )
Lines: 55.39% ( 2049 / 3699 )
Branches: 33.13% ( 378 / 1141 )

@github-actions
Copy link

E2E Queue Consumers Coverage Report

Totals Coverage
Statements: 79.6% ( 9155 / 11501 )
Methods: 78.79% ( 1181 / 1499 )
Lines: 82.83% ( 6881 / 8307 )
Branches: 64.48% ( 1093 / 1695 )

@github-actions
Copy link

E2E SIMS API Coverage Report

Totals Coverage
Statements: 64.52% ( 12677 / 19649 )
Methods: 60.67% ( 1473 / 2428 )
Lines: 68.25% ( 9247 / 13548 )
Branches: 53.28% ( 1957 / 3673 )

@sh16011993 sh16011993 enabled auto-merge March 12, 2026 17:07
Copy link
Collaborator

@weskubo-cgi weskubo-cgi left a comment

Choose a reason for hiding this comment

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

Approved.

@@ -0,0 +1,16 @@
<template>
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this a good use for ChipTag.vue. You won't need either RestrictedPartyChip.vue or ChipWithTag. We should confirm the color for the font and also look at whether the chips can be consistently right aligned in the v-select. If they can't be nicely right aligned then we can leave them as is.

Image

import { computed } from "vue";

const props = defineProps<{
clientType: RestrictedParty.Student | RestrictedParty.Institution;
Copy link
Collaborator

Choose a reason for hiding this comment

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

FYI clientType is still being used but as suggested I think we can just use ChipTag.vue in which case this won't matter.

@sh16011993 sh16011993 added this pull request to the merge queue Mar 12, 2026
Merged via the queue into main with commit 3bdaf7e Mar 12, 2026
22 checks passed
@sh16011993 sh16011993 deleted the feature/#5099-bypass-program-suspension-restriction-ui branch March 12, 2026 17:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants