Friday, May 29, 2026

Coach Event Application Flow — Document & Round Out

Volleyball Elite Academy development update
Volleyball Elite Academy
Coach Event Application Flow — Document & Round Out

Coach Event Application Flow — Document & Round Out

Volleyball Elite Academy — Development Update • May 29, 2026

Coach Event Application Flow — Document & Round Out

What & Why

Coaches today can apply to work specific event shifts via , admins approve them in , and accepted assignments flow into the Coach Portal. The plumbing exists end-to-end, but the experience is bare: coaches apply blind to capacity and required level, double-booking goes undetected, there's no notification when a matching role opens, and once interest is expressed neither side has a clean way to back out. This task documents the current process in and fills the four lifecycle gaps in one coordinated pass so the flow finally feels finished.

Done looks like

  • has a "Coach Event Application Flow" subsection under Product that walks through the five steps (browse → express interest → admin review → coach accept/decline → assignment lives in portal) and names the two distinct queues (academy application vs. event-shift interest).
  • Each opportunity card on and the Opportunities tab inside shows:
- "N of M filled" for the role on that event (capacity) - Required coach tier/level badge, with the card visually muted (and the express-interest button disabled with a tooltip) when the viewing coach doesn't meet the level
  • When a coach tries to express interest in an event whose date+time overlaps another assignment they've already ACCEPTED or had ASSIGNED, the server returns a clear 409 with the conflicting event's name and date, and the UI shows a "Schedule conflict with " inline error instead of silently succeeding.
  • The admin queue at surfaces the same overlap warning as a yellow pill on rows where the applicant has a clashing accepted assignment, so admins don't approve a double-booking.
  • When a new row is created with (a freshly opened opportunity), eligible coaches whose level matches receive a "New opportunity" email (and Web Push if subscribed), at most one digest per coach per day, coalesced.
  • A coach can withdraw their own interest before it's been approved: a "Withdraw" button on their pending interest cards calls a new that flips the row to and frees the slot. After approval, withdrawing requires admin action (existing decline flow).
  • An admin can reject an interest application with a required short reason (free text, max 280 chars). The rejected coach receives an email with the reason, and the row moves to with stored.
  • All of the above are covered by either a vitest unit test (server logic, conflict detection, notification coalescing, withdraw/reject endpoints) or a Playwright e2e (capacity badge, level lock, schedule-conflict inline error, withdraw button, admin reject-with-reason modal).

Out of scope

  • Changing the academy-application onboarding flow (, the 7-step checklist). That's the other queue and untouched here.
  • The "propose a new team" flow ( + ). Stays as-is.
  • Pay-band changes, payroll, SOF session lifecycle, or anything that happens after an assignment is ACCEPTED.
  • Auto-assigning coaches by matching algorithm. Admins still manually approve interest.
  • In-app notification center work — this task only adds the outbound email + push for new opportunities, reusing existing senders.

Steps

1. Document the current flow in — Add a "Coach Event Application Flow" subsection under Product covering the five-step process and explicitly noting the two distinct queues (academy join vs. event-shift interest) so future readers don't re-discover the distinction. 2. Capacity + level on opportunity cards — Extend the response to return per-role , , and alongside each opening. Render a "N of M filled" line and a level badge on each card; visually mute the card and disable Express Interest when the viewer's is below , with a tooltip explaining why. Mirror the same render in the Opportunities tab inside the Coach Portal. 3. Schedule conflict detection (server + UI) — In , before inserting/updating the row, look up the coach's existing assignments with status in (, ) and reject with HTTP 409 + when the target event's date+time overlaps. Surface the 409 as an inline error on the opportunity card. In , compute the same overlap on the server when enriching each row and render a "Conflicts with " pill so admins don't approve a clash. 4. New-opportunity notification — Add a small scheduler tick (or hook the assignment-create site) that, when a row with is created, queues a coalesced per-coach email to coaches whose level meets the requirement and who don't already have an interest/assignment on that event. Send at most once per coach per day via the existing dedupe pattern. If the coach has an active Web Push subscription, also send a single push. Persist the pending recipients in a mirror table so a crash mid-tick doesn't drop the batch (follow the pattern already used by the training-team selection coalescer). 5. Withdraw + reject-with-reason lifecycle — Add (coach-only, flips status to , only allowed while the row is ) and a "Withdraw" button on pending interest cards in the Coach Portal Assignments tab. Add taking a required (1–280 chars), storing it in a new column, flipping the row to , and emailing the coach the reason. Add a reject-with-reason modal to the admin queue alongside the existing approve action. 6. Tests — Vitest for: conflict detection (overlap and non-overlap fixtures), withdraw endpoint (allowed only while INTEREST_EXPRESSED), reject endpoint (reason required + stored + email sent), and the new-opportunity coalescer (eligibility filter + per-day dedupe + crash-safe recovery). Playwright for: capacity badge + level-lock disabled state on the opportunity card, schedule-conflict inline error after clicking Express Interest, Withdraw button removing the row, and admin reject-with-reason modal moving the row to a "Declined" pill.

Architectural constraints

  • Any new in-memory email coalescer MUST use the + helpers from together with a mirror table and a boot-time recovery call wired into . This is non-negotiable per the existing decision recorded in .
  • New columns on () require a schema change in followed by . Source of truth is the schema file, not ad-hoc SQL.
  • Server-side authorization on every new endpoint: the withdraw endpoint must verify the row belongs to the requesting coach; the admin reject endpoint must require a SuperAdmin (or whichever role already gates approve). No frontend gating alone.
  • Reuse the existing assignment-email sender — do not introduce a parallel email path for rejections or new-opportunity alerts.

Relevant files

- - - - - - - - - - - - - - -

Volleyball Elite Academy

Reply to this email — we read every reply.

You received this because you have an account with Volleyball Elite Academy.

elitevolleyball.training

No comments:

Post a Comment