tribunal-kit 3.0.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (233) hide show
  1. package/.agent/ARCHITECTURE.md +99 -99
  2. package/.agent/GEMINI.md +52 -52
  3. package/.agent/agents/accessibility-reviewer.md +187 -220
  4. package/.agent/agents/ai-code-reviewer.md +199 -233
  5. package/.agent/agents/backend-specialist.md +215 -238
  6. package/.agent/agents/code-archaeologist.md +161 -181
  7. package/.agent/agents/database-architect.md +184 -207
  8. package/.agent/agents/debugger.md +191 -218
  9. package/.agent/agents/dependency-reviewer.md +103 -136
  10. package/.agent/agents/devops-engineer.md +218 -238
  11. package/.agent/agents/documentation-writer.md +201 -221
  12. package/.agent/agents/explorer-agent.md +160 -180
  13. package/.agent/agents/frontend-reviewer.md +160 -194
  14. package/.agent/agents/frontend-specialist.md +248 -237
  15. package/.agent/agents/game-developer.md +48 -52
  16. package/.agent/agents/logic-reviewer.md +116 -149
  17. package/.agent/agents/mobile-developer.md +200 -223
  18. package/.agent/agents/mobile-reviewer.md +162 -195
  19. package/.agent/agents/orchestrator.md +181 -211
  20. package/.agent/agents/penetration-tester.md +157 -174
  21. package/.agent/agents/performance-optimizer.md +183 -203
  22. package/.agent/agents/performance-reviewer.md +178 -211
  23. package/.agent/agents/precedence-reviewer.md +213 -0
  24. package/.agent/agents/product-manager.md +142 -162
  25. package/.agent/agents/product-owner.md +6 -25
  26. package/.agent/agents/project-planner.md +142 -162
  27. package/.agent/agents/qa-automation-engineer.md +225 -242
  28. package/.agent/agents/security-auditor.md +174 -194
  29. package/.agent/agents/seo-specialist.md +193 -213
  30. package/.agent/agents/sql-reviewer.md +161 -194
  31. package/.agent/agents/supervisor-agent.md +184 -203
  32. package/.agent/agents/swarm-worker-contracts.md +17 -17
  33. package/.agent/agents/swarm-worker-registry.md +46 -46
  34. package/.agent/agents/test-coverage-reviewer.md +160 -193
  35. package/.agent/agents/test-engineer.md +0 -21
  36. package/.agent/agents/type-safety-reviewer.md +175 -208
  37. package/.agent/patterns/generator.md +9 -9
  38. package/.agent/patterns/inversion.md +12 -12
  39. package/.agent/patterns/pipeline.md +9 -9
  40. package/.agent/patterns/reviewer.md +13 -13
  41. package/.agent/patterns/tool-wrapper.md +9 -9
  42. package/.agent/rules/GEMINI.md +63 -63
  43. package/.agent/scripts/append_flow.js +72 -0
  44. package/.agent/scripts/case_law_manager.py +525 -0
  45. package/.agent/scripts/compress_skills.py +167 -0
  46. package/.agent/scripts/consolidate_skills.py +173 -0
  47. package/.agent/scripts/deep_compress.py +202 -0
  48. package/.agent/scripts/minify_context.py +80 -0
  49. package/.agent/scripts/security_scan.py +1 -1
  50. package/.agent/scripts/skill_evolution.py +563 -0
  51. package/.agent/scripts/strip_tribunal.py +41 -0
  52. package/.agent/skills/agent-organizer/SKILL.md +100 -126
  53. package/.agent/skills/agentic-patterns/SKILL.md +0 -70
  54. package/.agent/skills/ai-prompt-injection-defense/SKILL.md +134 -160
  55. package/.agent/skills/api-patterns/SKILL.md +123 -215
  56. package/.agent/skills/api-security-auditor/SKILL.md +143 -177
  57. package/.agent/skills/app-builder/SKILL.md +334 -50
  58. package/.agent/skills/app-builder/templates/SKILL.md +13 -15
  59. package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +16 -16
  60. package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +22 -22
  61. package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +18 -18
  62. package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +20 -20
  63. package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +17 -17
  64. package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +18 -18
  65. package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +21 -21
  66. package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +19 -19
  67. package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +26 -26
  68. package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +26 -26
  69. package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +19 -19
  70. package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +18 -18
  71. package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +20 -20
  72. package/.agent/skills/appflow-wireframe/SKILL.md +95 -121
  73. package/.agent/skills/architecture/SKILL.md +169 -331
  74. package/.agent/skills/authentication-best-practices/SKILL.md +139 -173
  75. package/.agent/skills/bash-linux/SKILL.md +129 -154
  76. package/.agent/skills/behavioral-modes/SKILL.md +8 -69
  77. package/.agent/skills/brainstorming/SKILL.md +436 -104
  78. package/.agent/skills/building-native-ui/SKILL.md +152 -174
  79. package/.agent/skills/clean-code/SKILL.md +331 -360
  80. package/.agent/skills/code-review-checklist/SKILL.md +0 -62
  81. package/.agent/skills/config-validator/SKILL.md +115 -141
  82. package/.agent/skills/csharp-developer/SKILL.md +468 -528
  83. package/.agent/skills/database-design/SKILL.md +104 -369
  84. package/.agent/skills/deployment-procedures/SKILL.md +119 -145
  85. package/.agent/skills/devops-engineer/SKILL.md +295 -332
  86. package/.agent/skills/devops-incident-responder/SKILL.md +87 -113
  87. package/.agent/skills/doc.md +5 -5
  88. package/.agent/skills/documentation-templates/SKILL.md +27 -63
  89. package/.agent/skills/edge-computing/SKILL.md +131 -157
  90. package/.agent/skills/extract-design-system/SKILL.md +108 -134
  91. package/.agent/skills/framer-motion-expert/SKILL.md +111 -855
  92. package/.agent/skills/frontend-design/SKILL.md +151 -499
  93. package/.agent/skills/game-design-expert/SKILL.md +79 -105
  94. package/.agent/skills/game-engineering-expert/SKILL.md +96 -122
  95. package/.agent/skills/geo-fundamentals/SKILL.md +97 -124
  96. package/.agent/skills/github-operations/SKILL.md +279 -314
  97. package/.agent/skills/gsap-expert/SKILL.md +119 -826
  98. package/.agent/skills/i18n-localization/SKILL.md +113 -138
  99. package/.agent/skills/intelligent-routing/SKILL.md +167 -127
  100. package/.agent/skills/lint-and-validate/SKILL.md +16 -52
  101. package/.agent/skills/llm-engineering/SKILL.md +344 -357
  102. package/.agent/skills/local-first/SKILL.md +128 -154
  103. package/.agent/skills/mcp-builder/SKILL.md +92 -118
  104. package/.agent/skills/mobile-design/SKILL.md +213 -219
  105. package/.agent/skills/motion-engineering/SKILL.md +184 -0
  106. package/.agent/skills/nextjs-react-expert/SKILL.md +99 -698
  107. package/.agent/skills/nodejs-best-practices/SKILL.md +498 -559
  108. package/.agent/skills/observability/SKILL.md +293 -330
  109. package/.agent/skills/parallel-agents/SKILL.md +96 -122
  110. package/.agent/skills/performance-profiling/SKILL.md +217 -254
  111. package/.agent/skills/plan-writing/SKILL.md +92 -118
  112. package/.agent/skills/platform-engineer/SKILL.md +97 -123
  113. package/.agent/skills/playwright-best-practices/SKILL.md +137 -162
  114. package/.agent/skills/powershell-windows/SKILL.md +112 -146
  115. package/.agent/skills/project-idioms/SKILL.md +87 -0
  116. package/.agent/skills/python-patterns/SKILL.md +15 -35
  117. package/.agent/skills/python-pro/SKILL.md +148 -754
  118. package/.agent/skills/react-specialist/SKILL.md +123 -827
  119. package/.agent/skills/readme-builder/SKILL.md +23 -85
  120. package/.agent/skills/realtime-patterns/SKILL.md +269 -304
  121. package/.agent/skills/red-team-tactics/SKILL.md +18 -51
  122. package/.agent/skills/rust-pro/SKILL.md +623 -701
  123. package/.agent/skills/seo-fundamentals/SKILL.md +129 -154
  124. package/.agent/skills/server-management/SKILL.md +164 -190
  125. package/.agent/skills/shadcn-ui-expert/SKILL.md +181 -206
  126. package/.agent/skills/skill-creator/SKILL.md +24 -56
  127. package/.agent/skills/sql-pro/SKILL.md +579 -633
  128. package/.agent/skills/supabase-postgres-best-practices/SKILL.md +35 -66
  129. package/.agent/skills/swiftui-expert/SKILL.md +151 -176
  130. package/.agent/skills/systematic-debugging/SKILL.md +92 -118
  131. package/.agent/skills/tailwind-patterns/SKILL.md +516 -576
  132. package/.agent/skills/tdd-workflow/SKILL.md +111 -137
  133. package/.agent/skills/test-result-analyzer/SKILL.md +33 -73
  134. package/.agent/skills/testing-patterns/SKILL.md +512 -573
  135. package/.agent/skills/trend-researcher/SKILL.md +30 -71
  136. package/.agent/skills/ui-ux-pro-max/SKILL.md +8 -41
  137. package/.agent/skills/ui-ux-researcher/SKILL.md +51 -91
  138. package/.agent/skills/vue-expert/SKILL.md +127 -866
  139. package/.agent/skills/vulnerability-scanner/SKILL.md +354 -269
  140. package/.agent/skills/web-accessibility-auditor/SKILL.md +168 -193
  141. package/.agent/skills/web-design-guidelines/SKILL.md +25 -61
  142. package/.agent/skills/webapp-testing/SKILL.md +119 -145
  143. package/.agent/skills/whimsy-injector/SKILL.md +58 -132
  144. package/.agent/skills/workflow-optimizer/SKILL.md +28 -68
  145. package/.agent/workflows/api-tester.md +151 -151
  146. package/.agent/workflows/audit.md +127 -138
  147. package/.agent/workflows/brainstorm.md +110 -110
  148. package/.agent/workflows/changelog.md +112 -112
  149. package/.agent/workflows/create.md +124 -124
  150. package/.agent/workflows/debug.md +165 -189
  151. package/.agent/workflows/deploy.md +180 -189
  152. package/.agent/workflows/enhance.md +128 -151
  153. package/.agent/workflows/fix.md +114 -135
  154. package/.agent/workflows/generate.md +13 -4
  155. package/.agent/workflows/migrate.md +160 -160
  156. package/.agent/workflows/orchestrate.md +168 -168
  157. package/.agent/workflows/performance-benchmarker.md +114 -123
  158. package/.agent/workflows/plan.md +173 -173
  159. package/.agent/workflows/preview.md +80 -80
  160. package/.agent/workflows/refactor.md +161 -183
  161. package/.agent/workflows/review-ai.md +101 -129
  162. package/.agent/workflows/review.md +116 -116
  163. package/.agent/workflows/session.md +94 -94
  164. package/.agent/workflows/status.md +79 -79
  165. package/.agent/workflows/strengthen-skills.md +138 -139
  166. package/.agent/workflows/swarm.md +179 -179
  167. package/.agent/workflows/test.md +189 -211
  168. package/.agent/workflows/tribunal-backend.md +94 -113
  169. package/.agent/workflows/tribunal-database.md +95 -115
  170. package/.agent/workflows/tribunal-frontend.md +96 -118
  171. package/.agent/workflows/tribunal-full.md +93 -133
  172. package/.agent/workflows/tribunal-mobile.md +95 -119
  173. package/.agent/workflows/tribunal-performance.md +110 -133
  174. package/.agent/workflows/ui-ux-pro-max.md +122 -143
  175. package/README.md +30 -1
  176. package/bin/tribunal-kit.js +175 -12
  177. package/package.json +25 -4
  178. package/.agent/skills/api-patterns/api-style.md +0 -42
  179. package/.agent/skills/api-patterns/auth.md +0 -24
  180. package/.agent/skills/api-patterns/documentation.md +0 -26
  181. package/.agent/skills/api-patterns/graphql.md +0 -41
  182. package/.agent/skills/api-patterns/rate-limiting.md +0 -31
  183. package/.agent/skills/api-patterns/response.md +0 -37
  184. package/.agent/skills/api-patterns/rest.md +0 -40
  185. package/.agent/skills/api-patterns/security-testing.md +0 -122
  186. package/.agent/skills/api-patterns/trpc.md +0 -41
  187. package/.agent/skills/api-patterns/versioning.md +0 -22
  188. package/.agent/skills/app-builder/agent-coordination.md +0 -71
  189. package/.agent/skills/app-builder/feature-building.md +0 -53
  190. package/.agent/skills/app-builder/project-detection.md +0 -34
  191. package/.agent/skills/app-builder/scaffolding.md +0 -118
  192. package/.agent/skills/app-builder/tech-stack.md +0 -40
  193. package/.agent/skills/architecture/context-discovery.md +0 -43
  194. package/.agent/skills/architecture/examples.md +0 -94
  195. package/.agent/skills/architecture/pattern-selection.md +0 -68
  196. package/.agent/skills/architecture/patterns-reference.md +0 -50
  197. package/.agent/skills/architecture/trade-off-analysis.md +0 -77
  198. package/.agent/skills/brainstorming/dynamic-questioning.md +0 -360
  199. package/.agent/skills/database-design/database-selection.md +0 -43
  200. package/.agent/skills/database-design/indexing.md +0 -39
  201. package/.agent/skills/database-design/migrations.md +0 -48
  202. package/.agent/skills/database-design/optimization.md +0 -36
  203. package/.agent/skills/database-design/orm-selection.md +0 -30
  204. package/.agent/skills/database-design/schema-design.md +0 -56
  205. package/.agent/skills/frontend-design/animation-guide.md +0 -331
  206. package/.agent/skills/frontend-design/color-system.md +0 -329
  207. package/.agent/skills/frontend-design/decision-trees.md +0 -418
  208. package/.agent/skills/frontend-design/motion-graphics.md +0 -306
  209. package/.agent/skills/frontend-design/typography-system.md +0 -363
  210. package/.agent/skills/frontend-design/ux-psychology.md +0 -1116
  211. package/.agent/skills/frontend-design/visual-effects.md +0 -383
  212. package/.agent/skills/intelligent-routing/router-manifest.md +0 -65
  213. package/.agent/skills/mobile-design/decision-trees.md +0 -516
  214. package/.agent/skills/mobile-design/mobile-backend.md +0 -491
  215. package/.agent/skills/mobile-design/mobile-color-system.md +0 -420
  216. package/.agent/skills/mobile-design/mobile-debugging.md +0 -122
  217. package/.agent/skills/mobile-design/mobile-design-thinking.md +0 -357
  218. package/.agent/skills/mobile-design/mobile-navigation.md +0 -458
  219. package/.agent/skills/mobile-design/mobile-performance.md +0 -767
  220. package/.agent/skills/mobile-design/mobile-testing.md +0 -356
  221. package/.agent/skills/mobile-design/mobile-typography.md +0 -433
  222. package/.agent/skills/mobile-design/platform-android.md +0 -666
  223. package/.agent/skills/mobile-design/platform-ios.md +0 -561
  224. package/.agent/skills/mobile-design/touch-psychology.md +0 -537
  225. package/.agent/skills/nextjs-react-expert/1-async-eliminating-waterfalls.md +0 -312
  226. package/.agent/skills/nextjs-react-expert/2-bundle-bundle-size-optimization.md +0 -240
  227. package/.agent/skills/nextjs-react-expert/3-server-server-side-performance.md +0 -490
  228. package/.agent/skills/nextjs-react-expert/4-client-client-side-data-fetching.md +0 -264
  229. package/.agent/skills/nextjs-react-expert/5-rerender-re-render-optimization.md +0 -581
  230. package/.agent/skills/nextjs-react-expert/6-rendering-rendering-performance.md +0 -432
  231. package/.agent/skills/nextjs-react-expert/7-js-javascript-performance.md +0 -684
  232. package/.agent/skills/nextjs-react-expert/8-advanced-advanced-patterns.md +0 -150
  233. package/.agent/skills/vulnerability-scanner/checklists.md +0 -121
