#3553 - Revise Impact of BC Lifetime Max Restriction to only block Loan#5592
Conversation
There was a problem hiding this comment.
Pull request overview
This PR refactors BC funding restrictions to provide more granular control by separating restrictions into distinct loan and grant types. Previously, StopFullTimeBCFunding and StopPartTimeBCFunding restricted all BC funding together. Now, full-time restrictions are split into StopFullTimeBCLoan (BCSL) and StopFullTimeBCGrants (BCAG, BGPD, SBSD), while StopPartTimeBCFunding is renamed to StopPartTimeBCGrants (BCAG, SBSD). The BCLM restriction is updated to block only BC loans while allowing grants to be disbursed.
Key changes:
- Database migration adds new restriction action types and updates existing restrictions to use them
- E-Cert generation logic now evaluates restrictions separately for loan vs. grant funding types
- Comprehensive test coverage validates the new behavior, including scenarios with multiple restrictions
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| RestrictionContract.ts (web) | Updated frontend enum with new restriction action types and consistent naming (full-time/part-time with hyphens) |
| restriction-action-type.type.ts | Updated backend enum to match frontend, splitting BC funding into loan and grant types |
| e-cert-steps-utils.ts | Added logic to map restrictions to specific funding types (loan vs grant) and build restriction map per disbursement value type |
| apply-stop-bc-funding-restriction-step.ts | Refactored to use new funding type restriction map instead of single restriction check |
| apply-overawards-balance-step.ts | Updated to use new funding type map for determining which awards should not be deducted from overawards |
| validate-disbursement-base.ts | Updated function signature to accept array of action types |
| application-restriction-bypass.service.ts | Updated queries to check for both loan and grant restriction types |
| application-restriction-bypass.ts (test factory) | Added RestrictionType filter to ensure proper restriction selection in tests |
| Update-restriction-action-types-BC-funding-to-loan-and-grants.sql | Migration to create new enum with split types and update column values |
| Rollback-update-restriction-action-types-BC-funding-to-loan-and-grants.sql | Rollback migration to revert enum types (incomplete for BCLM) |
| Update-stop-funding-loan-and-grants.sql | Updates specific restrictions (BCLM, B2D, B3D, B2, Z1, B6A) to use new action types |
| Rollback-update-stop-funding-loan-and-grants.sql | Reverts restrictions to previous types (incomplete for BCLM) |
| UpdateBCFundingToLoanAndGrants1767817093895.ts | Migration class that executes SQL migrations in correct order |
| ecert-full-time-process-integration.scheduler.e2e-spec.ts | Added test for multiple restrictions blocking both loan and grant; updated existing tests for new BCLM behavior |
| ecert-part-time-process-integration.scheduler.e2e-spec.ts | Updated tests to use new restriction types and verify proper filtering |
| e-cert-utils.ts | Enhanced awardAssert to support validation of specific restriction IDs |
| disbursement-schedule.models.ts | Removed unused interfaces |
...es/backend/apps/db-migrations/src/migrations/1767817093895-UpdateBCFundingToLoanAndGrants.ts
Outdated
Show resolved
Hide resolved
...end/apps/db-migrations/src/sql/Restrictions/Rollback-update-stop-funding-loan-and-grants.sql
Show resolved
Hide resolved
...ntegrations/src/services/disbursement-schedule/e-cert-processing-steps/e-cert-steps-utils.ts
Outdated
Show resolved
Hide resolved
| RestrictionActionType.StopFullTimeBCLoan, | ||
| RestrictionActionType.StopFullTimeBCGrants, | ||
| RestrictionActionType.StopFullTimeDisbursement, | ||
| RestrictionActionType.StopPartTimeBCFunding, | ||
| RestrictionActionType.StopPartTimeBCGrants, | ||
| RestrictionActionType.StopPartTimeDisbursement, |
| restrictionAmountSubtracted: 0, | ||
| effectiveAmount: 499, |
| restrictionType: RestrictionType.Provincial, | ||
| actionEffectiveConditions: IsNull(), |
| const restriction = await db.restriction.findOne({ | ||
| select: { id: true }, | ||
| where: { | ||
| restrictionType: RestrictionType.Provincial, | ||
| actionEffectiveConditions: IsNull(), | ||
| actionType: ArrayContains([ | ||
| RestrictionActionType.StopPartTimeBCFunding, | ||
| RestrictionActionType.StopPartTimeBCGrants, | ||
| ]), | ||
| }, | ||
| }); |
There was a problem hiding this comment.
As we are seeing this very often, it seems like a good candidate to be in factory.
There was a problem hiding this comment.
I agree, but this PR is not even using new "copies" of it, and the highlighted changes are already some minor fixes and improvements. I will refrain from doing it at this moment.
| /** | ||
| * Map of restriction action types associated with the offering intensity. | ||
| */ | ||
| const RESTRICTION_ACTION_TYPE_INTENSITY_MAP = new Map([ |
There was a problem hiding this comment.
STOP_FUNDING_ACTION_INTENSITY_MAP ?
|
| if (!restriction) { | ||
| log.info("Checking stop funding restriction."); | ||
| const stopFundingMap = | ||
| getStopFundingTypesAndRestrictionsMap(eCertDisbursement); |
There was a problem hiding this comment.
I feel that the existing idea of using the shouldStopBCFunding could be more simple and used with minor enhancement.
With a draft idea like this.
export function getStopFundingRestriction(
eCertDisbursement: EligibleECertDisbursement,
disbursementValue: DisbursementValue,
): ActiveRestriction | undefined {
const stopFullTimeFundingActionTypeMap = {
[DisbursementValueType.BCGrant]: RestrictionActionType.StopFullTimeBCGrants,
[DisbursementValueType.BCTotalGrant]:
RestrictionActionType.StopFullTimeBCGrants,
[DisbursementValueType.BCLoan]: RestrictionActionType.StopFullTimeBCLoan,
};
const stopPartTimeFundingActionTypeMap = {
[DisbursementValueType.BCGrant]: RestrictionActionType.StopPartTimeBCGrants,
[DisbursementValueType.BCTotalGrant]:
RestrictionActionType.StopPartTimeBCGrants,
};
const stopFundingActionTypeMap =
eCertDisbursement.offering.offeringIntensity === OfferingIntensity.fullTime
? stopFullTimeFundingActionTypeMap
: stopPartTimeFundingActionTypeMap;
const restrictionActionType =
stopFundingActionTypeMap[disbursementValue.valueType];
if (!restrictionActionType) {
return;
}
const [stopFundingRestriction] = getRestrictionsByActionType(
eCertDisbursement,
restrictionActionType,
);
return stopFundingRestriction;
}
``There was a problem hiding this comment.
- The proposed method does not consider the fact that multiple restrictions can possibly impact an award. The idea was to create a method with the ability to expose all the restrictions, supporting the current approach (that requires only one) but also future implementations.
- The
BCTotalGrantis purposely no longer considered as it should result as zero due to the other grants. - I am missing what would be the "minor enhancement" with the proposed solution.
Please let me know if it would be a blocker.
There was a problem hiding this comment.
The outcome of the method put in the PR is good. Only feeling was that the method handles data at multiple levels which makes it look confusing. But not a blocker.
dheepak-aot
left a comment
There was a problem hiding this comment.
Great work and improvement to the granularity of the funding type restrictions. 👍
| resultMap.set(DisbursementValueType.BCLoan, [ | ||
| ...(resultMap.get(DisbursementValueType.BCLoan) || []), | ||
| restriction, | ||
| ]); | ||
| } | ||
| if ( | ||
| BC_GRANTS_RESTRICTION_ACTIONS.some((action) => | ||
| restriction.actions.includes(action), | ||
| ) | ||
| ) { | ||
| resultMap.set(DisbursementValueType.BCGrant, [ | ||
| ...(resultMap.get(DisbursementValueType.BCGrant) || []), | ||
| restriction, | ||
| ]); |
sh16011993
left a comment
There was a problem hiding this comment.
Splendid work @andrewsignori-aot 👍 Thanks for clarifying my questions.



StopFullTimeBCFundingintoStopFullTimeBCLoanandStopFullTimeBCGrantsto allow restriction to be configured with a more granular option.StopPartTimeBCFundingtoStopPartTimeBCGrantssince part-time has no loan.B2D,B3D,B2,Z1to use the new action types, keeping their existing behavior.BCLMto block only BC Loan while still allowing grants disbursements.E2E Tests
Migration Rollback