* Emit standings-updated socket event after recalculate-floors so league pages refresh automatically When the admin runs "Recalculate Floors" on the bracket page, the league sports-season homepage was showing stale elimination data because there was no mechanism to notify it of the change. Fix: after recalculate-floors updates participant_results, emit a standings-updated socket event to all fantasy-season draft rooms linked to the sports season. The sports-season page now joins its draft room and revalidates its loader whenever it receives that event for the matching sports season. https://claude.ai/code/session_01D3NbnVQdaH82Fk7Jm8y3sB * Fix recalculate-floors incorrectly eliminating play-in losers who still advance The playoff_matches.isScoring column defaults to true in the database. Brackets created before this column was added (or before the migration set correct values) have isScoring=true on play-in rounds that should be false. When recalculate-floors replayed those matches, it took the "scoring round" path; since "Play-In Round 1" isn't in ROUND_CONFIG, config===null, and the loser was assigned finalPosition=0 regardless of loserAdvances — permanently eliminating teams like the Suns who had a second play-in game remaining. Fix: build a round→isScoring lookup from the bracket template before replaying matches and use it as the source of truth, falling back to the DB field only when the template doesn't define the round. This ensures non-scoring play-in rounds are always processed with isScoring=false so the loserAdvances guard fires correctly. Also revert unrelated socket changes from the previous (wrong) commit. https://claude.ai/code/session_01D3NbnVQdaH82Fk7Jm8y3sB * Fix isScoring fallback and loserAdvances gaps across all match-processing paths Three issues found in code review around the recalculate-floors fix: 1. set-winner and set-round-winners (bracket.server.ts) used `match.isScoring ?? true` just like recalculate-floors did. Both now derive isScoring from the bracket template as the source of truth, falling back to the DB field only when the round isn't defined in the template. 2. processPlayoffEvent (scoring-calculator.ts) used `matches[0]?.isScoring ?? true` with the same DB-default problem. Now uses BRACKET_TEMPLATES[bracketTemplateId] to look up the round's isScoring before falling back to the DB field. 3. doesLoserAdvance (playoff-match.ts) was missing the AFL afl_10 Qualifying Finals case: both losers advance to Semi-Finals. Without this, AFL QF losers would incorrectly receive finalPosition=0 when processed through the non-scoring path. https://claude.ai/code/session_01D3NbnVQdaH82Fk7Jm8y3sB * Fix no-non-null-assertion lint errors in isScoring Map lookups Replace Map.has(key) ? Map.get(key)! : fallback pattern with Map.get(key) ?? fallback to satisfy oxlint no-non-null-assertion rule. https://claude.ai/code/session_01D3NbnVQdaH82Fk7Jm8y3sB --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|---|---|---|
| .claude | ||
| .github/workflows | ||
| .storybook | ||
| .vscode | ||
| app | ||
| cypress | ||
| database | ||
| docs/superpowers | ||
| drizzle | ||
| plans | ||
| public | ||
| scripts | ||
| server | ||
| .dockerignore | ||
| .env.example | ||
| .gitignore | ||
| .nvmrc | ||
| .oxlintrc.json | ||
| CLAUDE.md | ||
| components.json | ||
| cypress.config.js | ||
| docker-compose.yml | ||
| Dockerfile | ||
| drizzle.config.ts | ||
| instrument.server.mjs | ||
| package-lock.json | ||
| package.json | ||
| plan.md | ||
| react-router.config.ts | ||
| README.md | ||
| server.ts | ||
| TESTING.md | ||
| tsconfig.json | ||
| tsconfig.node.json | ||
| tsconfig.server.json | ||
| tsconfig.vite.json | ||
| vite.config.ts | ||
| vitest.config.ts | ||
| vitest.shims.d.ts | ||
Welcome to React Router!
A modern, production-ready template for building full-stack React applications using React Router.
Features
- 🚀 Server-side rendering
- ⚡️ Hot Module Replacement (HMR)
- 📦 Asset bundling and optimization
- 🔄 Data loading and mutations
- 🔒 TypeScript by default
- 🎉 TailwindCSS for styling
- 💾 PostgreSQL + DrizzleORM
- 📖 React Router docs
Getting Started
Installation
Install the dependencies:
npm install
Development
Copy .env.example to .env and provide a DATABASE_URL with your connection string.
Run an initial database migration:
npm run db:migrate
Start the development server with HMR:
npm run dev
Your application will be available at http://localhost:5173.
Building for Production
Create a production build:
npm run build
Deployment
Docker Deployment
To build and run using Docker:
# For npm
docker build -t my-app .
# Run the container
docker run -p 3000:3000 my-app
The containerized application can be deployed to any platform that supports Docker, including:
- AWS ECS
- Google Cloud Run
- Azure Container Apps
- Digital Ocean App Platform
- Fly.io
- Railway
DIY Deployment
If you're familiar with deploying Node applications, the built-in app server is production-ready.
Make sure to deploy the output of npm run build
├── package.json
├── package-lock.json (or pnpm-lock.yaml, or bun.lockb)
├── server.js
├── build/
│ ├── client/ # Static assets
│ └── server/ # Server-side code
Styling
This template comes with Tailwind CSS already configured for a simple default starting experience. You can use whatever CSS framework you prefer.
Built with ❤️ using React Router.