Skip to content

MPDX-9273: Add spouse request flows for ASR and MHA#1639

Merged
dr-bizz merged 12 commits intomainfrom
MPDX-9273-MPDX-8921-spouse-logic
Feb 27, 2026
Merged

MPDX-9273: Add spouse request flows for ASR and MHA#1639
dr-bizz merged 12 commits intomainfrom
MPDX-9273-MPDX-8921-spouse-logic

Conversation

@dr-bizz
Copy link
Contributor

@dr-bizz dr-bizz commented Feb 22, 2026

Description

In this PR, I have implemented the changes from https://github.com/CruGlobal/mpdx_api/pull/3171 into the frontend.

  • Add isSpouse variable to ASR query/create mutation and MHA create mutation GraphQL operations
  • Wire up ASR spouse mode via ?isSpouse=true URL param through context to child components
  • Implement SpouseComponent click handler to create spouse ASR and navigate to spouse editing flow
  • Add "Request New MHA for [spouse]" button with open request detection on MHA landing page
  • Replace hardcoded spouse eligibility with real HCM data in IneligibleDisplay
  • Update all tests (57 suites, 358 tests passing)

Testing

  • ASR: Click "Request additional salary from [spouse]" navigates to the spouse's ASR or back to the current user
  • ASR: On receipt page, spouse link navigates to the spouse's ASR or back to the current user
  • MHA: "Request New MHA for [spouse]" navigates to the spouse's ASR or back to the current user
  • MHA: IneligibleDisplay shows correct spouse eligibility from HCM data

Checklist:

  • I have given my PR a title with the format "MPDX-(JIRA#) (summary sentence max 80 chars)"
  • I have applied the appropriate labels (Add the label "Preview" to automatically create a preview environment)
  • I have run the Claude Code /pr-review command locally and fixed any relevant suggestions
  • I have requested a review from another person on the project
  • I have tested my changes in preview or in staging
  • I have cleaned up my commit history

@github-actions
Copy link
Contributor

github-actions bot commented Feb 23, 2026

Bundle sizes [mpdx-react]

Compared against 9f34450

No significant changes found

@dr-bizz dr-bizz requested a review from wjames111 February 23, 2026 18:15
@dr-bizz dr-bizz requested a review from wjames111 February 25, 2026 18:43
Copy link
Contributor

@wjames111 wjames111 left a comment

Choose a reason for hiding this comment

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

This looks awesome, thanks for doing all this work!

Copy link
Contributor

Choose a reason for hiding this comment

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

Praise: Thanks for renaming this!


