# AGENTS.md — Work Hub Server ## Project Structure ``` work-hub-server/ ├── apps/ │ ├── api/ # NestJS 11 API (Express platform) │ └── web/ # Nuxt 4 app (Vue 3 + Nuxt UI) ├── packages/ │ └── schema/ # Shared schema package (empty placeholder) ├── openspec/ # OpenSpec config ├── turbo.json # Turborepo pipeline config └── package.json # Root workspace scripts ``` ## Build / Dev / Lint / Test Commands All commands run from the repository root. ### Root (Turborepo orchestrated) | Command | Description | | ------------------ | ------------------------------------- | | `pnpm build` | Build all apps/packages | | `pnpm dev` | Start all apps in dev mode | | `pnpm lint` | Lint all apps | | `pnpm format` | Prettier format all `*.ts,*.tsx,*.md` | | `pnpm check-types` | Type-check all apps | **Filtering to a single app:** `pnpm --filter=api build` ### API (NestJS) | Command | Description | | ------------------------------ | ------------------------------- | | `pnpm --filter=api test` | Run all unit tests | | `pnpm --filter=api test:watch` | Watch mode | | `pnpm --filter=api test:cov` | With coverage | | `pnpm --filter=api test:e2e` | Run e2e tests | | `pnpm --filter=api lint` | ESLint with `--fix` | | `pnpm --filter=api dev` | Start in watch mode (port 3001) | **Single unit test:** `pnpm --filter=api jest -- --testPathPattern="app.controller"` **Single e2e test:** `pnpm --filter=api jest --config ./test/jest-e2e.json --testPathPattern="app.e2e"` ### Web (Nuxt) | Command | Description | | ----------------------------- | ---------------------- | | `pnpm --filter=web dev` | Dev server (port 3000) | | `pnpm --filter=web build` | Production build | | `pnpm --filter=web lint` | ESLint | | `pnpm --filter=web typecheck` | `nuxt typecheck` | ## Code Style Guidelines ### Language & Runtime - **100% TypeScript** throughout the monorepo. - **Node >= 18** (root `engines` field). - Package manager: **pnpm 9** (see `pnpm-workspace.yaml`). ### Imports - Use **ESM `import` syntax** everywhere (`import { Foo } from './foo'`). - No barrel/index re-exports unless the package explicitly defines them. - API app: nestjs/common/core imports first, then local relative imports (`'./file'`). - Web app: auto-imports via Nuxt (components, composables); explicit imports for external modules. ### Formatting - **Prettier** with `singleQuote: false`, `trailingComma: 'all'`. - Quote strings with double quotes (single quotes for JSX attributes). - Run `pnpm format` before committing. ### Linting - **ESLint flat config** (`eslint.config.mjs`) in each app. - API uses `@typescript-eslint` with `recommendedTypeChecked` rules, plus `eslint-plugin-prettier`. - Key relaxed rules: - `@typescript-eslint/no-explicit-any: off` - `@typescript-eslint/no-floating-promises: warn` - Web uses `@nuxt/eslint` with stylistic config (`commaDangle: never`, `braceStyle: 1tbs`). ### TypeScript - **Target:** ES2023 - **Module:** `nodenext` with `moduleResolution: nodenext` - **Strict null checks** enabled (`strictNullChecks: true`). - Decorators enabled (`emitDecoratorMetadata`, `experimentalDecorators`). - `noImplicitAny: false` (API) — explicit `any` allowed but prefer proper types. - `skipLibCheck: true`, `forceConsistentCasingInFileNames: true`. - Web references Nuxt-generated tsconfig files (project references). ### Naming Conventions - **Classes:** PascalCase (`AppController`, `AppService`). - **Files:** kebab-case (`app.controller.ts`, `app.e2e-spec.ts`). - **Variables/functions:** camelCase. - **Test files:** `*.spec.ts` (unit), `*.e2e-spec.ts` (e2e), co-located with source. - **Decorators:** PascalCase (`@Controller()`, `@Injectable()`, `@Get()`). ### Error Handling - **API (NestJS):** Use NestJS exception filters, `@nestjs/common` exceptions (e.g., `NotFoundException`, `BadRequestException`). Avoid raw `throw Error`. - **Web (Nuxt):** Use Nuxt layers/plugins for error handling. Vue composition API with `try/catch` in async handlers. ### Testing (API app) - **Framework:** Jest 30 with `ts-jest`. - **Test location:** Unit tests live in `src/` alongside source files (`*.spec.ts`). E2e tests in `test/` (`*.e2e-spec.ts`). - **Pattern:** `describe`/`it` blocks. Use `@nestjs/testing` `Test.createTestingModule` for integration. - SuperTest for HTTP e2e tests. - Coverage output goes to `coverage/`. ### NestJS-Specific Conventions - Modules import providers/controllers; root module is `AppModule`. - Services decorated with `@Injectable()`, controllers with `@Controller()`. - Constructor-based DI with `private readonly` shorthand. - Default port 3001 (from `main.ts`). ### Vue/Nuxt-Specific Conventions - **Composition API** with `