Skip to content

feat(entries): rotating partners — pair individuals who are already paired, in an AD_HOC draw - #1470

Draft
CourtHive wants to merge 1 commit into
mainfrom
feat/rotating-partners-grouped-entries
Draft

CourtHive wants to merge 1 commit into
mainfrom
feat/rotating-partners-grouped-entries

Conversation

@CourtHive

Copy link
Copy Markdown
Owner

⚠️ Merge only after TMX's factory pin includes #4903(factory)

TMX pins tods-competition-factory@6.38.0 (latest published). #4890/#4891/#4903(factory), which let AD_HOC draws hold pairs sharing an individual and keep one person out of two matchUps of a round, are on factory dev and unreleased. With this toggle on 6.38.0, DrawMatic can schedule one person in two matchUps at once. CI resolves the published package, so it will not show this. Hence draft.

Why

AD_HOC entries are a roster, not a field: one person partnering several others over an evening is legitimate, and the factory now permits it only there. TMX had no way to create such a pair. An individual who is already paired is not an entry, so they never appeared in the table to be selected. The only route was destroying pairs.

What

In the draw-entries view of an AD_HOC doubles draw (DrawMatic included; never SWISS, never the event view) there is a Rotating partners toggle:

Default not persisted; starts ON when the draw already holds pairs sharing an individual
[Grouped] rows each individual of the draw's PAIR entries, as a virtual row (outlined chip, "with " under the name). Never an entry; pairing only
Ungrouped rows also the event's UNGROUPED individuals not yet in the draw, so they can be paired into it
Pairing Grouped+Grouped and Grouped+Ungrouped. Existing partners are refused (pairFromUnified allows duplicate participant pairs, so the factory would not stop it)
Entry placement a pair sharing an individual enters the draw as the chosen segment and the event as ALTERNATE, so a bracketed flight generated from the event's accepted entries is not refused for the overlap. A non-overlapping pair is added exactly as before
Other actions Move / Remove from draw / etc. are withheld from any selection containing a Grouped or event-only row

Every decision lives in the DOM-free rotatingPartners.ts.

Also fixed (found by the journey): navigating between entries views before Tabulator finished building left a stale panel whose tableBuilt called insertBefore on a detached container (page error) and could repaint EVENT_CONTROL with its own items. Stale panels now return early. Without the guard the error fired 1 run in 1; with it, 0 in 4.

Evidence

  • rotatingPartners.test.ts: 12 tests, including the overlapping-pair plan executed against the factory (pair lands in the AD_HOC draw as DIRECT_ACCEPTANCE, event ALTERNATE, SINGLE_ELIMINATION still generates).
  • Journey 125 (3 tests) against a dev server built from this branch + factory dev @ d3c0e5a84: toggle defaults, Grouped count, existing partners refused, Grouped+Grouped pair, event-ungrouped+Grouped pair, reopen starts ON, no toggle on all-entries, no page errors. With journeys 19, 22, 23, 33, 123: 28 passed.
  • check-types, lint, format:check, attr-audit --ci, i18n-audit --ci clean. vitest 184 files / 2,017 tests passed (baseline 2,005).

…aired, in an AD_HOC draw

AD_HOC entries are a roster, not a field, so the factory allows PAIRs that share
an individual there and keeps one person out of two matchUps of a round
(#4903(factory)). TMX had no way to create such a pair: an individual who is
already paired is not an entry, so they never appeared in the table.

The draw-entries view of an AD_HOC doubles draw (DrawMatic included; never
SWISS, never the event view) gains a "Rotating partners" toggle:

- Not persisted. It starts ON when the draw already holds pairs sharing an
  individual — the draw's own data remembers the mode was used.
- When ON, each individual of the draw's PAIR entries is a virtual [Grouped]
  row (outlined chip, "with <partner>" under the name). It is never an entry and
  supports pairing only. The event's UNGROUPED individuals not yet in the draw
  are listed as Ungrouped so they can be paired into it.
- Grouped+Grouped and Grouped+Ungrouped can be paired; two individuals already
  partners in the event cannot (pairFromUnified allows duplicate participant
  pairs, so the factory would not stop it).
- A pair sharing an individual enters the DRAW as the chosen segment and the
  EVENT as ALTERNATE (addEventEntryPairs + addDrawEntries in one queue), so a
  bracketed flight generated from the event's accepted entries is not refused
  for the overlap. A pair overlapping nothing is added exactly as before.
- Move, Remove from draw and every other entry action are withheld from a
  selection containing a Grouped or event-only row.

Every decision lives in the leaf rotatingPartners.ts (no DOM), unit-tested
including a run of the overlapping-pair plan against the factory.

Also fixes a race the journey exposed: navigating between entries views before
Tabulator finished building left a stale panel whose tableBuilt called
insertBefore on a detached container (page error) and could repaint
EVENT_CONTROL with its own items. Stale panels now return early from
tableBuilt and refresh.

Unknown segment rank moves 5 → 6; 5 is Grouped.
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.

1 participant