Skip to content

Test plan: Core HR Transaction Bundle

Expands on spec.md's Scope and Acceptance Criteria into concrete scenarios, one group per transaction (five this pass — Bonus and Incentive Awards deferred, see Out of scope) plus cross-cutting scenarios surfaced during implementation-plan.md's cross-scope compensation write finding. One scenario remains genuinely blocked on spec.md's unresolved multi-jurisdiction-tax Open Question; the document/attachment and Job Data Changes storage questions that were open in an earlier pass are now resolved decisions, reflected below rather than marked blocked.

Scenarios

Personal Data Updates

  1. Address/contact changes apply immediately, no approval.
  2. Given a Worker submits a new address or contact-info value
  3. When the value passes format validation
  4. Then it's reflected on their profile immediately, with no approval step and no notification sent to HR.

  5. Dependent addition without documentation is blocked. (blocked — depends on worker-document-management shipping, a resolved dependency, not an open question)

  6. Given a Worker adds a dependent but attaches no supporting documentation
  7. When the change is submitted
  8. Then the submission cannot finalize until documentation is attached.
  9. Cannot be verified end-to-end until worker-document-management exists — this Feature builds none of that capability itself (decided).

  10. Dependent/tax-withholding changes route to HR Business Partner.

  11. Given a Worker submits a dependent or tax-withholding change
  12. When it's submitted
  13. Then a Pending Approval transaction is created and routed to the HR Business Partner; on approval, the Worker record and any linked payroll/benefits fields update and the worker is notified.

  14. HR Operations can audit every personal data change.

  15. Given any number of personal data changes have been submitted for a worker
  16. When HR Operations queries that worker's history
  17. Then every change and its approval status is retrievable for periodic compliance audit.

Job Data Changes

  1. A job-level change is rejected and redirected.
  2. Given a Job Data Change submission includes a change to job level
  3. When it's validated
  4. Then it's rejected with a message directing the initiator to Promotion or Demotion instead of being processed here.

  5. Manager approval writes a new effective-dated Job Assignment entry.

  6. Given a Direct Manager approves a Job Data Change
  7. When the approval completes
  8. Then a new Job Assignment entry is created carrying the updated job description and/or skill tags, with job_start_date set to the change's effective date; the prior Job Assignment entry is closed by setting its job_end_date to that same date rather than being overwritten — the same insert-new/close-old pattern already used by department transfers and manager changes. Reflected in skills-inventory and internal mobility matching.

  9. Duplicate open Job Data Change for the same effective date is blocked.

  10. Given a worker already has an open Job Data Change transaction
  11. When a second one is submitted for the same effective date
  12. Then it cannot be submitted until the first resolves.

Promotion

  1. Promotion rejected if new level isn't higher.
  2. Given a Promotion submission where the new job level is not higher than the worker's current level
  3. When it's validated
  4. Then it's rejected.

  5. Promotion requires HR Business Partner and Department Head approval.

  6. Given a valid Promotion submission
  7. When it's routed for approval
  8. Then both the HR Business Partner and Department Head must approve; either denying halts the transaction and notifies the initiator with the stated reason.

  9. Full approval updates level, title, and compensation.

    • Given a Promotion receives full approval
    • When the effective date arrives
    • Then the worker's job level and title update in nova-corehcm-sn-app, and the compensation-band change persists on x_novaw_comp_worker_compensation via the cross-scope WorkerCompensationService.upsertCompensation() call — verify both writes, not just the Core HR side, and that the worker is notified.

Demotion

  1. Demotion rejected if new level isn't lower.

    • Given a Demotion submission where the new job level is not lower than the worker's current level
    • When it's validated
    • Then it's rejected.
  2. Demotion requires HR Business Partner and Department Head approval.

    • Given a valid Demotion submission
    • When it's routed for approval
    • Then both approvers must approve; either denying halts the transaction and notifies the initiator with the stated reason.
  3. Full approval updates level, title, and compensation, logged separately.

    • Given a Demotion receives full approval
    • When the effective date arrives
    • Then the worker's job level and title update, the compensation-band change persists on x_novaw_comp_worker_compensation via the same cross-scope call as scenario 10, and the change is logged separately in job history vs. compensation-change history.

Salary Changes

  1. Salary Change routes to HR Business Partner or Compensation reviewer.

    • Given a Direct Manager proposes a Salary Change
    • When it's submitted
    • Then it routes for review before it's applied to the Worker's compensation record.
  2. Salary Change exceeding the annual cap is blocked without override.

    • Given a Salary Change exceeds the annual increase cap
    • When it's submitted without an HR override
    • Then it's blocked.
  3. Approval updates the compensation record and notifies both parties.

    • Given a Salary Change receives approval
    • When the effective date arrives
    • Then the new compensation amount persists on x_novaw_comp_worker_compensation via WorkerCompensationService.upsertCompensation(), and both the worker and the proposing manager are notified.

Cross-cutting

  1. Compensation write succeeds under the execution script's actual runtime role.

    • Given Salary Changes, Promotion, or Demotion's execution script calls WorkerCompensationService.upsertCompensation()
    • When the call executes
    • Then it succeeds — verify the script's runtime role actually carries x_novaw_comp.hr_ops or x_novaw_comp.integration_writer, not the generic x_novaw_comp.agent role, which this table's write ACL does not grant (per implementation-plan.md's ACCESS CONTROL risk). A test running under the wrong role would fail ACL, not silently no-op — confirm this fails loudly if misconfigured.
  2. Cross-scope call is allowed, not stuck pending.

    • Given nova-corehcm-sn-app declares an outbound CrossScopePrivilege record for WorkerCompensationService
    • When Salary Changes, Promotion, or Demotion runs for the first time in a given instance
    • Then the call succeeds immediately — verify the privilege record's status is pre-declared allowed, not left to auto-create as requested (blocked) on first use, per implementation-plan.md's RCA risk.
  3. HRBP approval gate is testable in isolation. (blocked — no isolable hrbp test account exists today, per tests/API_integration_tests/INTEGRATION_TESTS.md §3.2)

    • Given Promotion, Demotion, or Salary Changes requires HR Business Partner approval
    • When an integration test attempts to verify that gate specifically (not admin behavior standing in for it)
    • Then it needs a dedicated hrbp-only account — none exists on the test instance today, since every current hrbp holder also holds full admin.

Out of scope for this pass

  • Bonus and Incentive Awards (#674) — deferred out of the build, not just untested; no existing home in nova-compensation-sn-app's schema, skipped rather than pulling that app's team in now (per spec.md's Out of Scope and implementation-plan.md). No scenarios for it here.
  • Cost Center Change and Org Restructuring/Reorganizations/Hierarchies — deferred to a later Feature under this same Feature Set per spec.md's Out of Scope; no scenarios here.
  • Building the document/attachment storage mechanism itself — scenario 2 tests against it once it exists; building it is worker-document-management's scope (resolved decision, not an open question).
  • Exact reason-code values for Job Data Changes — not yet finalized (spec.md Open Questions); scenario set doesn't assert specific codes.
  • The chat/utterance-classification layer (whether varied phrasings correctly detect each of the 5 new intents) — that's nova-corehcm-agent's existing eval-testset convention (tests/testsets/), not this acceptance-criteria-level plan.
  • nova-test-ci's actual Playwright implementation — held this pass (decided); these scenarios (especially 10, 13, 16, and the cross-cutting group) are what will drive that expansion in a future pass, not built now.