This file is a concise, repo-accurate guide for agentic coding assistants working in this repository. It summarizes the commands, conventions, and constraints inferred from configuration files and code.
- Build:
npm run build- Runs
save-commit-info, lint, and Nest build.
- Runs
- Dev server:
npm run start:dev - Debug server:
npm run start:debug - Prod server:
npm run start:prodprestart:prodrunsnpm run db:migrations:applyautomatically.
- Lint (Biome):
npm run lint - Lint + fix:
npm run lint:fix - Lint + fix (unsafe):
npm run lint:fix:unsafe - Type check:
npm run ts:check - Full check:
npm run check(type check + lint:fix + knip)
Pre-commit hooks (lefthook.yml):
pre-commit(parallel): runsnpm run check+npm run test(unit)pre-push: runsnpm run test:cov— blocks push if coverage drops below 80%
Do not bypass hooks unless explicitly asked.
- Unit tests:
npm run test - Watch mode:
npm run test:watch - Coverage:
npm run test:cov - E2E tests:
npm run test:e2e - All tests:
npm run test:all
Run a single unit test file (use npm scripts to preserve VITEST_TARGET):
npm run test -- src/modules/profile/profile.service.spec.tsRun a single E2E test file:
npm run test:e2e -- test/app.e2e.spec.tsDocker services (recommended for local dev):
docker-compose up -d db redisPrisma workflows:
npm run db:migrations:applynpm run db:migrations:createnpm run db:gennpm run db:resetnpm run db:schema:formatnpm run db:seed
- Biome is the formatter and linter.
- Quotes: single (
') - Indent: spaces
- Line endings: LF
- Imports are organized by Biome on format.
- Unused imports/vars/params are errors.
strict: true,noImplicitAny,noUncheckedIndexedAccessnoImplicitReturns,noUnusedLocals,noUnusedParameters- Prefer explicit return types where inference is unclear
- Modules:
*.module.ts - Services:
*.service.ts - Controllers:
*.controller.ts - Resolvers:
*.resolver.ts - Feature modules live under
src/app/and shared/common code undersrc/common/.
- Thin Controllers/Resolvers: Handle ONLY HTTP/GraphQL specifics (decorators, extracting inputs). No business logic, no
if/elseon domain data. - Fat Services: All business logic, Prisma calls, and external integrations live here.
- Validation: Use
nestjs-zodfor all DTOs and GraphQL Inputs. Never validate manually inside services. - Imports: ALWAYS use the
@/alias for internal imports (maps tosrc/). Never use relative paths like../../.
- Prefer small, focused functions.
- Keep dependencies explicit (Nest DI, constructor injection).
- Avoid mutation and hidden side effects where possible.
- TDD is mandatory: Write the test BEFORE the implementation (Red → Green → Refactor).
- Framework: ALWAYS use
vitest. Never usejest. - Test placement by layer:
- Controllers and Resolvers → E2E tests only (
test/<name>.e2e.spec.ts) - Services → Unit tests only (
src/modules/<name>/<name>.service.spec.ts)
- Controllers and Resolvers → E2E tests only (
- E2E Tests: Do NOT use
supertest,pactum, oraxios. Always useE2EClientandcreateTestingAppfromtest/utils/(Fastify inject). - Mocking: Do NOT use
as unknown as Typein tests. Always usemock<T>()ormockDeep<T>()fromvitest-mock-extended. - Test Data: Do NOT call
prisma.model.create()directly in tests. Use factories fromtest/factories/(e.g.createProfile,createUpload). If a factory for a model doesn't exist, create it first. - RBAC testing: Use
client.loginAs(user)to authenticate as a specific factory-created profile. Useclient.logout()to reset. - File uploads: Use
client.uploadFile(url, filename, buffer, mimetype)— do NOT constructmultipart/form-datamanually. - AAA Pattern: Follow Arrange-Act-Assert strictly. Do NOT use
if/elselogic inside tests. - Context Mocks: For
ExecutionContextandArgumentsHost, use factories fromtest/utils/mocks.ts. - Coverage threshold: Lines / Functions / Branches / Statements must stay ≥ 80%. Check with
npm run test:cov.
- Global exception handling uses
AllExceptionsFilter. - Throw
HttpExceptionsubclasses for HTTP errors. - Non-HTTP errors should be logged and mapped to consistent error shapes.
- Logging uses
nestjs-pino; avoidconsole.*outside bootstrap error handling.
- Configuration is via
@nestjs/configand.envfiles. - Use
ConfigService.getOrThrow()for required envs. - Validation uses
nestjs-zod+ZodValidationPipe.
No Copilot rules (.github/copilot-instructions.md) are used in this repo.
Skills live in .agents/skills/. Each skill is a SKILL.md file that guides agents through a specific workflow.
All skill content must be written in English only. This applies to descriptions, instructions, comments, and any other text inside SKILL.md files.
Do
- Write tests BEFORE implementation (TDD: Red → Green → Refactor).
- Use
npm run checkbefore commit. - Use Biome to format and organize imports.
- Follow NestJS module/service/controller/resolver patterns.
- Prefer explicit types at boundaries (DTOs, config, external IO).
- Use
vitest-mock-extended(mockDeep) for mocking dependencies. - Use
E2EClient(Fastify inject) for all E2E testing. - Use factories (
test/factories/) to create test data in E2E tests. - Follow the AAA (Arrange-Act-Assert) pattern in specs.
- Keep Controllers/Resolvers thin — business logic belongs in Services.
Don’t
- Write production code before writing the failing test.
- Bypass lefthook/pre-commit checks unless explicitly asked.
- Introduce unused imports/variables (Biome treats them as errors).
- Add undocumented scripts or commands not present in package.json.
- Use
as unknown asto bypass TypeScript in tests. - Use
pactum,supertest, or bind real ports in E2E tests. - Write conditional logic (
if/else) inside test assertions. - Call
prisma.model.create()directly in tests — use factories instead. - Put business logic in Controllers or Resolvers.
- Use relative paths (
../../) for internal imports — use@/alias.