@@ -1,559 +1,498 @@
1
- ---
2
- name: nodejs-best-practices
3
- description: Node.js 22+ production mastery. ES Modules, async patterns, Express/Fastify/Hono, middleware architecture, error handling, streaming, worker threads, environment config, security hardening, process management, and deployment patterns. Use when building Node.js servers, APIs, CLI tools, or any server-side JavaScript.
4
- allowed-tools: Read, Write, Edit, Glob, Grep
5
- version: 2.0.0
6
- last-updated: 2026-04-01
7
- applies-to-model: gemini-2.5-pro, claude-3-7-sonnet
8
- ---
9
-
10
- # Node.js Best Practices — Node 22+ Production Mastery
11
-
12
- > Node.js is not "JavaScript on the server." It is an event-driven, non-blocking I/O runtime.
13
- > Every callback without error handling is a memory leak waiting to happen.
14
- > Every unhandled promise rejection is a crashed process in production.
15
-
16
- ---
17
-
18
- ## ES Modules (Mandatory)
19
-
20
- ```json
21
- // package.json — ALWAYS set type to module
22
- {
23
- "type": "module",
24
- "engines": { "node": ">=22" }
25
- }
26
- ```
27
-
28
- ```typescript
29
- // ESM imports (modern Node.js)
30
- import { readFile, writeFile } from "node:fs/promises";
31
- import { join, resolve } from "node:path";
32
- import { createServer } from "node:http";
33
- import { EventEmitter } from "node:events";
34
-
35
- // ❌ HALLUCINATION TRAP: Use node: protocol prefix for built-in modules
36
- // ❌ import fs from "fs"; ambiguous (could be npm package)
37
- // ✅ import fs from "node:fs"; ← explicitly a Node.js built-in
38
-
39
- // HALLUCINATION TRAP: Do NOT use require() in ESM projects
40
- // ❌ const fs = require("fs"); ← CommonJS (legacy)
41
- // ✅ import fs from "node:fs/promises"; ← ESM
42
-
43
- // Dynamic imports (for conditional loading)
44
- const module = await import("./heavy-module.js");
45
- ```
46
-
47
- ---
48
-
49
- ## Framework Selection
50
-
51
- ```
52
- ┌────────────────────────────────────────────────────────────┐
53
- When to Use What
54
- ├────────────────────────────────────────────────────────────┤
55
- Express Legacy projects, extensive middleware ecosystem
56
- │ Fastify │ Performance-critical APIs, schema validation │
57
- │ Hono │ Edge/serverless, multi-runtime (Node/Deno/Bun)│
58
- │ tRPC │ Full-stack TypeScript (Next.js + React Query) │
59
- Raw http │ Learning, minimal proxies, health checks │
60
- └────────────────────────────────────────────────────────────┘
61
- ```
62
-
63
- ### Fastify (Recommended)
64
-
65
- ```typescript
66
- import Fastify from "fastify";
67
- import { z } from "zod";
68
-
69
- const app = Fastify({
70
- logger: {
71
- level: process.env.LOG_LEVEL ?? "info",
72
- transport: process.env.NODE_ENV === "development"
73
- ? { target: "pino-pretty" }
74
- : undefined,
75
- },
76
- });
77
-
78
- // Schema validation with Zod → Fastify schema
79
- const CreateUserSchema = z.object({
80
- name: z.string().min(2).max(100),
81
- email: z.string().email(),
82
- role: z.enum(["admin", "user"]).default("user"),
83
- });
84
-
85
- type CreateUserBody = z.infer<typeof CreateUserSchema>;
86
-
87
- app.post<{ Body: CreateUserBody }>("/users", {
88
- schema: {
89
- body: {
90
- type: "object",
91
- required: ["name", "email"],
92
- properties: {
93
- name: { type: "string", minLength: 2 },
94
- email: { type: "string", format: "email" },
95
- role: { type: "string", enum: ["admin", "user"] },
96
- },
97
- },
98
- },
99
- }, async (request, reply) => {
100
- const validated = CreateUserSchema.parse(request.body);
101
- const user = await createUser(validated);
102
- return reply.status(201).send(user);
103
- });
104
-
105
- // Graceful shutdown
106
- const start = async () => {
107
- try {
108
- await app.listen({ port: 3000, host: "0.0.0.0" });
109
- } catch (err) {
110
- app.log.error(err);
111
- process.exit(1);
112
- }
113
- };
114
-
115
- start();
116
- ```
117
-
118
- ### Hono (Edge-First)
119
-
120
- ```typescript
121
- import { Hono } from "hono";
122
- import { cors } from "hono/cors";
123
- import { logger } from "hono/logger";
124
- import { zValidator } from "@hono/zod-validator";
125
- import { z } from "zod";
126
-
127
- const app = new Hono();
128
-
129
- app.use("*", logger());
130
- app.use("*", cors({ origin: "https://myapp.com" }));
131
-
132
- const createUserSchema = z.object({
133
- name: z.string().min(2),
134
- email: z.string().email(),
135
- });
136
-
137
- app.post("/users", zValidator("json", createUserSchema), async (c) => {
138
- const body = c.req.valid("json");
139
- const user = await createUser(body);
140
- return c.json(user, 201);
141
- });
142
-
143
- app.get("/health", (c) => c.json({ status: "ok" }));
144
-
145
- export default app; // works in Node, Deno, Bun, Cloudflare Workers
146
- ```
147
-
148
- ---
149
-
150
- ## Error Handling
151
-
152
- ### Global Error Handlers
153
-
154
- ```typescript
155
- // MANDATORY: Handle unhandled rejections and exceptions
156
- process.on("unhandledRejection", (reason, promise) => {
157
- console.error("Unhandled Rejection at:", promise, "reason:", reason);
158
- // Log to error tracking service (Sentry, etc.)
159
- // Gracefully shutdown
160
- process.exit(1);
161
- });
162
-
163
- process.on("uncaughtException", (error) => {
164
- console.error("Uncaught Exception:", error);
165
- // Log to error tracking service
166
- process.exit(1); // MUST exit state is corrupted
167
- });
168
-
169
- // ❌ HALLUCINATION TRAP: After uncaughtException, the process MUST exit
170
- // The process is in an undefined state — continuing is dangerous
171
- // process.on("uncaughtException", (err) => { console.log(err); }); // continues running
172
- // ✅ process.on("uncaughtException", (err) => { log(err); process.exit(1); });
173
- ```
174
-
175
- ### Application Error Classes
176
-
177
- ```typescript
178
- export class AppError extends Error {
179
- constructor(
180
- message: string,
181
- public statusCode: number = 500,
182
- public code: string = "INTERNAL_ERROR",
183
- public isOperational: boolean = true,
184
- ) {
185
- super(message);
186
- this.name = "AppError";
187
- Error.captureStackTrace(this, this.constructor);
188
- }
189
- }
190
-
191
- export class NotFoundError extends AppError {
192
- constructor(resource: string, id: string) {
193
- super(`${resource} '${id}' not found`, 404, "NOT_FOUND");
194
- }
195
- }
196
-
197
- export class ValidationError extends AppError {
198
- constructor(message: string, public errors: Record<string, string[]> = {}) {
199
- super(message, 400, "VALIDATION_ERROR");
200
- }
201
- }
202
-
203
- export class UnauthorizedError extends AppError {
204
- constructor(message = "Authentication required") {
205
- super(message, 401, "UNAUTHORIZED");
206
- }
207
- }
208
-
209
- // Express error middleware
210
- app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
211
- if (err instanceof AppError && err.isOperational) {
212
- res.status(err.statusCode).json({
213
- error: { code: err.code, message: err.message },
214
- });
215
- } else {
216
- // Programmer error — log and return generic message
217
- console.error("Unexpected error:", err);
218
- res.status(500).json({
219
- error: { code: "INTERNAL_ERROR", message: "Something went wrong" },
220
- });
221
- }
222
- });
223
- ```
224
-
225
- ---
226
-
227
- ## Async Patterns
228
-
229
- ### Parallel vs Sequential
230
-
231
- ```typescript
232
- // ❌ SEQUENTIAL: Each await blocks the next
233
- const users = await getUsers(); // 200ms
234
- const posts = await getPosts(); // 200ms
235
- const stats = await getStats(); // 200ms
236
- // Total: 600ms
237
-
238
- // PARALLEL: All start simultaneously
239
- const [users, posts, stats] = await Promise.all([
240
- getUsers(), // 200ms
241
- getPosts(), // 200ms (concurrent)
242
- getStats(), // 200ms (concurrent)
243
- ]);
244
- // Total: ~200ms
245
-
246
- // Promise.allSettled — when some can fail
247
- const results = await Promise.allSettled([
248
- fetchCriticalData(),
249
- fetchOptionalData(),
250
- fetchAnalytics(),
251
- ]);
252
-
253
- for (const result of results) {
254
- if (result.status === "fulfilled") {
255
- process(result.value);
256
- } else {
257
- console.error("Failed:", result.reason);
258
- }
259
- }
260
- ```
261
-
262
- ### Retry Pattern
263
-
264
- ```typescript
265
- async function withRetry<T>(
266
- fn: () => Promise<T>,
267
- options: { maxRetries?: number; baseDelay?: number; maxDelay?: number } = {},
268
- ): Promise<T> {
269
- const { maxRetries = 3, baseDelay = 1000, maxDelay = 10000 } = options;
270
-
271
- for (let attempt = 0; attempt <= maxRetries; attempt++) {
272
- try {
273
- return await fn();
274
- } catch (error) {
275
- if (attempt === maxRetries) throw error;
276
-
277
- const delay = Math.min(baseDelay * 2 ** attempt, maxDelay);
278
- const jitter = delay * (0.5 + Math.random() * 0.5);
279
- console.warn(`Attempt ${attempt + 1} failed, retrying in ${jitter}ms`);
280
- await new Promise((resolve) => setTimeout(resolve, jitter));
281
- }
282
- }
283
- throw new Error("Unreachable");
284
- }
285
-
286
- // Usage:
287
- const data = await withRetry(() => fetch("https://api.flaky.com/data"), {
288
- maxRetries: 3,
289
- baseDelay: 500,
290
- });
291
- ```
292
-
293
- ### AbortController (Timeouts & Cancellation)
294
-
295
- ```typescript
296
- async function fetchWithTimeout(url: string, timeoutMs = 5000): Promise<Response> {
297
- const controller = new AbortController();
298
- const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
299
-
300
- try {
301
- const response = await fetch(url, { signal: controller.signal });
302
- return response;
303
- } catch (error) {
304
- if (error instanceof DOMException && error.name === "AbortError") {
305
- throw new Error(`Request to ${url} timed out after ${timeoutMs}ms`);
306
- }
307
- throw error;
308
- } finally {
309
- clearTimeout(timeoutId);
310
- }
311
- }
312
- ```
313
-
314
- ---
315
-
316
- ## Streaming
317
-
318
- ```typescript
319
- import { Readable, Transform, pipeline } from "node:stream/promises";
320
- import { createReadStream, createWriteStream } from "node:fs";
321
- import { createGzip } from "node:zlib";
322
-
323
- // Stream large file processing (no memory issues)
324
- async function processLargeCSV(inputPath: string, outputPath: string) {
325
- const transform = new Transform({
326
- transform(chunk, encoding, callback) {
327
- const processed = chunk.toString().toUpperCase();
328
- callback(null, processed);
329
- },
330
- });
331
-
332
- await pipeline(
333
- createReadStream(inputPath),
334
- transform,
335
- createGzip(),
336
- createWriteStream(outputPath),
337
- );
338
- }
339
-
340
- // Streaming HTTP response
341
- app.get("/export", async (req, res) => {
342
- res.setHeader("Content-Type", "text/csv");
343
- res.setHeader("Content-Disposition", "attachment; filename=export.csv");
344
-
345
- const cursor = db.collection("users").find().stream();
346
- cursor.on("data", (user) => {
347
- res.write(`${user.id},${user.name},${user.email}\n`);
348
- });
349
- cursor.on("end", () => res.end());
350
- cursor.on("error", (err) => {
351
- console.error(err);
352
- res.status(500).end();
353
- });
354
- });
355
-
356
- // ❌ HALLUCINATION TRAP: Use stream/promises (not callbacks)
357
- // ❌ const { pipeline } = require("stream"); ← callback-based
358
- // ✅ import { pipeline } from "node:stream/promises"; ← async/await
359
- ```
360
-
361
- ---
362
-
363
- ## Environment & Config
364
-
365
- ```typescript
366
- // config.ts centralized, validated configuration
367
- import { z } from "zod";
368
-
369
- const envSchema = z.object({
370
- NODE_ENV: z.enum(["development", "production", "test"]).default("development"),
371
- PORT: z.coerce.number().default(3000),
372
- DATABASE_URL: z.string().url(),
373
- REDIS_URL: z.string().url().optional(),
374
- JWT_SECRET: z.string().min(32),
375
- CORS_ORIGIN: z.string().default("http://localhost:5173"),
376
- LOG_LEVEL: z.enum(["debug", "info", "warn", "error"]).default("info"),
377
- });
378
-
379
- export const config = envSchema.parse(process.env);
380
-
381
- // ❌ HALLUCINATION TRAP: Validate env vars at startup — fail FAST
382
- // ❌ process.env.DATABASE_URL!crashes at runtime, not startup
383
- // ✅ Validate with Zod on app init — crash immediately with clear error
384
-
385
- // ❌ HALLUCINATION TRAP: Never hardcode secrets
386
- // ❌ const JWT_SECRET = "my-secret-key"; ← in source code
387
- // ✅ const JWT_SECRET = process.env.JWT_SECRET; ← from environment
388
- ```
389
-
390
- ---
391
-
392
- ## Security Hardening
393
-
394
- ```typescript
395
- import helmet from "helmet";
396
- import rateLimit from "express-rate-limit";
397
-
398
- // Security headers
399
- app.use(helmet());
400
-
401
- // Rate limiting
402
- app.use("/api/", rateLimit({
403
- windowMs: 15 * 60 * 1000, // 15 minutes
404
- max: 100, // 100 requests per window
405
- standardHeaders: true,
406
- legacyHeaders: false,
407
- message: { error: "Too many requests, try again later" },
408
- }));
409
-
410
- // Auth rate limiting (stricter)
411
- app.use("/api/auth/", rateLimit({
412
- windowMs: 15 * 60 * 1000,
413
- max: 5, // only 5 login attempts per 15 min
414
- }));
415
-
416
- // Input validation (ALWAYS validate)
417
- app.post("/api/users", async (req, res, next) => {
418
- try {
419
- const data = CreateUserSchema.parse(req.body); // Zod validates
420
- const user = await createUser(data);
421
- res.status(201).json(user);
422
- } catch (error) {
423
- next(error);
424
- }
425
- });
426
-
427
- // SQL injection prevention (covered by parameterized queries)
428
- // db.query(`SELECT * FROM users WHERE id = ${req.params.id}`);
429
- // ✅ db.query("SELECT * FROM users WHERE id = $1", [req.params.id]);
430
-
431
- // Path traversal prevention
432
- import { resolve, normalize } from "node:path";
433
-
434
- function safePath(userInput: string, baseDir: string): string {
435
- const resolved = resolve(baseDir, normalize(userInput));
436
- if (!resolved.startsWith(baseDir)) {
437
- throw new Error("Path traversal detected");
438
- }
439
- return resolved;
440
- }
441
- ```
442
-
443
- ---
444
-
445
- ## Process Management
446
-
447
- ### Graceful Shutdown
448
-
449
- ```typescript
450
- async function gracefulShutdown(signal: string) {
451
- console.log(`\n${signal} received — shutting down gracefully`);
452
-
453
- // Stop accepting new connections
454
- server.close();
455
-
456
- // Close database connections
457
- await db.end();
458
-
459
- // Close Redis
460
- await redis.quit();
461
-
462
- // Allow in-flight requests 10s to complete
463
- setTimeout(() => {
464
- console.error("Forceful shutdown after timeout");
465
- process.exit(1);
466
- }, 10000);
467
-
468
- process.exit(0);
469
- }
470
-
471
- process.on("SIGTERM", () => gracefulShutdown("SIGTERM"));
472
- process.on("SIGINT", () => gracefulShutdown("SIGINT"));
473
- ```
474
-
475
- ### Worker Threads (CPU-Bound)
476
-
477
- ```typescript
478
- import { Worker, isMainThread, parentPort, workerData } from "node:worker_threads";
479
-
480
- if (isMainThread) {
481
- // Main thread — offload CPU work
482
- function runWorker(data: unknown): Promise<unknown> {
483
- return new Promise((resolve, reject) => {
484
- const worker = new Worker(new URL(import.meta.url), { workerData: data });
485
- worker.on("message", resolve);
486
- worker.on("error", reject);
487
- });
488
- }
489
-
490
- const result = await runWorker({ input: largeDataSet });
491
- } else {
492
- // Worker thread — CPU-intensive work
493
- const result = heavyComputation(workerData.input);
494
- parentPort?.postMessage(result);
495
- }
496
-
497
- // ❌ HALLUCINATION TRAP: Worker threads are for CPU-bound tasks
498
- // For I/O-bound tasks (network, file), use async/await — NOT workers
499
- // Workers have overhead (serialization, memory) — don't overuse
500
- ```
501
-
502
- ---
503
-
504
- ## Output Format
505
-
506
- ```
507
- ━━━ Node.js Report ━━━━━━━━━━━━━━━━━━━━━━━━
508
- Skill: Node.js Best Practices
509
- Node Ver: 22+
510
- Scope: [N files · N endpoints]
511
- ─────────────────────────────────────────────────
512
- ✅ Passed: [checks that passed, or "All clean"]
513
- ⚠️ Warnings: [non-blocking issues, or "None"]
514
- ❌ Blocked: [blocking issues requiring fix, or "None"]
515
- ─────────────────────────────────────────────────
516
- VBC status: PENDING → VERIFIED
517
- Evidence: [test output / server start / build success]
518
- ```
519
-
520
- ---
521
-
522
- ## 🤖 LLM-Specific Traps
523
-
524
- 1. **`require()` in ESM:** Never use `require()` in `"type": "module"` projects. Use `import`.
525
- 2. **Missing `node:` Prefix:** Always use `node:fs`, `node:path`, `node:http`, etc. Bare imports are ambiguous.
526
- 3. **Callback-Based APIs:** Use `node:fs/promises`, `node:stream/promises`. Callback APIs are legacy.
527
- 4. **Continuing After `uncaughtException`:** Process MUST exit after uncaughtException. State is corrupted.
528
- 5. **`process.env` Without Validation:** Environment variables are `string | undefined`. Always validate at startup with Zod.
529
- 6. **Hardcoded Secrets:** JWT secrets, API keys, and DB URLs must come from environment, never source code.
530
- 7. **`express()` Without `helmet()`:** Every Express app needs security headers. `helmet()` is non-negotiable.
531
- 8. **SQL String Interpolation:** Never use template literals for SQL. Use parameterized queries.
532
- 9. **Worker Threads for I/O:** Workers are for CPU-bound work. I/O-bound work uses async/await natively.
533
- 10. **Missing Graceful Shutdown:** Servers MUST handle SIGTERM/SIGINT for clean container/PaaS shutdown.
534
-
535
- ---
536
-
537
- ## 🏛️ Tribunal Integration
538
-
539
- **Slash command: `/tribunal-backend`**
540
-
541
- ### ✅ Pre-Flight Self-Audit
542
-
543
- ```
544
- ✅ Did I use ESM imports with node: prefix?
545
- ✅ Did I validate all environment variables at startup?
546
- ✅ Are secrets in environment variables (not hardcoded)?
547
- ✅ Did I handle unhandledRejection and uncaughtException?
548
- ✅ Did I implement graceful shutdown (SIGTERM/SIGINT)?
549
- ✅ Did I use parameterized queries (not string interpolation)?
550
- ✅ Did I add rate limiting and security headers?
551
- ✅ Did I validate all request input with Zod?
552
- ✅ Are async errors properly caught and propagated?
553
- ✅ Did I use streams for large data (not loading all into memory)?
554
- ```
555
-
556
- ### 🛑 VBC Protocol
557
-
558
- - ❌ **Forbidden:** Assuming a server "works" because it starts without errors.
559
- - ✅ **Required:** Provide test output, health check response, or build success evidence.
1
+ ---
2
+ name: nodejs-best-practices
3
+ description: Node.js 22+ production mastery. ES Modules, async patterns, Express/Fastify/Hono, middleware architecture, error handling, streaming, worker threads, environment config, security hardening, process management, and deployment patterns. Use when building Node.js servers, APIs, CLI tools, or any server-side JavaScript.
4
+ allowed-tools: Read, Write, Edit, Glob, Grep
5
+ version: 2.0.0
6
+ last-updated: 2026-04-01
7
+ applies-to-model: gemini-2.5-pro, claude-3-7-sonnet
8
+ ---
9
+
10
+ # Node.js Best Practices — Node 22+ Production Mastery
11
+
12
+ ---
13
+
14
+ ## ES Modules (Mandatory)
15
+
16
+ ```json
17
+ // package.json — ALWAYS set type to module
18
+ {
19
+ "type": "module",
20
+ "engines": { "node": ">=22" }
21
+ }
22
+ ```
23
+
24
+ ```typescript
25
+ // ✅ ESM imports (modern Node.js)
26
+ import { readFile, writeFile } from "node:fs/promises";
27
+ import { join, resolve } from "node:path";
28
+ import { createServer } from "node:http";
29
+ import { EventEmitter } from "node:events";
30
+
31
+ // HALLUCINATION TRAP: Use node: protocol prefix for built-in modules
32
+ // import fs from "fs"; ← ambiguous (could be npm package)
33
+ // import fs from "node:fs"; ← explicitly a Node.js built-in
34
+
35
+ // ❌ HALLUCINATION TRAP: Do NOT use require() in ESM projects
36
+ // ❌ const fs = require("fs"); CommonJS (legacy)
37
+ // ✅ import fs from "node:fs/promises"; ← ESM
38
+
39
+ // Dynamic imports (for conditional loading)
40
+ const module = await import("./heavy-module.js");
41
+ ```
42
+
43
+ ---
44
+
45
+ ## Framework Selection
46
+
47
+ ```
48
+ ┌────────────────────────────────────────────────────────────┐
49
+ │ When to Use What │
50
+ ├────────────────────────────────────────────────────────────┤
51
+ │ Express │ Legacy projects, extensive middleware ecosystem│
52
+ │ Fastify │ Performance-critical APIs, schema validation │
53
+ Hono │ Edge/serverless, multi-runtime (Node/Deno/Bun)
54
+ │ tRPC │ Full-stack TypeScript (Next.js + React Query) │
55
+ Raw http Learning, minimal proxies, health checks
56
+ └────────────────────────────────────────────────────────────┘
57
+ ```
58
+
59
+ ### Fastify (Recommended)
60
+
61
+ ```typescript
62
+ import Fastify from "fastify";
63
+ import { z } from "zod";
64
+
65
+ const app = Fastify({
66
+ logger: {
67
+ level: process.env.LOG_LEVEL ?? "info",
68
+ transport: process.env.NODE_ENV === "development"
69
+ ? { target: "pino-pretty" }
70
+ : undefined,
71
+ },
72
+ });
73
+
74
+ // Schema validation with Zod → Fastify schema
75
+ const CreateUserSchema = z.object({
76
+ name: z.string().min(2).max(100),
77
+ email: z.string().email(),
78
+ role: z.enum(["admin", "user"]).default("user"),
79
+ });
80
+
81
+ type CreateUserBody = z.infer<typeof CreateUserSchema>;
82
+
83
+ app.post<{ Body: CreateUserBody }>("/users", {
84
+ schema: {
85
+ body: {
86
+ type: "object",
87
+ required: ["name", "email"],
88
+ properties: {
89
+ name: { type: "string", minLength: 2 },
90
+ email: { type: "string", format: "email" },
91
+ role: { type: "string", enum: ["admin", "user"] },
92
+ },
93
+ },
94
+ },
95
+ }, async (request, reply) => {
96
+ const validated = CreateUserSchema.parse(request.body);
97
+ const user = await createUser(validated);
98
+ return reply.status(201).send(user);
99
+ });
100
+
101
+ // Graceful shutdown
102
+ const start = async () => {
103
+ try {
104
+ await app.listen({ port: 3000, host: "0.0.0.0" });
105
+ } catch (err) {
106
+ app.log.error(err);
107
+ process.exit(1);
108
+ }
109
+ };
110
+
111
+ start();
112
+ ```
113
+
114
+ ### Hono (Edge-First)
115
+
116
+ ```typescript
117
+ import { Hono } from "hono";
118
+ import { cors } from "hono/cors";
119
+ import { logger } from "hono/logger";
120
+ import { zValidator } from "@hono/zod-validator";
121
+ import { z } from "zod";
122
+
123
+ const app = new Hono();
124
+
125
+ app.use("*", logger());
126
+ app.use("*", cors({ origin: "https://myapp.com" }));
127
+
128
+ const createUserSchema = z.object({
129
+ name: z.string().min(2),
130
+ email: z.string().email(),
131
+ });
132
+
133
+ app.post("/users", zValidator("json", createUserSchema), async (c) => {
134
+ const body = c.req.valid("json");
135
+ const user = await createUser(body);
136
+ return c.json(user, 201);
137
+ });
138
+
139
+ app.get("/health", (c) => c.json({ status: "ok" }));
140
+
141
+ export default app; // works in Node, Deno, Bun, Cloudflare Workers
142
+ ```
143
+
144
+ ---
145
+
146
+ ## Error Handling
147
+
148
+ ### Global Error Handlers
149
+
150
+ ```typescript
151
+ // ✅ MANDATORY: Handle unhandled rejections and exceptions
152
+ process.on("unhandledRejection", (reason, promise) => {
153
+ console.error("Unhandled Rejection at:", promise, "reason:", reason);
154
+ // Log to error tracking service (Sentry, etc.)
155
+ // Gracefully shutdown
156
+ process.exit(1);
157
+ });
158
+
159
+ process.on("uncaughtException", (error) => {
160
+ console.error("Uncaught Exception:", error);
161
+ // Log to error tracking service
162
+ process.exit(1); // MUST exit — state is corrupted
163
+ });
164
+
165
+ // HALLUCINATION TRAP: After uncaughtException, the process MUST exit
166
+ // The process is in an undefined state — continuing is dangerous
167
+ // ❌ process.on("uncaughtException", (err) => { console.log(err); }); // continues running
168
+ // ✅ process.on("uncaughtException", (err) => { log(err); process.exit(1); });
169
+ ```
170
+
171
+ ### Application Error Classes
172
+
173
+ ```typescript
174
+ export class AppError extends Error {
175
+ constructor(
176
+ message: string,
177
+ public statusCode: number = 500,
178
+ public code: string = "INTERNAL_ERROR",
179
+ public isOperational: boolean = true,
180
+ ) {
181
+ super(message);
182
+ this.name = "AppError";
183
+ Error.captureStackTrace(this, this.constructor);
184
+ }
185
+ }
186
+
187
+ export class NotFoundError extends AppError {
188
+ constructor(resource: string, id: string) {
189
+ super(`${resource} '${id}' not found`, 404, "NOT_FOUND");
190
+ }
191
+ }
192
+
193
+ export class ValidationError extends AppError {
194
+ constructor(message: string, public errors: Record<string, string[]> = {}) {
195
+ super(message, 400, "VALIDATION_ERROR");
196
+ }
197
+ }
198
+
199
+ export class UnauthorizedError extends AppError {
200
+ constructor(message = "Authentication required") {
201
+ super(message, 401, "UNAUTHORIZED");
202
+ }
203
+ }
204
+
205
+ // Express error middleware
206
+ app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
207
+ if (err instanceof AppError && err.isOperational) {
208
+ res.status(err.statusCode).json({
209
+ error: { code: err.code, message: err.message },
210
+ });
211
+ } else {
212
+ // Programmer error — log and return generic message
213
+ console.error("Unexpected error:", err);
214
+ res.status(500).json({
215
+ error: { code: "INTERNAL_ERROR", message: "Something went wrong" },
216
+ });
217
+ }
218
+ });
219
+ ```
220
+
221
+ ---
222
+
223
+ ## Async Patterns
224
+
225
+ ### Parallel vs Sequential
226
+
227
+ ```typescript
228
+ // ❌ SEQUENTIAL: Each await blocks the next
229
+ const users = await getUsers(); // 200ms
230
+ const posts = await getPosts(); // 200ms
231
+ const stats = await getStats(); // 200ms
232
+ // Total: 600ms
233
+
234
+ // PARALLEL: All start simultaneously
235
+ const [users, posts, stats] = await Promise.all([
236
+ getUsers(), // 200ms
237
+ getPosts(), // 200ms (concurrent)
238
+ getStats(), // 200ms (concurrent)
239
+ ]);
240
+ // Total: ~200ms
241
+
242
+ // Promise.allSettled — when some can fail
243
+ const results = await Promise.allSettled([
244
+ fetchCriticalData(),
245
+ fetchOptionalData(),
246
+ fetchAnalytics(),
247
+ ]);
248
+
249
+ for (const result of results) {
250
+ if (result.status === "fulfilled") {
251
+ process(result.value);
252
+ } else {
253
+ console.error("Failed:", result.reason);
254
+ }
255
+ }
256
+ ```
257
+
258
+ ### Retry Pattern
259
+
260
+ ```typescript
261
+ async function withRetry<T>(
262
+ fn: () => Promise<T>,
263
+ options: { maxRetries?: number; baseDelay?: number; maxDelay?: number } = {},
264
+ ): Promise<T> {
265
+ const { maxRetries = 3, baseDelay = 1000, maxDelay = 10000 } = options;
266
+
267
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
268
+ try {
269
+ return await fn();
270
+ } catch (error) {
271
+ if (attempt === maxRetries) throw error;
272
+
273
+ const delay = Math.min(baseDelay * 2 ** attempt, maxDelay);
274
+ const jitter = delay * (0.5 + Math.random() * 0.5);
275
+ console.warn(`Attempt ${attempt + 1} failed, retrying in ${jitter}ms`);
276
+ await new Promise((resolve) => setTimeout(resolve, jitter));
277
+ }
278
+ }
279
+ throw new Error("Unreachable");
280
+ }
281
+
282
+ // Usage:
283
+ const data = await withRetry(() => fetch("https://api.flaky.com/data"), {
284
+ maxRetries: 3,
285
+ baseDelay: 500,
286
+ });
287
+ ```
288
+
289
+ ### AbortController (Timeouts & Cancellation)
290
+
291
+ ```typescript
292
+ async function fetchWithTimeout(url: string, timeoutMs = 5000): Promise<Response> {
293
+ const controller = new AbortController();
294
+ const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
295
+
296
+ try {
297
+ const response = await fetch(url, { signal: controller.signal });
298
+ return response;
299
+ } catch (error) {
300
+ if (error instanceof DOMException && error.name === "AbortError") {
301
+ throw new Error(`Request to ${url} timed out after ${timeoutMs}ms`);
302
+ }
303
+ throw error;
304
+ } finally {
305
+ clearTimeout(timeoutId);
306
+ }
307
+ }
308
+ ```
309
+
310
+ ---
311
+
312
+ ## Streaming
313
+
314
+ ```typescript
315
+ import { Readable, Transform, pipeline } from "node:stream/promises";
316
+ import { createReadStream, createWriteStream } from "node:fs";
317
+ import { createGzip } from "node:zlib";
318
+
319
+ // Stream large file processing (no memory issues)
320
+ async function processLargeCSV(inputPath: string, outputPath: string) {
321
+ const transform = new Transform({
322
+ transform(chunk, encoding, callback) {
323
+ const processed = chunk.toString().toUpperCase();
324
+ callback(null, processed);
325
+ },
326
+ });
327
+
328
+ await pipeline(
329
+ createReadStream(inputPath),
330
+ transform,
331
+ createGzip(),
332
+ createWriteStream(outputPath),
333
+ );
334
+ }
335
+
336
+ // Streaming HTTP response
337
+ app.get("/export", async (req, res) => {
338
+ res.setHeader("Content-Type", "text/csv");
339
+ res.setHeader("Content-Disposition", "attachment; filename=export.csv");
340
+
341
+ const cursor = db.collection("users").find().stream();
342
+ cursor.on("data", (user) => {
343
+ res.write(`${user.id},${user.name},${user.email}\n`);
344
+ });
345
+ cursor.on("end", () => res.end());
346
+ cursor.on("error", (err) => {
347
+ console.error(err);
348
+ res.status(500).end();
349
+ });
350
+ });
351
+
352
+ // ❌ HALLUCINATION TRAP: Use stream/promises (not callbacks)
353
+ // ❌ const { pipeline } = require("stream"); ← callback-based
354
+ // ✅ import { pipeline } from "node:stream/promises"; ← async/await
355
+ ```
356
+
357
+ ---
358
+
359
+ ## Environment & Config
360
+
361
+ ```typescript
362
+ // config.ts — centralized, validated configuration
363
+ import { z } from "zod";
364
+
365
+ const envSchema = z.object({
366
+ NODE_ENV: z.enum(["development", "production", "test"]).default("development"),
367
+ PORT: z.coerce.number().default(3000),
368
+ DATABASE_URL: z.string().url(),
369
+ REDIS_URL: z.string().url().optional(),
370
+ JWT_SECRET: z.string().min(32),
371
+ CORS_ORIGIN: z.string().default("http://localhost:5173"),
372
+ LOG_LEVEL: z.enum(["debug", "info", "warn", "error"]).default("info"),
373
+ });
374
+
375
+ export const config = envSchema.parse(process.env);
376
+
377
+ // ❌ HALLUCINATION TRAP: Validate env vars at startup — fail FAST
378
+ // ❌ process.env.DATABASE_URL! ← crashes at runtime, not startup
379
+ // Validate with Zod on app init — crash immediately with clear error
380
+
381
+ // ❌ HALLUCINATION TRAP: Never hardcode secrets
382
+ // ❌ const JWT_SECRET = "my-secret-key";in source code
383
+ // ✅ const JWT_SECRET = process.env.JWT_SECRET; ← from environment
384
+ ```
385
+
386
+ ---
387
+
388
+ ## Security Hardening
389
+
390
+ ```typescript
391
+ import helmet from "helmet";
392
+ import rateLimit from "express-rate-limit";
393
+
394
+ // Security headers
395
+ app.use(helmet());
396
+
397
+ // Rate limiting
398
+ app.use("/api/", rateLimit({
399
+ windowMs: 15 * 60 * 1000, // 15 minutes
400
+ max: 100, // 100 requests per window
401
+ standardHeaders: true,
402
+ legacyHeaders: false,
403
+ message: { error: "Too many requests, try again later" },
404
+ }));
405
+
406
+ // Auth rate limiting (stricter)
407
+ app.use("/api/auth/", rateLimit({
408
+ windowMs: 15 * 60 * 1000,
409
+ max: 5, // only 5 login attempts per 15 min
410
+ }));
411
+
412
+ // Input validation (ALWAYS validate)
413
+ app.post("/api/users", async (req, res, next) => {
414
+ try {
415
+ const data = CreateUserSchema.parse(req.body); // Zod validates
416
+ const user = await createUser(data);
417
+ res.status(201).json(user);
418
+ } catch (error) {
419
+ next(error);
420
+ }
421
+ });
422
+
423
+ // SQL injection prevention (covered by parameterized queries)
424
+ // ❌ db.query(`SELECT * FROM users WHERE id = ${req.params.id}`);
425
+ // ✅ db.query("SELECT * FROM users WHERE id = $1", [req.params.id]);
426
+
427
+ // Path traversal prevention
428
+ import { resolve, normalize } from "node:path";
429
+
430
+ function safePath(userInput: string, baseDir: string): string {
431
+ const resolved = resolve(baseDir, normalize(userInput));
432
+ if (!resolved.startsWith(baseDir)) {
433
+ throw new Error("Path traversal detected");
434
+ }
435
+ return resolved;
436
+ }
437
+ ```
438
+
439
+ ---
440
+
441
+ ## Process Management
442
+
443
+ ### Graceful Shutdown
444
+
445
+ ```typescript
446
+ async function gracefulShutdown(signal: string) {
447
+ console.log(`\n${signal} received — shutting down gracefully`);
448
+
449
+ // Stop accepting new connections
450
+ server.close();
451
+
452
+ // Close database connections
453
+ await db.end();
454
+
455
+ // Close Redis
456
+ await redis.quit();
457
+
458
+ // Allow in-flight requests 10s to complete
459
+ setTimeout(() => {
460
+ console.error("Forceful shutdown after timeout");
461
+ process.exit(1);
462
+ }, 10000);
463
+
464
+ process.exit(0);
465
+ }
466
+
467
+ process.on("SIGTERM", () => gracefulShutdown("SIGTERM"));
468
+ process.on("SIGINT", () => gracefulShutdown("SIGINT"));
469
+ ```
470
+
471
+ ### Worker Threads (CPU-Bound)
472
+
473
+ ```typescript
474
+ import { Worker, isMainThread, parentPort, workerData } from "node:worker_threads";
475
+
476
+ if (isMainThread) {
477
+ // Main thread — offload CPU work
478
+ function runWorker(data: unknown): Promise<unknown> {
479
+ return new Promise((resolve, reject) => {
480
+ const worker = new Worker(new URL(import.meta.url), { workerData: data });
481
+ worker.on("message", resolve);
482
+ worker.on("error", reject);
483
+ });
484
+ }
485
+
486
+ const result = await runWorker({ input: largeDataSet });
487
+ } else {
488
+ // Worker thread — CPU-intensive work
489
+ const result = heavyComputation(workerData.input);
490
+ parentPort?.postMessage(result);
491
+ }
492
+
493
+ // HALLUCINATION TRAP: Worker threads are for CPU-bound tasks
494
+ // For I/O-bound tasks (network, file), use async/await — NOT workers
495
+ // Workers have overhead (serialization, memory) — don't overuse
496
+ ```
497
+
498
+ ---