Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Use when building or extending a TypeScript service on Node.js - Fastify, NestJS, Express or Hono, runtime validation at the boundary, strict types, the repository's ORM and migrations, async error handling, graceful shutdown
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
설치 방법 보기설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.
A Node.js service is TypeScript at compile time and untyped JavaScript at run time. Every type at the edge — a request body, a header, an environment variable, a queue message, a row from a raw query — is a claim until something checks it.
Core principle: the repository's framework, package manager, module system and ORM win. Parse input at the boundary into typed values; keep the domain free of the framework.
app.inject() for tests, pino logging built in.| Layer | Responsibility |
|---|---|
| Route / controller | Parse and validate input, call one service, map the result and errors to HTTP |
| Service | Use-case orchestration and business rules; takes plain typed values |
| Domain | Types, invariants, pure functions — no framework import |
| Adapter | Database, outbound HTTP, queues — behind an interface the service depends on |
pnpm-lock.yaml → pnpm, yarn.lock → yarn, package-lock.json → npm; install with the frozen form (pnpm install --frozen-lockfile, npm ci). Node version from .nvmrc, .node-version or engines; a new service targets the current Active LTS.package.json: "type": "module" means ESM (relative imports carry .js under NodeNext); otherwise CommonJS. Never mix them in one package.strict: true. No any; unknown at the boundary, narrowed by a parser. No non-null ! to silence a real undefined.z.infer) so the two cannot drift. Environment variables are parsed once at startup by the same means and the process exits on a bad one.setErrorHandler, a Nest exception filter, Express 5's error middleware) maps domain errors to 400/404/409 problem+json; an unknown error is logged with its stack and answered 500 without it.@typescript-eslint/no-floating-promises catches the rest). An unhandled rejection crashes the process in current Node.fetch(url, { signal: AbortSignal.timeout(5_000) }) or the client's own timeout; retries only for idempotent calls (resilient-io-and-jobs).*Sync file or crypto calls on a request path, no unbounded JSON.parse of a large body, CPU-heavy work in a worker thread or a job.pg — with parameters, never string-built SQL ($queryRawUnsafe and sql.raw with input are bugs). Migrations through that tool (prisma migrate dev --name, drizzle-kit generate), committed with the schema change; postgres-migrations covers safe DDL.nestjs-pino) with structured fields, request id bound per request; no console.log in service code; redact secrets and tokens (redact option).close(), Nest enableShutdownHooks().POST /tasks in Fastify with zod:
const CreateTask = z.object({ title: z.string().trim().min(1).max(200) });
export function taskRoutes(app: FastifyInstance, service: TaskService) {
app.post("/tasks", async (req, reply) => {
const parsed = CreateTask.safeParse(req.body);
if (!parsed.success) {
return reply.code(400).type("application/problem+json").send(problemFrom(parsed.error));
}
const task = await service.create(parsed.data.title, req.user.id);
return reply.code(201).header("location", `/tasks/${task.id}`).send(toResponse(task));
});
}
TaskService.create takes a string and an owner id and knows nothing of Fastify; Task.create enforces the 200-character rule again for callers that are not HTTP.
The repository's scripts first (list_component_checks, package.json, CI): typically npm run typecheck (or tsc --noEmit), npm run lint, npm test, npm run build. For the runtime check build once and run the output — npm run build, then PORT=18080 node dist/main.js in the background with its pid recorded — not a watcher (npm run dev, tsx watch, nodemon), which never exits and restarts under you.
req.body as CreateTaskDto — a cast is not a check.async route handlers in Express 4 without a wrapper: the rejection never reaches the error middleware.for loop where one query or Promise.all with a bound would do — or Promise.all over an unbounded list.process.env.X! scattered through the code instead of one parsed config object.any in a new signature, or // @ts-ignore / @ts-expect-error added to get a build green.console.log of a request body that may hold a token or a password.아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.
로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.
아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.
Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Use when the diff adds or changes an endpoint, resolver, RPC, job or query that takes an object id, a role check, a request binding or a tenant filter - BOLA/IDOR, function-level authorization, mass assignment and tenant scoping
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Use on every UI change - semantic HTML, labels for controls, keyboard-navigable dialogs/menus, visible focus, and never color as the only signal
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Use when a task changes any screen, form, dialog, menu or control - Lighthouse/axe scan of the changed screens, a keyboard walk, and the thresholds that fail a task
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
How to work a task returned with review, QA or UAT findings. Use when a task is in need_revision or PR review comments are in your context.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Use when the repository keeps its alerting in code, or a person asks for alerts outside TaskTrooper - PrometheusRule YAML, a Cloud Monitoring alert policy in Terraform, a Datadog monitor, each routed to TaskTrooper's alert ingest URL so it opens an incident here
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.