1
# Repository Guidelines
## Environment
- Local Mongo + Redis contain disposable dev data. Safe to drop/flush as needed; no production users. Everything is safe to start from scratch as of right now.
- Prefer `pnpm ds` to reseed after wipes.
- For ad-hoc testing, you can write directly to Redis with `redis-cli` (any key/type as needed).
- Initial deployments are not meant to be public facing yet; keep search engine/AI crawler blocking (`noindex`/`noai`) in place until explicitly told to remove it.
- This repo supports Windows dev environments. Do not run `pnpm install`, `pnpm lint`, `pnpm test`, or any Node/Vite/dev-server commands from WSL against the `/mnt/c/...` workspace, because it can cause Windows-native binaries in `node_modules` (e.g. `esbuild.exe`) to become locked or cross-platform-mismatched. Use Windows terminals for installs/tests/servers; WSL is only for Codex CLI and services like Redis.
- Do not remind the user about the WSL/Windows restriction unless explicitly asked or it directly blocks the current task.
- If the user includes the abbreviation "DWC" in all caps in a prompt, do not make any file changes for that request.
## Project Structure & Module Organization
The project is split into `client/` (Vite + React TypeScript UI), `server/` (Express, Auth.js, and Socket.IO services), and `shared/` (types and utility functions consumed by both runtimes).
## Vendor Restrictions (No Vercel)
- Do **not** introduce or recommend any Vercel products or services in this repo.
- This includes (non-exhaustive): Vercel hosting/deployment, `vercel` CLI/config, `@vercel/*` packages, Vercel Analytics/Speed Insights, Vercel Edge/Serverless Functions, and Vercel-managed integrations.
- Prefer stack choices that keep the current architecture (Express + Vite + React) and deploy to non-Vercel providers when deployment guidance is needed.
## Build, Test, and Development Commands
Run `pnpm start` from the repo root to launch API, client, and MongoDB concurrently; use `pnpm start-no-db` when an external database is already running. `pnpm run client` and `pnpm run server` start each service individually, while `pnpm run db` launches the local Mongo daemon writing to `server/devdata`. Build the production bundle with `pnpm run build` (delegates to `client/build`).
## Coding Style & Naming Conventions
All code is strict mode TypeScript with ES modules and 2-space indentation; the Biome config (line width 120, trailing commas `es5`) is shared across `client/` and `server/`. Keep filenames kebab-case on the server (e.g., `redisExpirationSubscriptionEvents.ts`) and PascalCase for React components (e.g., `GameBoard.tsx`). Biome enforces import sorting and lint rules—run `pnpm lint` or the package-specific lint scripts before pushing.
### Personal Preferences
- Use arrow functions by default; avoid the `function` keyword in ~99% of cases unless there is a truly exceptional reason.
- Avoid `class`es; prefer functions unless an API absolutely requires a class (e.g., `Error` subclasses).
- Inline single-use helpers and variables instead of introducing extra names.
- Avoid standalone one-off factory/initializer helpers; inline the literal where it is used if it otherwise would only be referenced once in that scope.
- Avoid unnecessary helper types (e.g., `Record` wrappers for inline objects); rely on inference unless linting or clarity demands an explicit type.
- Prefer `for...of` loops over `[].forEach` when it fits the use case.
- Keep the ranking logic numerically robust, but default to concise guards when data is guaranteed (e.g., no legacy streak fields).
- Use deliberate vertical whitespace: add blank lines after guard clauses, before returns, and around major conditional branches to keep logic blocks readable.
- Prefer a single guard branch with one return when multiple guard checks lead to the same exit path.
- When multiple guard checks share the same exit, combine them into a single conditional block rather than separate return statements.
- Ignore legacy data concerns; schema changes can assume a fresh database with no backward-compatibility guards.
- Prefer `interface` over `type` in most cases, especially for key:value object shapes; reserve `type` for unions or utility aliases.
- Prefer `as` casts over `is` type predicates for simple filter narrowing, when a cast is acceptable.
- Organize imports in grouped blocks: third-party/built-ins first, then local modules, with type-only imports grouped separately; keep each block alphabetized.
- Always use `import type` for type-only symbols—even if it means duplicating import paths alongside value imports.
- Do not mix value imports and `type` specifiers within the same statement; emit a dedicated `import type` line (even from the same module) so the grouping stays clean.
- Always use braces with control flow statements (if, for, while, etc.) even when the body is a single statement or return. Never write inline `if (!x) return;`—always expand to a multi-line block with braces.
- Match existing module patterns for error handling and caching; don't add extra try/catch or type scaffolding unless nearby code already does.
## Material-UI Grid and Grid2
This project uses the most latest version of MUI, and its new Grid (Grid2) component - do not use the first Grid at all, and make sure to not use the `item` prop. Never try to manually import Grid2, just use the standard `import { Grid } from @mui/material`.
## Testing Guidelines
Unit tests live beside the code they cover: Vitest specs in `client/src/**/tests/*.test.ts[x]`, Node test runner suites in `server/socket/**/tests/*.test.ts`, and shared logic tests in `shared/tests/*.test.ts`. Execute `pnpm test` to run all suites concurrently, or narrow with `pnpm test:client`, `pnpm test:server`, or `pnpm test:shared`. Use `pnpm test:client:watch` or `pnpm test:shared:watch` during development; aim to keep high-impact move/board logic covered before merging. JSX component tests (vitest) are currently not included in this repo and should not be added when working on client side code.
## Commit & Pull Request Guidelines
Follow the existing history by using short, imperative summaries (`rename join queue`, `add matchmaking updates`) and include relevant scope keywords when useful. Reference tickets in the body (`Refs #123`) and attach screenshots or console output for UI and matchmaking changes. Pull requests should describe the feature, list manual verification steps (`pnpm test`, `pnpm lint`), and flag any database or Redis setup needed for reviewers.
- Git commits should be short notes to "future self" that capture the meaningful change. Don't enumerate trivial edits, and feel free to label context-only or machine-handoff commits as `wip` when that's the intent.
- When a commit is requested, always stage all relevant changes first (e.g., `git add -A`) so that newly created files are not missed before running `git commit`.
- Do not add "Generated with [AI Tool]" footers or "Co-Authored-By" lines to commits.
This application is in active development, and warnings like "this should be changed before production" should not be called out as there's little value to comments like that at this stage of this application.
## Environment & Data Setup
Stick to Node `>=22.14.0` as enforced in every package. Prime local stores with `pnpm ds` (drops Mongo/Redis, seeds dev data) or wipe via `pnpm da` when debugging auth issues. Never commit files from `server/devdata/` or local coverage results; add environment secrets via `.env` files mirrored to teammates through a secure channel.
---
### Note for automated / AI PR reviewers
This project is in active, non-production development. Data models, seeds, and service contracts are expected to change frequently. It is normal here to drop/reseed/wipe the entire datastore while iterating. Do **not** flag "legacy users," "legacy data," or "incompatible model changes" as issues at this stage — backward compatibility is not a requirement until deployment is locked.
For immediate assistance, please email our customer support: [email protected]