work-hub-server/AGENTS.md

5.5 KiB

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
    • @typescript-eslint/no-unsafe-argument: 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 <script setup> (no Options API).
  • Single-file components (.vue) with template, script, style sections.
  • Auto-imports for Nuxt composables (useHead, useSeoMeta, defineAppConfig).
  • Nuxt UI components (UApp, UHeader, UButton, etc.) are auto-imported.
  • CSS: Tailwind CSS v4 via @import "tailwindcss" in main.css.
  • TypeScript config references .nuxt/tsconfig.*.json — do not edit directly.