- D1: require a Manager-approved SalaryStructure before onboarding; a SELECTED
application with none is now blocked instead of silently binding zero salary
rows.
- D3 AC2: the CREW_ONBOARDED CrewAction records the created IDs
(assignmentId, employeeId, salaryStructureId) in metadata.
- Atomicity: the contract letter is uploaded before the transaction and its row
is created INSIDE it, so onboarding is one atomic write (no half-onboarded
crew member without a contract on failure).
onboarding.test.ts asserts the metadata and the new D1 block (no assignment, the
candidate stays a CANDIDATE).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>