Website for Brackt.com
Find a file
chrisp f96c8f5244
All checks were successful
🚀 Deploy / 🧪 Test (push) Successful in 2m40s
🚀 Deploy / ʦ🔍 Typecheck & Lint (push) Successful in 1m26s
🚀 Deploy / 🐳 Build (push) Successful in 1m14s
🚀 Deploy / 🚀 Deploy (push) Successful in 12s
Fix draft timer: broadcasts, increments, reconnect sync, overnight pause (#72)
## Summary

- **Timer bank broadcasts**: emit `timer-bank-updated` after every pick so all clients immediately see the updated bank instead of waiting for the next `timer-pick-started`
- **Increment accuracy**: capture `pickMadeAt` at route entry (before auth/DB overhead) and use `Math.ceil` so credited seconds always match the client countdown display
- **Race condition fix**: hold `schedulingInProgress` lock for the full timer callback to prevent the recovery interval from scheduling a duplicate timeout mid-pick
- **force-autopick fix**: call `rescheduleTimer` so the next team's clock starts immediately instead of waiting for the old timeout to naturally expire
- **adjust-time-bank fix**: for on-clock teams, shift `picksExpiresAt` by the adjustment and reschedule so the client countdown updates; block adjustments that would reduce the bank to zero
- **New socket events**: `timer-pick-started`, `timer-overnight-paused`, `timer-bank-updated` with full type definitions; removed dead `timer-update` event
- **Reconnect sync**: `draft-state-sync` now includes `expiresAt` for the active timer and `isOvernightPause` state so reconnecting clients see accurate countdown and pause banner immediately without a page reload
- **Room closure countdown**: capture client-side timestamp when draft completes so the "Room closes in X" countdown actually ticks down before the loader revalidates with `draftCompletedAt`
- **Countdown interval**: run at 500ms with `Math.ceil` to prevent skipped seconds under event loop pressure
- **Overnight pause UX**: `canPick` only blocks on commissioner pause — overnight pause freezes the timer but the on-clock player can still pick early
- **Overnight pause refactor**: extract `checkOvernightPause` to `server/overnight-pause-check.ts`, breaking the `timer↔socket` circular import and sharing the timezone cache across both callers with correct eviction
- **PostgreSQL type fix**: cast `varchar` owner ID to `uuid` in `getTeamTimezone` join

## Test plan

- [ ] Manual pick: all clients see bank increment immediately after pick
- [ ] Timeout pick: all clients see bank update (0 → increment); next clock starts within ~1s
- [ ] Force-autopick: next team's clock starts immediately; no "Pick already made" log
- [ ] Force-manual-pick: all clients see bank increment
- [ ] Pause while clock running: countdown freezes on all clients
- [ ] Resume: clock continues from frozen value
- [ ] adjust-time-bank on on-clock team: countdown shifts immediately
- [ ] adjust-time-bank to zero: returns 400 error
- [ ] Reconnect (socket disconnect/connect): countdown resumes for correct team
- [ ] Hard refresh mid-draft: on-clock indicator and countdown correct immediately
- [ ] Draft complete: "Room closes in X" counts down
- [ ] Overnight pause: banner shows, pick buttons still enabled, timer frozen
- [ ] `npm run test:run` — all 158 files / 2351 tests pass

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Chris Parsons <chrisparsons1127@gmail.com>
Reviewed-on: #72
2026-06-06 05:57:46 +00:00
.claude Refactor league settings into per-section components (#379) 2026-05-05 14:19:50 -07:00
.forgejo/workflows Optimize CI pipeline: merge check jobs, remove docker install, improve layer caching 2026-05-31 21:37:01 -07:00
.opencode/plugins Add opencode oxlint plugin and UI refinements (#323) 2026-04-24 11:11:20 -07:00
.production-info Fix draft timer: broadcasts, increments, reconnect sync, overnight pause (#72) 2026-06-06 05:57:46 +00:00
.storybook New design (#309) 2026-04-23 13:14:55 -07:00
.vscode feat: add Sentry error monitoring (#132) 2026-03-10 23:35:33 -07:00
app Fix draft timer: broadcasts, increments, reconnect sync, overnight pause (#72) 2026-06-06 05:57:46 +00:00
cypress Fix oxlint warnings: no-shadow, consistent-function-scoping, no-non-null-assertion, and others (#196) 2026-03-21 10:59:51 -07:00
database Fix draft timer: broadcasts, increments, reconnect sync, overnight pause (#72) 2026-06-06 05:57:46 +00:00
docs Fix draft timer: broadcasts, increments, reconnect sync, overnight pause (#72) 2026-06-06 05:57:46 +00:00
drizzle Fix draft timer: broadcasts, increments, reconnect sync, overnight pause (#72) 2026-06-06 05:57:46 +00:00
plans Fix draft timer: broadcasts, increments, reconnect sync, overnight pause (#72) 2026-06-06 05:57:46 +00:00
public Fix robots.txt and sitemap issues from code review 2026-05-24 22:16:49 -07:00
scripts Add robots.txt and sitemap.xml.gz for SEO 2026-05-24 22:05:37 -07:00
server Fix draft timer: broadcasts, increments, reconnect sync, overnight pause (#72) 2026-06-06 05:57:46 +00:00
test-fixtures/baselines chore: capture pre-migration baselines 2026-04-30 23:09:24 -07:00
.dockerignore Optimize CI pipeline: merge check jobs, remove docker install, improve layer caching 2026-05-31 21:37:01 -07:00
.env.example Add Cloudinary-backed avatar system (#385) 2026-05-06 14:47:37 -07:00
.gitignore Fix robots.txt and sitemap issues from code review 2026-05-24 22:16:49 -07:00
.npmrc Migrate authentication from Clerk to BetterAuth (#324) 2026-04-24 22:00:49 -07:00
.nvmrc Optimize GitHub Actions CI/CD pipeline (#252) 2026-04-01 00:59:21 -07:00
.oxlintrc.json Replace console.* with structured logger, fix no-inferrable-types (closes #98) (#199) 2026-03-21 13:41:39 -07:00
AGENTS.md Docs update 2026-05-04 09:33:13 -07:00
BETTERAUTH_MIGRATION.md Migrate authentication from Clerk to BetterAuth (#324) 2026-04-24 22:00:49 -07:00
CLAUDE.md Docs update 2026-05-04 09:33:13 -07:00
components.json feat: add theme system with dark mode support and navbar component 2025-10-10 23:30:26 -07:00
cypress.config.js ci: add test job to GitHub workflow and setup testing dependencies 2025-10-21 12:47:11 -07:00
docker-compose.yml feat: add FIFA World Cup 48-team bracket template with group stage and projected scoring 2026-02-14 22:30:12 -08:00
Dockerfile Fix Docker build: copy root server.ts into build-env stage 2026-05-31 21:56:17 -07:00
drizzle.config.ts Add PgBouncer connection pooling support for Vultr managed PostgreSQL (#271) 2026-04-06 17:15:18 -04:00
instrument.server.mjs Block bot probe requests before routing (#444) 2026-05-18 11:17:18 -07:00
oxlint.json Add oxlint config and fix unicorn/no-array-sort violation 2026-05-21 17:01:02 -07:00
package-lock.json Add Cloudinary-backed avatar system (#385) 2026-05-06 14:47:37 -07:00
package.json Add robots.txt and sitemap.xml.gz for SEO 2026-05-24 22:05:37 -07:00
plan.md Add implementation plan for commissioner-without-team feature (#6) 2026-02-20 08:45:09 -08:00
react-router.config.ts Add oxlint linting setup with zero errors (#194) 2026-03-21 09:44:05 -07:00
README.md Initial commit from create-react-router 2025-10-10 23:04:50 -07:00
server.ts Decouple database migrations from server startup (#265) 2026-04-06 00:07:36 -04:00
TESTING.md ci: add test job to GitHub workflow and setup testing dependencies 2025-10-21 12:47:11 -07:00
tsconfig.json refactor: update import paths to use absolute paths for better clarity and maintainability 2025-10-24 21:20:19 -07:00
tsconfig.node.json Add oxlint linting setup with zero errors (#194) 2026-03-21 09:44:05 -07:00
tsconfig.server.json Add oxlint linting setup with zero errors (#194) 2026-03-21 09:44:05 -07:00
tsconfig.vite.json Add oxlint linting setup with zero errors (#194) 2026-03-21 09:44:05 -07:00
vite.config.ts New design (#309) 2026-04-23 13:14:55 -07:00
vitest.config.ts Fix test:run failing in CI due to missing Playwright browser (#246) 2026-03-30 14:42:23 -07:00
vitest.shims.d.ts Install Storybook with React Router Vite plugin fix, closes #229 (#243) 2026-03-29 15:20:48 -07:00

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.