brackt/plans/completed/DRAFT_ORDER_IMPLEMENTATION.md
Chris Parsons 35fe84a1dd
Update claude.md to push more tests. (#84)
* Update claude.md to push more tests.

* Archiving old plans.

* fix: run DB migrations programmatically on server startup

Replace unreliable drizzle-kit CLI migration with drizzle-orm's built-in
migrator running in the server process before accepting connections. This
ensures migrations are always applied on deploy and fails fast if they error.

- Add runMigrations() to server.ts using drizzle-orm/postgres-js/migrator
- Skip migrations in development (handled manually via db:migrate)
- Add DATABASE_URL guard with a clear error message
- Remove start:production script (now identical to start)
- Update Dockerfile CMD to use npm run start

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-07 22:31:04 -08:00

3.6 KiB

Draft Order Implementation

Overview

Implemented a complete draft slot system that allows commissioners to manage draft order for their fantasy leagues.

What Was Implemented

1. Database Schema

  • New Table: draft_slots
    • id: UUID primary key
    • season_id: Foreign key to seasons (cascade delete)
    • team_id: Foreign key to teams (cascade delete)
    • draft_order: Integer representing the draft position
    • created_at, updated_at: Timestamps

2. Model Layer (app/models/draft-slot.ts)

  • CRUD Operations:

    • createDraftSlot() - Create a single draft slot
    • createManyDraftSlots() - Create multiple draft slots
    • findDraftSlotsBySeasonId() - Get all draft slots for a season (with team info)
    • findDraftSlotByTeamId() - Find draft slot by team
    • updateDraftSlotOrder() - Update a slot's order
    • deleteDraftSlotsBySeasonId() - Delete all slots for a season
    • deleteDraftSlot() - Delete a specific slot
  • Special Functions:

    • setDraftOrder() - Set the complete draft order for a season
    • randomizeDraftOrder() - Randomize draft order using Fisher-Yates shuffle

3. League Settings Page (app/routes/leagues/$leagueId.settings.tsx)

  • New Draft Order Section:

    • Visual list showing current draft order with numbered badges
    • Up/Down arrow buttons to manually reorder teams
    • "Save Draft Order" button to persist changes
    • "🎲 Randomize Draft Order" button for random order generation
    • Only editable during pre_draft status
    • Shows helpful note when draft order hasn't been set yet
  • Action Handlers:

    • set-draft-order - Validates and saves manual draft order
    • randomize-draft-order - Generates and saves random order

4. League Page (app/routes/leagues/$leagueId.tsx)

  • Draft Order Display Box:
    • Shows in right column during pre_draft and draft statuses
    • Displays numbered list of teams in draft order
    • Shows team owner names when available
    • Automatically hidden once season moves to active or completed

5. Database Migration

  • Generated migration: drizzle/0013_pink_the_order.sql
  • Successfully applied to database

Key Features

Commissioner Controls

  • Manual Ordering: Commissioners can manually arrange teams using up/down buttons
  • Randomization: One-click randomization for fair draft order
  • Validation: Ensures all teams are included and valid
  • Status Protection: Draft order can only be modified during pre_draft status

User Experience

  • Visual Feedback: Numbered badges clearly show draft positions
  • Responsive Design: Works on mobile and desktop
  • Conditional Display: Draft order only shown when relevant (pre_draft/draft states)
  • Owner Information: Shows which user owns each team in the draft order

Technical Details

Data Flow

  1. Commissioner sets/randomizes order on settings page
  2. Action handler validates and calls model functions
  3. Model deletes old slots and creates new ones with correct order
  4. League page loader fetches draft slots for display
  5. Draft order box conditionally renders based on season status

Snake Draft Ready

The current implementation stores draft order as a simple integer sequence (1, 2, 3...). When implementing snake draft logic later, you can use this order to determine:

  • Round 1: Order 1→N
  • Round 2: Order N→1
  • Round 3: Order 1→N
  • etc.

Future Enhancements

  • Drag-and-drop reordering (currently uses up/down buttons)
  • Draft order history/audit log
  • Automatic draft order setting when all teams are filled
  • Draft order lottery system with weighted probabilities