brackt/docs/agents/architecture.md
2026-04-15 19:50:39 -07:00

2 KiB

Architecture

Server

Dual-server setup:

  • server.ts — HTTP server entry point, initializes Socket.IO
  • server/app.ts — Express app with React Router SSR handler and database context
  • server/socket.ts — Socket.IO server for real-time draft updates
  • server/timer.ts — Runs every second via setInterval to advance draft timers. Uses a dedicated DB connection. Must be started for draft functionality to work.

Database Layer

  • Schema: database/schema.ts
  • Context: database/context.ts — DB connection injected via AsyncLocalStorage
  • Models: app/models/ — all DB queries live here, organized by domain (e.g. league.ts, season.ts, draft-pick.ts)

Always query through the model layer — never write Drizzle queries directly in route files.

Frontend

  • Routes config: app/routes.ts — all routes must be explicitly registered here (React Router 7 does not auto-discover files)
  • Route files: app/routes/ — file naming uses . as path separator; $param for dynamic segments; _index.tsx for index routes
  • Components: app/components/ — UI primitives in app/components/ui/ (ShadCN)
  • Hooks: app/hooks/ — custom React hooks
  • Lib: app/lib/ — pure utility functions

Real-time (Socket.IO)

Clients join a room per season. Key events:

Event Direction Trigger
join-draft client → server on draft page load
timer-update server → client every second during active draft
pick-made server → client participant drafted
autodraft-updated server → client team enables/disables autodraft
team-connected / team-disconnected server → client presence

Server emits via getSocketIO() from server/socket.ts. Clients consume via useDraftSocket() hook at app/hooks/useDraftSocket.ts.

Adding a Socket Event

  1. Define types in server/socket.d.ts
  2. Add handler in server/socket.ts
  3. Emit from server: getSocketIO().to(room).emit(...)
  4. Listen in client component or hook