tribunal-kit 1.0.0 → 2.4.2
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.
- package/.agent/.shared/ui-ux-pro-max/README.md +3 -3
- package/.agent/ARCHITECTURE.md +205 -10
- package/.agent/GEMINI.md +37 -7
- package/.agent/agents/accessibility-reviewer.md +134 -0
- package/.agent/agents/ai-code-reviewer.md +129 -0
- package/.agent/agents/frontend-specialist.md +3 -0
- package/.agent/agents/game-developer.md +21 -21
- package/.agent/agents/logic-reviewer.md +12 -0
- package/.agent/agents/mobile-reviewer.md +79 -0
- package/.agent/agents/orchestrator.md +56 -26
- package/.agent/agents/performance-reviewer.md +36 -0
- package/.agent/agents/supervisor-agent.md +156 -0
- package/.agent/agents/swarm-worker-contracts.md +166 -0
- package/.agent/agents/swarm-worker-registry.md +92 -0
- package/.agent/rules/GEMINI.md +134 -5
- package/.agent/scripts/bundle_analyzer.py +259 -0
- package/.agent/scripts/dependency_analyzer.py +247 -0
- package/.agent/scripts/lint_runner.py +188 -0
- package/.agent/scripts/patch_skills_meta.py +177 -0
- package/.agent/scripts/patch_skills_output.py +285 -0
- package/.agent/scripts/schema_validator.py +279 -0
- package/.agent/scripts/security_scan.py +224 -0
- package/.agent/scripts/session_manager.py +144 -3
- package/.agent/scripts/skill_integrator.py +234 -0
- package/.agent/scripts/strengthen_skills.py +220 -0
- package/.agent/scripts/swarm_dispatcher.py +317 -0
- package/.agent/scripts/test_runner.py +192 -0
- package/.agent/scripts/test_swarm_dispatcher.py +163 -0
- package/.agent/skills/agent-organizer/SKILL.md +132 -0
- package/.agent/skills/agentic-patterns/SKILL.md +335 -0
- package/.agent/skills/api-patterns/SKILL.md +226 -50
- package/.agent/skills/app-builder/SKILL.md +215 -52
- package/.agent/skills/architecture/SKILL.md +176 -31
- package/.agent/skills/bash-linux/SKILL.md +150 -134
- package/.agent/skills/behavioral-modes/SKILL.md +152 -160
- package/.agent/skills/brainstorming/SKILL.md +148 -101
- package/.agent/skills/brainstorming/dynamic-questioning.md +10 -0
- package/.agent/skills/clean-code/SKILL.md +139 -134
- package/.agent/skills/code-review-checklist/SKILL.md +177 -80
- package/.agent/skills/config-validator/SKILL.md +165 -0
- package/.agent/skills/csharp-developer/SKILL.md +107 -0
- package/.agent/skills/database-design/SKILL.md +252 -29
- package/.agent/skills/deployment-procedures/SKILL.md +122 -175
- package/.agent/skills/devops-engineer/SKILL.md +134 -0
- package/.agent/skills/devops-incident-responder/SKILL.md +98 -0
- package/.agent/skills/documentation-templates/SKILL.md +175 -121
- package/.agent/skills/dotnet-core-expert/SKILL.md +103 -0
- package/.agent/skills/edge-computing/SKILL.md +213 -0
- package/.agent/skills/frontend-design/SKILL.md +76 -0
- package/.agent/skills/frontend-design/color-system.md +18 -0
- package/.agent/skills/frontend-design/typography-system.md +18 -0
- package/.agent/skills/game-development/SKILL.md +69 -0
- package/.agent/skills/geo-fundamentals/SKILL.md +158 -99
- package/.agent/skills/github-operations/SKILL.md +354 -0
- package/.agent/skills/i18n-localization/SKILL.md +158 -96
- package/.agent/skills/intelligent-routing/SKILL.md +89 -285
- package/.agent/skills/intelligent-routing/router-manifest.md +65 -0
- package/.agent/skills/lint-and-validate/SKILL.md +229 -27
- package/.agent/skills/llm-engineering/SKILL.md +258 -0
- package/.agent/skills/local-first/SKILL.md +203 -0
- package/.agent/skills/mcp-builder/SKILL.md +159 -111
- package/.agent/skills/mobile-design/SKILL.md +102 -282
- package/.agent/skills/nextjs-react-expert/SKILL.md +143 -227
- package/.agent/skills/nodejs-best-practices/SKILL.md +201 -254
- package/.agent/skills/observability/SKILL.md +285 -0
- package/.agent/skills/parallel-agents/SKILL.md +124 -118
- package/.agent/skills/performance-profiling/SKILL.md +143 -89
- package/.agent/skills/plan-writing/SKILL.md +133 -97
- package/.agent/skills/platform-engineer/SKILL.md +135 -0
- package/.agent/skills/powershell-windows/SKILL.md +167 -104
- package/.agent/skills/python-patterns/SKILL.md +149 -361
- package/.agent/skills/python-pro/SKILL.md +114 -0
- package/.agent/skills/react-specialist/SKILL.md +107 -0
- package/.agent/skills/readme-builder/SKILL.md +270 -0
- package/.agent/skills/realtime-patterns/SKILL.md +296 -0
- package/.agent/skills/red-team-tactics/SKILL.md +136 -134
- package/.agent/skills/rust-pro/SKILL.md +237 -173
- package/.agent/skills/seo-fundamentals/SKILL.md +134 -82
- package/.agent/skills/server-management/SKILL.md +155 -104
- package/.agent/skills/sql-pro/SKILL.md +104 -0
- package/.agent/skills/systematic-debugging/SKILL.md +156 -79
- package/.agent/skills/tailwind-patterns/SKILL.md +163 -205
- package/.agent/skills/tdd-workflow/SKILL.md +148 -88
- package/.agent/skills/test-result-analyzer/SKILL.md +299 -0
- package/.agent/skills/testing-patterns/SKILL.md +141 -114
- package/.agent/skills/trend-researcher/SKILL.md +228 -0
- package/.agent/skills/ui-ux-pro-max/SKILL.md +107 -0
- package/.agent/skills/ui-ux-researcher/SKILL.md +234 -0
- package/.agent/skills/vue-expert/SKILL.md +118 -0
- package/.agent/skills/vulnerability-scanner/SKILL.md +228 -188
- package/.agent/skills/web-design-guidelines/SKILL.md +148 -33
- package/.agent/skills/webapp-testing/SKILL.md +171 -122
- package/.agent/skills/whimsy-injector/SKILL.md +349 -0
- package/.agent/skills/workflow-optimizer/SKILL.md +219 -0
- package/.agent/workflows/api-tester.md +279 -0
- package/.agent/workflows/audit.md +168 -0
- package/.agent/workflows/brainstorm.md +65 -19
- package/.agent/workflows/changelog.md +144 -0
- package/.agent/workflows/create.md +67 -14
- package/.agent/workflows/debug.md +122 -30
- package/.agent/workflows/deploy.md +82 -31
- package/.agent/workflows/enhance.md +59 -27
- package/.agent/workflows/fix.md +143 -0
- package/.agent/workflows/generate.md +84 -20
- package/.agent/workflows/migrate.md +163 -0
- package/.agent/workflows/orchestrate.md +66 -17
- package/.agent/workflows/performance-benchmarker.md +305 -0
- package/.agent/workflows/plan.md +76 -33
- package/.agent/workflows/preview.md +73 -17
- package/.agent/workflows/refactor.md +153 -0
- package/.agent/workflows/review-ai.md +140 -0
- package/.agent/workflows/review.md +83 -16
- package/.agent/workflows/session.md +154 -0
- package/.agent/workflows/status.md +74 -18
- package/.agent/workflows/strengthen-skills.md +99 -0
- package/.agent/workflows/swarm.md +194 -0
- package/.agent/workflows/test.md +80 -31
- package/.agent/workflows/tribunal-backend.md +55 -13
- package/.agent/workflows/tribunal-database.md +62 -18
- package/.agent/workflows/tribunal-frontend.md +58 -12
- package/.agent/workflows/tribunal-full.md +70 -11
- package/.agent/workflows/tribunal-mobile.md +123 -0
- package/.agent/workflows/tribunal-performance.md +152 -0
- package/.agent/workflows/ui-ux-pro-max.md +100 -82
- package/README.md +117 -62
- package/bin/tribunal-kit.js +542 -288
- package/package.json +10 -6
|
@@ -2,332 +2,279 @@
|
|
|
2
2
|
name: nodejs-best-practices
|
|
3
3
|
description: Node.js development principles and decision-making. Framework selection, async patterns, security, and architecture. Teaches thinking, not copying.
|
|
4
4
|
allowed-tools: Read, Write, Edit, Glob, Grep
|
|
5
|
+
version: 1.0.0
|
|
6
|
+
last-updated: 2026-03-12
|
|
7
|
+
applies-to-model: gemini-2.5-pro, claude-3-7-sonnet
|
|
5
8
|
---
|
|
6
9
|
|
|
7
|
-
# Node.js
|
|
10
|
+
# Node.js Development Principles
|
|
8
11
|
|
|
9
|
-
>
|
|
10
|
-
>
|
|
12
|
+
> Node.js is not a problem — unpredictable async behavior is.
|
|
13
|
+
> Understand the event loop and half of Node.js "gotchas" disappear.
|
|
11
14
|
|
|
12
15
|
---
|
|
13
16
|
|
|
14
|
-
##
|
|
17
|
+
## Framework Selection
|
|
15
18
|
|
|
16
|
-
|
|
19
|
+
| Context | Recommended | Why |
|
|
20
|
+
|---|---|---|
|
|
21
|
+
| REST API, standard patterns | Express + TypeScript | Mature, flexible, most hiring knowledge |
|
|
22
|
+
| REST API, speed + TypeScript-first | Fastify | 2x Express throughput, built-in validation |
|
|
23
|
+
| Full-stack React | Next.js API routes | Colocated API and UI, serverless-friendly |
|
|
24
|
+
| REST + tRPC | Next.js + tRPC | Type-safe end-to-end with no code generation |
|
|
25
|
+
| RPC across services | gRPC | Binary protocol, contract-first |
|
|
26
|
+
| Edge function / Cloudflare Worker | Hono | Tiny, Web Platform API-native, zero cold start |
|
|
27
|
+
| Scripts / tooling / bun-native | Bun | Built-in bundler, test runner, near-Node compat |
|
|
17
28
|
|
|
18
|
-
|
|
19
|
-
- Choose framework/pattern based on CONTEXT
|
|
20
|
-
- Don't default to same solution every time
|
|
29
|
+
**Questions to ask before choosing:**
|
|
21
30
|
|
|
22
|
-
|
|
31
|
+
- Is this public-facing or internal?
|
|
32
|
+
- Do we control the deployment environment (server vs. serverless vs. edge)?
|
|
33
|
+
- Is the team already familiar with a framework?
|
|
34
|
+
- Does this need to compose with an existing TypeScript frontend?
|
|
23
35
|
|
|
24
|
-
|
|
36
|
+
---
|
|
25
37
|
|
|
26
|
-
|
|
38
|
+
## Modern Runtime Landscape (2025+)
|
|
27
39
|
|
|
28
|
-
|
|
29
|
-
What are you building?
|
|
30
|
-
│
|
|
31
|
-
├── Edge/Serverless (Cloudflare, Vercel)
|
|
32
|
-
│ └── Hono (zero-dependency, ultra-fast cold starts)
|
|
33
|
-
│
|
|
34
|
-
├── High Performance API
|
|
35
|
-
│ └── Fastify (2-3x faster than Express)
|
|
36
|
-
│
|
|
37
|
-
├── Enterprise/Team familiarity
|
|
38
|
-
│ └── NestJS (structured, DI, decorators)
|
|
39
|
-
│
|
|
40
|
-
├── Legacy/Stable/Maximum ecosystem
|
|
41
|
-
│ └── Express (mature, most middleware)
|
|
42
|
-
│
|
|
43
|
-
└── Full-stack with frontend
|
|
44
|
-
└── Next.js API Routes or tRPC
|
|
45
|
-
```
|
|
40
|
+
The Node.js monopoly is ending. Understand constraints before picking a runtime:
|
|
46
41
|
|
|
47
|
-
|
|
42
|
+
| Runtime | `fs` | `crypto` | `child_process` | `process.env` | Deploy Target |
|
|
43
|
+
|---|---|---|---|---|---|
|
|
44
|
+
| **Node.js** | ✅ | ✅ | ✅ | ✅ | Server, serverless |
|
|
45
|
+
| **Bun** | ✅ | ✅ | ✅ | ✅ | Server (Node-compatible) |
|
|
46
|
+
| **Deno** | ✅ (explicit perm) | ✅ | ✅ (explicit perm) | ✅ | Server, Deno Deploy |
|
|
47
|
+
| **Edge (Cloudflare Workers)** | ❌ | Web only | ❌ | via `env` binding | Edge (global) |
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
| **Ecosystem** | Growing | Good | Largest |
|
|
54
|
-
| **TypeScript** | Native | Excellent | Good |
|
|
55
|
-
| **Learning curve** | Low | Medium | Low |
|
|
49
|
+
```ts
|
|
50
|
+
// ❌ Portability anti-pattern — works in Node, breaks at edge
|
|
51
|
+
import { createHash } from 'crypto'; // Node crypto — not available at edge
|
|
52
|
+
import fs from 'fs'; // No filesystem at edge
|
|
56
53
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
4. Is there legacy code to maintain?
|
|
54
|
+
// ✅ Web Platform APIs — work everywhere (Node ≥18, Bun, Deno, Edge)
|
|
55
|
+
const hash = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(input));
|
|
56
|
+
const response = await fetch('https://api.example.com/data');
|
|
57
|
+
```
|
|
62
58
|
|
|
63
|
-
|
|
59
|
+
### When to Consider Bun
|
|
64
60
|
|
|
65
|
-
|
|
61
|
+
```ts
|
|
62
|
+
// Bun is Node-compatible but: starts faster, ships a bundler + test runner built-in
|
|
63
|
+
// Use Bun when: scripts, tooling, new greenfield backends, or test-heavy projects
|
|
66
64
|
|
|
67
|
-
|
|
65
|
+
// package.json — identical, works in both
|
|
66
|
+
// bun install → 10x faster than npm install
|
|
67
|
+
// bun test → built-in Vitest-compatible runner
|
|
68
|
+
// bun run → direct TypeScript execution, no transpile step
|
|
68
69
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
├── Run .ts files directly
|
|
72
|
-
├── No build step needed for simple projects
|
|
73
|
-
└── Consider for: scripts, simple APIs
|
|
70
|
+
// Gotcha: some native Node addons (e.g. bcrypt, canvas) need Bun alternatives
|
|
71
|
+
// Use: @node-rs/bcrypt instead of bcrypt (N-API native, works in both)
|
|
74
72
|
```
|
|
75
73
|
|
|
76
|
-
|
|
74
|
+
---
|
|
77
75
|
|
|
78
|
-
|
|
79
|
-
ESM (import/export)
|
|
80
|
-
├── Modern standard
|
|
81
|
-
├── Better tree-shaking
|
|
82
|
-
├── Async module loading
|
|
83
|
-
└── Use for: new projects
|
|
84
|
-
|
|
85
|
-
CommonJS (require)
|
|
86
|
-
├── Legacy compatibility
|
|
87
|
-
├── More npm packages support
|
|
88
|
-
└── Use for: existing codebases, some edge cases
|
|
89
|
-
```
|
|
76
|
+
## Async Patterns
|
|
90
77
|
|
|
91
|
-
###
|
|
78
|
+
### Always: Handle rejection
|
|
92
79
|
|
|
93
|
-
|
|
94
|
-
|---------|----------|
|
|
95
|
-
| **Node.js** | General purpose, largest ecosystem |
|
|
96
|
-
| **Bun** | Performance, built-in bundler |
|
|
97
|
-
| **Deno** | Security-first, built-in TypeScript |
|
|
80
|
+
Every Promise needs a rejection handler. Unhandled rejections crash Node.js processes in modern versions.
|
|
98
81
|
|
|
99
|
-
|
|
82
|
+
```ts
|
|
83
|
+
// ❌ Unhandled rejection
|
|
84
|
+
fetchData().then(process);
|
|
100
85
|
|
|
101
|
-
|
|
86
|
+
// ✅ Handled
|
|
87
|
+
fetchData().then(process).catch(handleError);
|
|
102
88
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
│ ├── Input validation at boundary
|
|
111
|
-
│ └── Calls service layer
|
|
112
|
-
│
|
|
113
|
-
├── Service Layer
|
|
114
|
-
│ ├── Business logic
|
|
115
|
-
│ ├── Framework-agnostic
|
|
116
|
-
│ └── Calls repository layer
|
|
117
|
-
│
|
|
118
|
-
└── Repository Layer
|
|
119
|
-
├── Data access only
|
|
120
|
-
├── Database queries
|
|
121
|
-
└── ORM interactions
|
|
89
|
+
// ✅ Or with async/await
|
|
90
|
+
try {
|
|
91
|
+
const data = await fetchData();
|
|
92
|
+
process(data);
|
|
93
|
+
} catch (err) {
|
|
94
|
+
handleError(err);
|
|
95
|
+
}
|
|
122
96
|
```
|
|
123
97
|
|
|
124
|
-
###
|
|
125
|
-
- **Testability**: Mock layers independently
|
|
126
|
-
- **Flexibility**: Swap database without touching business logic
|
|
127
|
-
- **Clarity**: Each layer has single responsibility
|
|
98
|
+
### Avoid: Blocking the event loop
|
|
128
99
|
|
|
129
|
-
|
|
130
|
-
- Small scripts → Single file OK
|
|
131
|
-
- Prototypes → Less structure acceptable
|
|
132
|
-
- Always ask: "Will this grow?"
|
|
100
|
+
The event loop is single-threaded. Anything synchronous that takes more than a few ms blocks all other requests.
|
|
133
101
|
|
|
134
|
-
|
|
102
|
+
```ts
|
|
103
|
+
// ❌ Blocks event loop for large files
|
|
104
|
+
const data = fs.readFileSync('huge.csv');
|
|
135
105
|
|
|
136
|
-
|
|
106
|
+
// ✅ Non-blocking
|
|
107
|
+
const data = await fs.promises.readFile('huge.csv');
|
|
137
108
|
|
|
138
|
-
|
|
109
|
+
// ❌ CPU-intensive work on main thread
|
|
110
|
+
const result = computeHuge(dataset);
|
|
139
111
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
├── Create custom error classes
|
|
143
|
-
├── Throw from any layer
|
|
144
|
-
├── Catch at top level (middleware)
|
|
145
|
-
└── Format consistent response
|
|
112
|
+
// ✅ Offload to worker thread
|
|
113
|
+
const { Worker } = require('worker_threads');
|
|
146
114
|
```
|
|
147
115
|
|
|
148
|
-
###
|
|
116
|
+
### Concurrency vs. Parallelism
|
|
149
117
|
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
└── NO internal details (security!)
|
|
156
|
-
|
|
157
|
-
Logs get:
|
|
158
|
-
├── Full stack trace
|
|
159
|
-
├── Request context
|
|
160
|
-
├── User ID (if applicable)
|
|
161
|
-
└── Timestamp
|
|
162
|
-
```
|
|
118
|
+
```ts
|
|
119
|
+
// Sequential — each awaits the previous (use when order matters or requests are dependent)
|
|
120
|
+
for (const id of ids) {
|
|
121
|
+
await processItem(id);
|
|
122
|
+
}
|
|
163
123
|
|
|
164
|
-
|
|
124
|
+
// Concurrent — all start immediately, await all completions (use for independent operations)
|
|
125
|
+
await Promise.all(ids.map(id => processItem(id)));
|
|
165
126
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
| Not found | 404 | Resource doesn't exist |
|
|
172
|
-
| Conflict | 409 | Duplicate or state conflict |
|
|
173
|
-
| Validation | 422 | Schema valid but business rules fail |
|
|
174
|
-
| Server error | 500 | Our fault, log everything |
|
|
127
|
+
// Concurrent with limit — avoid overwhelming downstream services
|
|
128
|
+
import pLimit from 'p-limit';
|
|
129
|
+
const limit = pLimit(5); // max 5 concurrent
|
|
130
|
+
await Promise.all(ids.map(id => limit(() => processItem(id))));
|
|
131
|
+
```
|
|
175
132
|
|
|
176
133
|
---
|
|
177
134
|
|
|
178
|
-
##
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
135
|
+
## Error Handling Architecture
|
|
136
|
+
|
|
137
|
+
Structure errors so they carry meaning, not just messages:
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
// Base application error
|
|
141
|
+
class AppError extends Error {
|
|
142
|
+
constructor(
|
|
143
|
+
message: string,
|
|
144
|
+
public code: string,
|
|
145
|
+
public statusCode: number,
|
|
146
|
+
public isOperational = true
|
|
147
|
+
) {
|
|
148
|
+
super(message);
|
|
149
|
+
this.name = this.constructor.name;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Domain-specific errors
|
|
154
|
+
class NotFoundError extends AppError {
|
|
155
|
+
constructor(resource: string, id: string) {
|
|
156
|
+
super(`${resource} ${id} not found`, 'NOT_FOUND', 404);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
class ValidationError extends AppError {
|
|
161
|
+
constructor(message: string) {
|
|
162
|
+
super(message, 'VALIDATION_FAILED', 400);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
203
165
|
```
|
|
204
166
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
167
|
+
**Global error handler:**
|
|
168
|
+
```ts
|
|
169
|
+
app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
|
|
170
|
+
if (err instanceof AppError && err.isOperational) {
|
|
171
|
+
return res.status(err.statusCode).json({
|
|
172
|
+
error: err.message,
|
|
173
|
+
code: err.code,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
// Non-operational errors — log fully, don't expose details
|
|
177
|
+
logger.error('Unexpected error', { err, url: req.url });
|
|
178
|
+
res.status(500).json({ error: 'Internal server error' });
|
|
179
|
+
});
|
|
180
|
+
```
|
|
210
181
|
|
|
211
182
|
---
|
|
212
183
|
|
|
213
|
-
##
|
|
184
|
+
## Security Baseline
|
|
214
185
|
|
|
215
|
-
|
|
186
|
+
```ts
|
|
187
|
+
import helmet from 'helmet';
|
|
188
|
+
import rateLimit from 'express-rate-limit';
|
|
216
189
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
├── API entry point (request body/params)
|
|
220
|
-
├── Before database operations
|
|
221
|
-
├── External data (API responses, file uploads)
|
|
222
|
-
└── Environment variables (startup)
|
|
223
|
-
```
|
|
190
|
+
// Security headers
|
|
191
|
+
app.use(helmet());
|
|
224
192
|
|
|
225
|
-
|
|
193
|
+
// Rate limiting — protect all routes
|
|
194
|
+
app.use(rateLimit({
|
|
195
|
+
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
196
|
+
max: 100, // requests per window
|
|
197
|
+
standardHeaders: true,
|
|
198
|
+
legacyHeaders: false,
|
|
199
|
+
}));
|
|
226
200
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
| **Zod** | TypeScript first, inference |
|
|
230
|
-
| **Valibot** | Smaller bundle (tree-shakeable) |
|
|
231
|
-
| **ArkType** | Performance critical |
|
|
232
|
-
| **Yup** | Existing React Form usage |
|
|
201
|
+
// Body size limit — prevent payload bombs
|
|
202
|
+
app.use(express.json({ limit: '10kb' }));
|
|
233
203
|
|
|
234
|
-
|
|
204
|
+
// Trust proxy correctly for rate limiting behind load balancer
|
|
205
|
+
app.set('trust proxy', 1);
|
|
206
|
+
```
|
|
235
207
|
|
|
236
|
-
|
|
237
|
-
-
|
|
238
|
-
-
|
|
208
|
+
**Never:**
|
|
209
|
+
- Use `eval()` or `new Function()` with user input
|
|
210
|
+
- Pass unvalidated user input to `exec()`, `spawn()`, or `child_process`
|
|
211
|
+
- Log full request bodies (may contain credentials or PII)
|
|
239
212
|
|
|
240
213
|
---
|
|
241
214
|
|
|
242
|
-
##
|
|
243
|
-
|
|
244
|
-
### Security Checklist (Not Code)
|
|
245
|
-
|
|
246
|
-
- [ ] **Input validation**: All inputs validated
|
|
247
|
-
- [ ] **Parameterized queries**: No string concatenation for SQL
|
|
248
|
-
- [ ] **Password hashing**: bcrypt or argon2
|
|
249
|
-
- [ ] **JWT verification**: Always verify signature and expiry
|
|
250
|
-
- [ ] **Rate limiting**: Protect from abuse
|
|
251
|
-
- [ ] **Security headers**: Helmet.js or equivalent
|
|
252
|
-
- [ ] **HTTPS**: Everywhere in production
|
|
253
|
-
- [ ] **CORS**: Properly configured
|
|
254
|
-
- [ ] **Secrets**: Environment variables only
|
|
255
|
-
- [ ] **Dependencies**: Regularly audited
|
|
256
|
-
|
|
257
|
-
### Security Mindset
|
|
215
|
+
## Project Structure
|
|
258
216
|
|
|
259
217
|
```
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
218
|
+
src/
|
|
219
|
+
routes/ HTTP route definitions (thin — only parse and delegate)
|
|
220
|
+
controllers/ Request handling, validation, response formatting
|
|
221
|
+
services/ Business logic (no HTTP awareness)
|
|
222
|
+
repositories/ Database access (no business logic)
|
|
223
|
+
middleware/ Auth, rate limit, logging
|
|
224
|
+
lib/ Shared utilities (date, crypto, validation)
|
|
225
|
+
types/ TypeScript interfaces and type exports
|
|
226
|
+
config/ Environment config with validation
|
|
267
227
|
```
|
|
268
228
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
## 8. Testing Principles
|
|
272
|
-
|
|
273
|
-
### Test Strategy Selection
|
|
229
|
+
**Dependency direction:** routes → controllers → services → repositories
|
|
230
|
+
**Never:** repositories calling services, or services knowing about HTTP
|
|
274
231
|
|
|
275
|
-
|
|
276
|
-
|------|---------|-------|
|
|
277
|
-
| **Unit** | Business logic | node:test, Vitest |
|
|
278
|
-
| **Integration** | API endpoints | Supertest |
|
|
279
|
-
| **E2E** | Full flows | Playwright |
|
|
280
|
-
|
|
281
|
-
### What to Test (Priorities)
|
|
232
|
+
---
|
|
282
233
|
|
|
283
|
-
|
|
284
|
-
2. **Edge cases**: Empty inputs, boundaries
|
|
285
|
-
3. **Error handling**: What happens when things fail?
|
|
286
|
-
4. **Not worth testing**: Framework code, trivial getters
|
|
234
|
+
## Output Format
|
|
287
235
|
|
|
288
|
-
|
|
236
|
+
When this skill produces or reviews code, structure your output as follows:
|
|
289
237
|
|
|
290
238
|
```
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
239
|
+
━━━ Nodejs Best Practices Report ━━━━━━━━━━━━━━━━━━━━━━━━
|
|
240
|
+
Skill: Nodejs Best Practices
|
|
241
|
+
Language: [detected language / framework]
|
|
242
|
+
Scope: [N files · N functions]
|
|
243
|
+
─────────────────────────────────────────────────
|
|
244
|
+
✅ Passed: [checks that passed, or "All clean"]
|
|
245
|
+
⚠️ Warnings: [non-blocking issues, or "None"]
|
|
246
|
+
❌ Blocked: [blocking issues requiring fix, or "None"]
|
|
247
|
+
─────────────────────────────────────────────────
|
|
248
|
+
VBC status: PENDING → VERIFIED
|
|
249
|
+
Evidence: [test output / lint pass / compile success]
|
|
295
250
|
```
|
|
296
251
|
|
|
297
|
-
|
|
252
|
+
**VBC (Verification-Before-Completion) is mandatory.**
|
|
253
|
+
Do not mark status as VERIFIED until concrete terminal evidence is provided.
|
|
298
254
|
|
|
299
|
-
## 10. Anti-Patterns to Avoid
|
|
300
|
-
|
|
301
|
-
### ❌ DON'T:
|
|
302
|
-
- Use Express for new edge projects (use Hono)
|
|
303
|
-
- Use sync methods in production code
|
|
304
|
-
- Put business logic in controllers
|
|
305
|
-
- Skip input validation
|
|
306
|
-
- Hardcode secrets
|
|
307
|
-
- Trust external data without validation
|
|
308
|
-
- Block event loop with CPU work
|
|
309
|
-
|
|
310
|
-
### ✅ DO:
|
|
311
|
-
- Choose framework based on context
|
|
312
|
-
- Ask user for preferences when unclear
|
|
313
|
-
- Use layered architecture for growing projects
|
|
314
|
-
- Validate all inputs
|
|
315
|
-
- Use environment variables for secrets
|
|
316
|
-
- Profile before optimizing
|
|
317
255
|
|
|
318
256
|
---
|
|
319
257
|
|
|
320
|
-
##
|
|
258
|
+
## 🏛️ Tribunal Integration (Anti-Hallucination)
|
|
321
259
|
|
|
322
|
-
|
|
260
|
+
**Slash command: `/tribunal-backend`**
|
|
261
|
+
**Active reviewers: `logic` · `security` · `dependency` · `type-safety`**
|
|
323
262
|
|
|
324
|
-
|
|
325
|
-
- [ ] **Chosen framework for THIS context?** (not just default)
|
|
326
|
-
- [ ] **Considered deployment target?**
|
|
327
|
-
- [ ] **Planned error handling strategy?**
|
|
328
|
-
- [ ] **Identified validation points?**
|
|
329
|
-
- [ ] **Considered security requirements?**
|
|
263
|
+
### ❌ Forbidden AI Tropes in Node.js
|
|
330
264
|
|
|
331
|
-
|
|
265
|
+
1. **Blindly mixing `require` and `import`** — pick ESM or CommonJS and stick to it strictly based on `package.json`.
|
|
266
|
+
2. **"Catch-all and ignore" error handling** — e.g., `catch (e) { console.log(e); }` without throwing or returning an error response.
|
|
267
|
+
3. **Assuming Express** — if the project is Next.js, Fastify, or NestJS, do not hallucinate Express code.
|
|
268
|
+
4. **Unparameterized queries** — never interpolate strings into SQL.
|
|
269
|
+
5. **No `any` types** — unless an external library leaves no choice, type all request bodies and responses.
|
|
270
|
+
|
|
271
|
+
### ✅ Pre-Flight Self-Audit
|
|
332
272
|
|
|
333
|
-
|
|
273
|
+
Review these questions before generating Node.js code:
|
|
274
|
+
```
|
|
275
|
+
✅ Did I use the correct module system (CJS vs ESM) for this context?
|
|
276
|
+
✅ Is every Promise rejection properly handled?
|
|
277
|
+
✅ Did I block the event loop with synchronous FS or Crypto operations?
|
|
278
|
+
✅ Are all inputs validated before business logic runs?
|
|
279
|
+
✅ Is this code safe from memory leaks (e.g., unbounded arrays/maps)?
|
|
280
|
+
```
|