#5722 - Parent current year income appeal#6029
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a new “Parent Current Year Income” appeal form and wires it into the full-time 2026-2027 assessment workflow so the assessment gateway can surface eligibility for the new appeal.
Changes:
- Added a new dynamic form definition:
parentcurrentyearincomeappeal.json. - Updated workflow eligibility outputs and assessment gateway eligibility list to include the parent current-year-income appeal.
- Added DB migration + SQL scripts to register the new dynamic form configuration.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| sources/packages/forms/src/form-definitions/parentcurrentyearincomeappeal.json | Introduces the new Form.io appeal form definition for parent current-year income. |
| sources/packages/backend/workflow/src/workflow-definitions/fulltime-assessment-2026-2027.bpmn | Outputs a new workflow variable to indicate eligibility for the parent current-year-income appeal. |
| sources/packages/backend/workflow/src/workflow-definitions/assessment-gateway-v2.bpmn | Adds the new appeal form into the gateway’s computed eligibility list. |
| sources/packages/backend/apps/db-migrations/src/sql/DynamicFormConfigurations/Add-parent-current-year-income.sql | Inserts a new dynamic form configuration record for the appeal. |
| sources/packages/backend/apps/db-migrations/src/sql/DynamicFormConfigurations/Rollback-add-parent-current-year-income.sql | Removes the inserted dynamic form configuration record on rollback. |
| sources/packages/backend/apps/db-migrations/src/migrations/1775854087027-AddParentCurrentYearIncomeAppeal.ts | Runs the add/rollback SQL scripts as a TypeORM migration. |
| <bpmn:sequenceFlow id="Flow_0163xsr" name="Yes" sourceRef="Gateway_0zn0cny" targetRef="Event_0q2arco"> | ||
| <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=studentDataParents[1].currentYearParentIncome != null</bpmn:conditionExpression> | ||
| <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=appealsParentCurrentYearIncomeAppealData[1].currentYearParentIncome != null</bpmn:conditionExpression> | ||
| </bpmn:sequenceFlow> |
There was a problem hiding this comment.
The gateway condition accesses appealsParentCurrentYearIncomeAppealData[1].currentYearParentIncome directly. If appealsParentCurrentYearIncomeAppealData is null/undefined (no appeal submitted) or shorter than expected (e.g., single parent), FEEL evaluation can fail depending on null/index semantics. Guard the condition (e.g., check the list is defined and has the index) before dereferencing.
…ps://github.com/bcgov/SIMS into feature/#5722-parent-current-year-income-appeal
| public async up(queryRunner: QueryRunner): Promise<void> { | ||
| await queryRunner.query( | ||
| getSQLFileData( | ||
| "Add-parent-current-year-income.sql", |
There was a problem hiding this comment.
Suggestion: Just like the filename, this can also be suffixed with the word appeal indicating that this form is a student appeal.
|
| <bpmn:sequenceFlow id="Flow_0163xsr" name="Yes" sourceRef="Gateway_0zn0cny" targetRef="Event_0q2arco"> | ||
| <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=studentDataParents[1].currentYearParentIncome != null</bpmn:conditionExpression> | ||
| <bpmn:sequenceFlow id="Flow_0163xsr" name="Appeal" sourceRef="Gateway_0zn0cny" targetRef="Event_0q2arco"> | ||
| <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=appealsParentCurrentYearIncomeAppealData[1].currentYearParentIncome != null</bpmn:conditionExpression> |
There was a problem hiding this comment.
Just confirming a couple assumptions on this code:
- Accessing by an index that isn't valid (e.g. empty array) will gracefully evaluate to null and not throw an error
- The order of parents is consistent across the consolidated data and appeals data (which originates from the parent supplementary-data) since they are both sorted by id asc
| @@ -0,0 +1,19 @@ | |||
| -- Insert configuration for the parent current year income appeal form into the dynamic_form_configurations table. | |||
There was a problem hiding this comment.
I wasn't sure if "Add-" or "Insert-" was preferred as there is a mix across the scripts. Happy to switch if wanted.
sh16011993
left a comment
There was a problem hiding this comment.
Nice work @weskubo-cgi 👍
| <bpmn:sequenceFlow id="Flow_1pj43zf" name="No" sourceRef="Gateway_09wstv9" targetRef="Event_0sjmtg8"> | ||
| <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=studentDataParents[2].currentYearParentIncome = null </bpmn:conditionExpression> | ||
| </bpmn:sequenceFlow> | ||
| <bpmn:sequenceFlow id="Flow_0f0wu98" name="Application or CRA" sourceRef="Gateway_0zn0cny" targetRef="Event_0yefgn7" /> |
| assessmentConsolidatedData.studentDataDependantstatus = | ||
| dependantStatus as DependantStatusType; | ||
| // Need for dependant students | ||
| if (dependantStatus === "dependant") { |
There was a problem hiding this comment.
Not a blocker, but this type of check and data setup defeats a bit the idea of the for loop, IMO.
Still maybe not the case, but when some data setup is required, an approach like the below can be used.
const appealEligibilityScenarios = [
{
dependantStatus: "dependant",
expectedEligibility: true,
inputData: {
parent1TotalIncome: 99999,
parent1CppEmployment: 500,
parent1CppSelfemploymentOther: 200,
parent1Ei: 600,
parent1Tax: 700,
parent1Contributions: 0,
studentDataVoluntaryContributions: 0,
studentDataParents: [
{
parentIsAbleToReport: YesNoOptions.Yes,
},
],
},
},
{
dependantStatus: "independant",
expectedEligibility: false,
},
];// Arrange
const assessmentConsolidatedData = {
...createFakeConsolidatedFulltimeData(PROGRAM_YEAR),
...inputData,
}| ).toBe(55000); | ||
| }); | ||
|
|
||
| it("Should use the appeal current year income values when there is a parent current year income appeal for parent 1 and CRA reported income for parent 2 .", async () => { |
There was a problem hiding this comment.
Please remove the extra white space at the end.




Summary
sfaa2026-27-ft.jsonparentcurrentyearincomeappeal.jsonNotes
Custom validation was done at the grid level because the component level validation isn't handling the dynamic data in the label when presenting the error summary. Custom error labels were an option but they aren't used in custom validations.

Screenshots
Student -> 2026-2027 Full Time Application
Student -> Forms
Student -> Parent Current Year Income Appeal
Ministry -> Approve/Deny Appeal
Camunda
E2E Tests
fulltime-assessment-appeal-eligibility-parent-current-year-income.e2e-spec.ts
fulltime-assessment-parent-current-year-income.e2e-spec.ts
fulltime-assessment-total-parent-income.e2e-spec.ts
DB Migrations