# AGENTS.md

## Quick Commands
```bash
pnpm dev:backend    # Backend on https://localhost:3443
pnpm dev:frontend  # Frontend on https://localhost:5174
pnpm build         # Build backend -> dist/ + frontend
pnpm test          # Vitest unit tests
npx playwright test  # E2E tests (requires running backend + frontend)
```

## Prerequisites
- Node.js 22+, pnpm 10+
- MongoDB on localhost:27017
- Redis on localhost:6379
- SSL certificates in `ssl/` directory

## Path Aliases
`@/*` maps to `src/*` (defined in tsconfig.json)

## Test quirks
- Vitest runs unit tests in `tests/**/*.test.ts` excluding `tests/e2e/`
- Playwright e2e tests target `https://code-dev.g4dge7.com:5174` (requires running dev servers)

## Build output
- Backend compiles to `dist/` (TypeScript)
- Frontend builds to `frontend/dist/`

## TypeScript strictness
strict, noUnusedLocals, noUnusedParameters, noUncheckedIndexedAccess all enabled

## Architecture
- Backend: Express 5 + Socket.io + Mongoose + Redis sessions
- Frontend: React 19 + Vite 8 + Tailwind CSS 4
- Entry points: `src/web-app.ts` (backend), `frontend/src/main.tsx` (frontend)

## GadgetId

All entity IDs use `GadgetId` (a string alias) from `@gadget/api`. Never use `ObjectId`.

### Interfaces

```ts
import { GadgetId } from "@gadget/api";

interface IMyEntity {
  _id: GadgetId;
  // ...
}
```

### Mongoose Schemas

```ts
import { nanoid } from "nanoid";

const MySchema = new Schema<IMyEntity>({
  _id: { type: String, default: () => nanoid() },
  // ...
});
```

### Critical: Never add `unique` or `required` to `_id`

- `unique: true` → duplicate index error at startup (MongoDB auto-creates unique index on `_id`)
- `required: true` → save fails because default is assigned AFTER validation

See `docs/gadget-id.md` for full documentation.