fix(enrollments): let a player be moved back into a group they have left
The transfer wizard died on the return leg of every shuffle. transfer()
always INSERTs the replacement enrolment, but nothing ever deletes the row
a player leaves — it stays, cancelled — and `enrollments` is unique on
(participant_id, training_group_id). So moving a child from 2015 A to
2015 B worked, and moving them back a month later raised a raw
UniqueConstraintViolationException that the wizard's catch-all reported to
the desk as "خطأ غير متوقع", with nothing to say what had gone wrong.
On the OC-Sport tenant 94 active players already have a former group that
is still open and still listed as a destination, so this was one click away
on any of them.
Revive the existing row rather than loosening the constraint: one player is
in one group once, which is what the unique key says and what the history
should read like. The lookup drops global scopes deliberately — the
constraint is academy-wide and knows nothing about the branch scope, so a
row this request could not see would still collide — and clears the
withdrawal that ended the previous spell, or the revived enrolment would
read as active and withdrawn at once and the renewal command would skip it.
Two neighbours fixed while here, both latent rather than reported:
- transfer() had no "one group per programme" guard, though enroll() has
one. A transfer into a programme the player was already enrolled in left
two active enrolments, which GenerateRenewalInvoices bills twice.
- transfer() left academy_id to BelongsToAcademy, which fills it from a
container binding that only exists in a web request. Same NOT NULL
failure enroll() was already fixed for; states it explicitly now.
Transferring into the group the player is already in is now refused
instead of cancelling and reviving the same row and reporting success.
Verified against a restored oc_sport tenant (the suite's own convention):
the new test reproduces the violation without the fix and passes with it,
and the full suite shows the same 6 pre-existing failures before and after
— no regressions.
Co-Authored-By:
Claude Opus 5 <noreply@anthropic.com>
Showing
Please register or sign in to comment