* Add implementation plan for commissioner-without-team feature https://claude.ai/code/session_01NSRMSYtb7jSFbngDS8okn3 * Allow commissioners to exist without owning a team - Add opt-out checkbox on league creation ("I want to play in this league") so the creator can be commissioner-only without claiming a team - Add Commissioner Management card to league settings with add/remove commissioner UI; guards against removing the last commissioner - Add countCommissionersByLeagueId model helper for the last-commissioner guard - Show "No team" indicator on the league homepage next to commissioners who don't own a team in the current season https://claude.ai/code/session_01NSRMSYtb7jSFbngDS8okn3 * Fix code review issues in commissioner management - Add success/error feedback banners to commissioner add/remove actions - Gate allUsers query to admin-only (prevents exposing all users to non-admin commissioners) - Prevent commissioner self-removal in both action (server) and UI (client) - Add "(you)" label next to current user in commissioner list - Remove all unnecessary `any` type casts in favor of inferred types https://claude.ai/code/session_01NSRMSYtb7jSFbngDS8okn3 * Allow commissioners to add league members as co-commissioners Non-admin commissioners can now add users who already own a team in the league as co-commissioners. Admins still see the full user list. Previously the add-commissioner form was admin-only. https://claude.ai/code/session_01NSRMSYtb7jSFbngDS8okn3 --------- Co-authored-by: Claude <noreply@anthropic.com>
66 lines
3.7 KiB
Markdown
66 lines
3.7 KiB
Markdown
# Plan: Commissioner Without a Team
|
|
|
|
## Current State
|
|
|
|
**At the database level**, commissioners and teams are already independent:
|
|
- Commissioners are stored in the `commissioners` table (league-level, keyed by `leagueId` + `userId`)
|
|
- Teams are stored in the `teams` table (season-level, keyed by `seasonId` + `ownerId`)
|
|
- A commissioner does NOT need a team to access the league homepage or draft room — this already works
|
|
|
|
**The actual problem** is that there's no way to *become* a commissioner without also getting a team:
|
|
1. **League creation** (`app/routes/leagues/new.tsx:198-201`): The creator is always assigned the first team (`ownerId: i === 0 ? userId : null`)
|
|
2. **No "Add Commissioner" UI**: There's no way for a league creator to add additional commissioners at all
|
|
3. **Invite link flow** (`app/routes/i.$inviteCode.tsx`): Joining always assigns a team — there's no option to join as commissioner-only
|
|
|
|
**Also**, the league creation flow has no opt-out for team ownership — the creator always gets Team 1.
|
|
|
|
## Changes
|
|
|
|
### 1. League creation: Add "Join as player" checkbox
|
|
**File**: `app/routes/leagues/new.tsx`
|
|
|
|
- Add a checkbox: "I want to play in this league" (checked by default)
|
|
- When unchecked, skip assigning the creator to the first team (all teams get `ownerId: null`)
|
|
- When checked, behavior stays the same (creator gets first team)
|
|
|
|
### 2. Add Commissioner Management UI to League Settings
|
|
**File**: `app/routes/leagues/$leagueId.settings.tsx`
|
|
|
|
- Add a new "Commissioner Management" card section
|
|
- Show current commissioners with a "Remove" button (cannot remove if they're the last commissioner)
|
|
- Add an "Add Commissioner" form with a user search/select dropdown
|
|
- Only show users who are already members of the league (team owners) OR allow adding by searching all users
|
|
- Since only the site admin can currently assign users to teams, let's keep it simple: commissioners can add any registered user as a commissioner
|
|
- Backend actions: `add-commissioner` and `remove-commissioner` intents
|
|
|
|
### 3. Model changes
|
|
**File**: `app/models/commissioner.ts`
|
|
|
|
- Already has `createCommissioner`, `deleteCommissioner`, `removeCommissionerByLeagueAndUser` — these are sufficient
|
|
- Add `countCommissionersByLeagueId` to prevent removing the last commissioner
|
|
|
|
### 4. Settings loader changes
|
|
**File**: `app/routes/leagues/$leagueId.settings.tsx`
|
|
|
|
- Load commissioners list and user data for display
|
|
- Load all users list for the "add commissioner" dropdown (reuse existing `allUsers` pattern but make it available to commissioners, not just admins)
|
|
|
|
### 5. League homepage: Show commissioner-only indicator
|
|
**File**: `app/routes/leagues/$leagueId.tsx`
|
|
|
|
- In the commissioners list, if a commissioner doesn't own a team in the current season, show a "(No team)" indicator next to their name
|
|
- This helps distinguish playing commissioners from non-playing commissioners
|
|
|
|
## Files to modify
|
|
|
|
1. `app/routes/leagues/new.tsx` — Add "play in league" checkbox, conditionally assign first team
|
|
2. `app/models/commissioner.ts` — Add `countCommissionersByLeagueId` helper
|
|
3. `app/routes/leagues/$leagueId.settings.tsx` — Add commissioner management card (loader + action + UI)
|
|
4. `app/routes/leagues/$leagueId.server.ts` — Pass team ownership info for commissioners to the homepage
|
|
5. `app/routes/leagues/$leagueId.tsx` — Show "(No team)" indicator for commissioners without teams
|
|
|
|
## Out of scope (not changing)
|
|
|
|
- The invite link flow — this is for players joining, not commissioners. Commissioners should be added through settings.
|
|
- The `createdBy` vs commissioners table inconsistency in draft control endpoints — that's a separate bug
|
|
- Adding a way for a commissioner to later claim/release a team mid-season — possible future work but not needed here
|