const showStatuses: AsrStatusEnum[] = [
AsrStatusEnum.ActionRequired,
AsrStatusEnum.Pending,
Copy link
Contributor

Choose a reason for hiding this comment

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

Praise: Thanks for removing this!

const name = isSpouse
? (user?.staffInfo?.firstName ?? '')
: (spouse?.staffInfo?.firstName ?? '');
const name = spouse?.staffInfo?.firstName ?? '';
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm getting a blank name, should we put a guard up for this component? If I click "Request additional salary for" I get Spouse information not available.

}
spouseCalculations {
currentSalaryCap
pendingAsrAmount
Copy link
Contributor

Choose a reason for hiding this comment

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

Comment: I believe pendingAsrAmount checks for user and spouse in the back-end. So it's effectively the same number as the calculation's pendingAsrAmount. I might need to update the back-end to just check pendingAsrAmount for the current user rather then both.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We may need to address this then, as we have the below code in the file src/components/Reports/AdditionalSalaryRequest/Shared/useSalaryCalculations.ts:

// Annual salary calculations
    const additionalSalaryReceivedThisYear =
      calculations?.pendingAsrAmount ?? 0;
    const totalAnnualSalary =
      grossAnnualSalary + additionalSalaryReceivedThisYear + total;

    // Spouse annual salary calculations
    const spouseTotalThisYear = spouse
      ? requestData?.latestAdditionalSalaryRequest?.spouseCalculations
          ?.pendingAsrAmount
      : null;
    const spouseTotalAnnualSalary =
      spouseGrossAnnualSalary + (spouseTotalThisYear ?? 0);

    // Exceeding cap calculations
    const exceedsCap = totalAnnualSalary > individualCap;
    const spouseExceedsCap =
      spouse && spouseIndividualCap !== null
        ? (spouseTotalAnnualSalary ?? 0) > spouseIndividualCap
        : undefined;

    const exceedsCombinedCap =
      (combinedCap ?? 0) < totalAnnualSalary + spouseTotalAnnualSalary;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The combined cap adds both the spouse pending ASR and user's pending ASR together

Copy link
Contributor

Choose a reason for hiding this comment

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

I have a PR out for just calculating the current user's pending_asr_amount rather then using both user and spouse. This should hopefully fix the issue without having to do update combinedCap.

Pass isSpouse to latestAdditionalSalaryRequest query and both
createAdditionalSalaryRequest and createMinistryHousingAllowanceRequest
mutations to support spouse request flows from the backend.
Read isSpouse from router query params on the ASR page and pass it to
AdditionalSalaryRequestProvider, which forwards it to the query and
exposes it on the context for child components.
- SpouseComponent: create spouse ASR on click and navigate to spouse flow
- StepList: fix receipt spouse link to use proper ?isSpouse=true URL
- RequestPage: pass isSpouse to create mutation and use spouse HCM data
- MinisterHousingAllowance: add spouse MHA creation button with open
  request detection
- IneligibleDisplay: replace hardcoded false with actual spouse
  eligibility from HCM data
- Add isSpouse: false to all mock context objects
- Add SnackbarProvider to shared test utilities for SpouseComponent
- Add spouse ASR creation and error handling tests
- Add MHA spouse button and open request detection tests
- Add real spouse eligibility tests for IneligibleDisplay

Fixing PR

fixing issues
small edits after Claude review
Reverting changes
@dr-bizz dr-bizz force-pushed the MPDX-9273-MPDX-8921-spouse-logic branch from 19894bb to 2f2583b Compare February 27, 2026 13:21
@dr-bizz
Copy link
Contributor Author

dr-bizz commented Feb 27, 2026

🤖 Multi-Agent Code Review Report

PR #1639: MPDX-9273: Add spouse request flows for ASR and MHA
Agents: 6 specialized reviewers (Architecture, Data Integrity, Testing, UX, Financial, Standards) with 2 debate rounds
Review Mode: Standard (smart agent selection)


📊 Risk Assessment

Risk Score: 13 — CRITICAL
Files Changed: 16 (+489 -100 lines)

Risk Factors:

  • src/lib/apollo/cache.ts modified (55 dependents)
  • AdditionalSalaryRequestContext.tsx modified (27 dependents)
  • .graphql schema changed
  • 500+ lines changed

Required Reviewer: Senior developer should review


⚠️ Important Issues (Should fix before merge)

1. Missing isSpouse=true test coverage in SpouseComponent (8/10)

Consensus: 5 of 6 agents flagged

SpouseComponent has critical conditional logic (lines 23-28) that swaps which calculations are used based on isSpouse. The link text also changes. None of this is tested — all 6 test cases use isSpouse: false.

Suggested tests:

it('shows "Switch back to" text when isSpouse is true', ...);
it('uses userCalculations for remaining salary when isSpouse is true', ...);
it('generates correct link URL when isSpouse is true (no query param)', ...);

2. Duplicated spouse link logic across 3 components (7.5/10)

Consensus: All 6 agents flagged

Identical logic is copy-pasted in SpouseComponent.tsx, InProgressDisplay.tsx, and StepList.tsx:

  • Same link text computation
  • Same URL construction

Recommendation: Extract into a shared useSpouseLink() hook.

3. Missing isSpouse=true tests in InProgressDisplay and StepList (7/10)

Consensus: 4 of 6 agents flagged

Neither component tests the isSpouse=true path — "Switch back to" text, link URL without ?isSpouse=true, and StepList spouse link rendering are all unverified.

4. "Switch back to" link text is ambiguous (7/10)

When isSpouse=true, "Switch back to {{name}}" doesn't clearly communicate the action. Consider "View {{name}}'s request" or similar.


💡 Medium Priority (Consider addressing)

  • (7/10) Full page navigation for spouse switching — Uses MUI <Link href> instead of next/link, causing full page reload
  • (6/10) Hardcoded past-due date "9/25/2025" in StepList — Pre-existing, not introduced by this PR, but exposed to more users. Recommend follow-up ticket.
  • (6/10) isSpouse: isSpouse || undefined coercion asymmetry between query and mutation
  • (5/10) Backend contract for calculations orientation should be documented with a code comment
  • (5/10) Inconsistent nullish coalescing (|| vs ??) in useFormUserInfo.ts

✅ Positive Findings

  • Apollo cache keyArgs: ['isSpouse'] correctly prevents cache collision
  • Context-level user/spouse swap is well-implemented with good test coverage
  • 403b percentage swap logic is tested and correct
  • All user-visible text properly localized with t()
  • Gender-neutral language improvement ("her" → "their")
  • Named exports, id fields in GraphQL, no security issues, no any types

📝 Debate Summary

The Data Integrity Agent initially flagged two CRITICAL (10/10) findings about useSalaryCalculations and useFormUserInfo not being isSpouse-aware. After cross-examination by Architecture, Testing, Financial, and Standards agents, both findings were conceded and downgraded to 5/10 and 4/10 respectively. The context-level swap and backend isSpouse query parameterization handle the data orientation correctly. The residual concern is an implicit backend contract that should be documented.


🎯 Recommended Next Steps

Should fix before merge:

  • Add isSpouse=true test cases to SpouseComponent.test.tsx
  • Extract shared spouse link logic into a hook
  • Add isSpouse=true test coverage to InProgressDisplay and StepList

Consider addressing:

  • Clarify "Switch back to" link text
  • Use next/link for SPA navigation
  • Add code comment documenting backend contract

Follow-up ticket:

  • Fix hardcoded past-due date "9/25/2025" in StepList

🤖 Generated by MPDX Multi-Agent Review System v3.0 | 6 agents, 2 debate rounds

@dr-bizz dr-bizz merged commit e659c63 into main Feb 27, 2026
23 of 24 checks passed
@dr-bizz dr-bizz deleted the MPDX-9273-MPDX-8921-spouse-logic branch February 27, 2026 21:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants