@zimezone/z-command 1.1.1 → 1.1.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.
Files changed (282) hide show
  1. package/README.md +13 -1
  2. package/dist/commands/init.d.ts.map +1 -1
  3. package/dist/commands/init.js +34 -9
  4. package/dist/commands/init.js.map +1 -1
  5. package/package.json +8 -3
  6. package/templates.zip +0 -0
  7. package/templates/agents/accessibility-expert.agent.md +0 -56
  8. package/templates/agents/ai-engineer.agent.md +0 -61
  9. package/templates/agents/angular-architect.agent.md +0 -49
  10. package/templates/agents/api-designer.agent.md +0 -40
  11. package/templates/agents/api-documenter.agent.md +0 -161
  12. package/templates/agents/architect-review.agent.md +0 -146
  13. package/templates/agents/arm-cortex-expert.agent.md +0 -288
  14. package/templates/agents/azure-infra-engineer.agent.md +0 -57
  15. package/templates/agents/backend-architect.agent.md +0 -309
  16. package/templates/agents/backend-developer.agent.md +0 -61
  17. package/templates/agents/backend-security-coder.agent.md +0 -152
  18. package/templates/agents/bash-pro.agent.md +0 -285
  19. package/templates/agents/blockchain-developer.agent.md +0 -57
  20. package/templates/agents/build-engineer.agent.md +0 -56
  21. package/templates/agents/business-analyst.agent.md +0 -47
  22. package/templates/agents/c-pro.agent.md +0 -35
  23. package/templates/agents/c4-code.agent.md +0 -320
  24. package/templates/agents/c4-component.agent.md +0 -227
  25. package/templates/agents/c4-container.agent.md +0 -248
  26. package/templates/agents/c4-context.agent.md +0 -235
  27. package/templates/agents/cli-developer.agent.md +0 -57
  28. package/templates/agents/cloud-architect.agent.md +0 -56
  29. package/templates/agents/code-architect.agent.md +0 -63
  30. package/templates/agents/code-reviewer.agent.md +0 -49
  31. package/templates/agents/competitive-analyst.agent.md +0 -48
  32. package/templates/agents/conductor-validator.agent.md +0 -245
  33. package/templates/agents/context-manager.agent.md +0 -55
  34. package/templates/agents/cpp-pro.agent.md +0 -59
  35. package/templates/agents/csharp-developer.agent.md +0 -57
  36. package/templates/agents/csharp-pro.agent.md +0 -38
  37. package/templates/agents/customer-support.agent.md +0 -148
  38. package/templates/agents/data-engineer.agent.md +0 -55
  39. package/templates/agents/data-researcher.agent.md +0 -55
  40. package/templates/agents/data-scientist.agent.md +0 -56
  41. package/templates/agents/database-admin.agent.md +0 -142
  42. package/templates/agents/database-administrator.agent.md +0 -50
  43. package/templates/agents/database-architect.agent.md +0 -238
  44. package/templates/agents/database-optimizer.agent.md +0 -144
  45. package/templates/agents/debugger.agent.md +0 -30
  46. package/templates/agents/deployment-engineer.agent.md +0 -0
  47. package/templates/agents/devops-engineer.agent.md +0 -59
  48. package/templates/agents/devops-troubleshooter.agent.md +0 -138
  49. package/templates/agents/django-developer.agent.md +0 -50
  50. package/templates/agents/django-pro.agent.md +0 -159
  51. package/templates/agents/docs-architect.agent.md +0 -77
  52. package/templates/agents/documentation-engineer.agent.md +0 -57
  53. package/templates/agents/dotnet-architect.agent.md +0 -175
  54. package/templates/agents/dx-optimizer.agent.md +0 -63
  55. package/templates/agents/electron-pro.agent.md +0 -56
  56. package/templates/agents/elixir-pro.agent.md +0 -38
  57. package/templates/agents/embedded-systems.agent.md +0 -55
  58. package/templates/agents/error-detective.agent.md +0 -32
  59. package/templates/agents/event-sourcing-architect.agent.md +0 -42
  60. package/templates/agents/fastapi-pro.agent.md +0 -171
  61. package/templates/agents/fintech-engineer.agent.md +0 -57
  62. package/templates/agents/firmware-analyst.agent.md +0 -330
  63. package/templates/agents/flutter-expert.agent.md +0 -50
  64. package/templates/agents/frontend-developer.agent.md +0 -59
  65. package/templates/agents/frontend-security-coder.agent.md +0 -149
  66. package/templates/agents/fullstack-developer.agent.md +0 -46
  67. package/templates/agents/git-workflow-manager.agent.md +0 -57
  68. package/templates/agents/golang-pro.agent.md +0 -50
  69. package/templates/agents/graphql-architect.agent.md +0 -48
  70. package/templates/agents/haskell-pro.agent.md +0 -37
  71. package/templates/agents/hr-pro.agent.md +0 -105
  72. package/templates/agents/incident-responder.agent.md +0 -190
  73. package/templates/agents/ios-developer.agent.md +0 -198
  74. package/templates/agents/iot-engineer.agent.md +0 -56
  75. package/templates/agents/java-architect.agent.md +0 -48
  76. package/templates/agents/java-pro.agent.md +0 -156
  77. package/templates/agents/javascript-pro.agent.md +0 -35
  78. package/templates/agents/julia-pro.agent.md +0 -187
  79. package/templates/agents/kotlin-specialist.agent.md +0 -50
  80. package/templates/agents/laravel-specialist.agent.md +0 -50
  81. package/templates/agents/legacy-modernizer.agent.md +0 -56
  82. package/templates/agents/legal-advisor.agent.md +0 -49
  83. package/templates/agents/llm-architect.agent.md +0 -58
  84. package/templates/agents/malware-analyst.agent.md +0 -272
  85. package/templates/agents/mcp-developer.agent.md +0 -54
  86. package/templates/agents/mermaid-expert.agent.md +0 -39
  87. package/templates/agents/microservices-architect.agent.md +0 -47
  88. package/templates/agents/minecraft-bukkit-pro.agent.md +0 -104
  89. package/templates/agents/ml-engineer.agent.md +0 -56
  90. package/templates/agents/mlops-engineer.agent.md +0 -56
  91. package/templates/agents/mobile-developer.agent.md +0 -45
  92. package/templates/agents/mobile-security-coder.agent.md +0 -163
  93. package/templates/agents/monorepo-architect.agent.md +0 -44
  94. package/templates/agents/multi-agent-coordinator.agent.md +0 -55
  95. package/templates/agents/network-engineer.agent.md +0 -57
  96. package/templates/agents/nextjs-developer.agent.md +0 -48
  97. package/templates/agents/nlp-engineer.agent.md +0 -58
  98. package/templates/agents/observability-engineer.agent.md +0 -228
  99. package/templates/agents/payment-integration.agent.md +0 -56
  100. package/templates/agents/performance-engineer.agent.md +0 -167
  101. package/templates/agents/performance-optimizer.agent.md +0 -57
  102. package/templates/agents/php-pro.agent.md +0 -43
  103. package/templates/agents/platform-engineer.agent.md +0 -57
  104. package/templates/agents/posix-shell-pro.agent.md +0 -284
  105. package/templates/agents/postgres-pro.agent.md +0 -58
  106. package/templates/agents/product-manager.agent.md +0 -55
  107. package/templates/agents/project-manager.agent.md +0 -57
  108. package/templates/agents/prompt-engineer.agent.md +0 -58
  109. package/templates/agents/python-pro.agent.md +0 -48
  110. package/templates/agents/quant-analyst.agent.md +0 -32
  111. package/templates/agents/rails-expert.agent.md +0 -50
  112. package/templates/agents/react-specialist.agent.md +0 -49
  113. package/templates/agents/refactoring-specialist.agent.md +0 -56
  114. package/templates/agents/reference-builder.agent.md +0 -167
  115. package/templates/agents/research-analyst.agent.md +0 -63
  116. package/templates/agents/reverse-engineer.agent.md +0 -202
  117. package/templates/agents/risk-manager.agent.md +0 -41
  118. package/templates/agents/ruby-pro.agent.md +0 -35
  119. package/templates/agents/rust-pro.agent.md +0 -156
  120. package/templates/agents/sales-automator.agent.md +0 -35
  121. package/templates/agents/scala-pro.agent.md +0 -60
  122. package/templates/agents/scrum-master.agent.md +0 -54
  123. package/templates/agents/search-specialist.agent.md +0 -59
  124. package/templates/agents/security-analyst.agent.md +0 -57
  125. package/templates/agents/security-auditor.agent.md +0 -138
  126. package/templates/agents/security-engineer.agent.md +0 -57
  127. package/templates/agents/seo-authority-builder.agent.md +0 -116
  128. package/templates/agents/seo-cannibalization-detector.agent.md +0 -103
  129. package/templates/agents/seo-content-auditor.agent.md +0 -63
  130. package/templates/agents/seo-content-planner.agent.md +0 -88
  131. package/templates/agents/seo-content-refresher.agent.md +0 -98
  132. package/templates/agents/seo-content-writer.agent.md +0 -76
  133. package/templates/agents/seo-keyword-strategist.agent.md +0 -75
  134. package/templates/agents/seo-meta-optimizer.agent.md +0 -72
  135. package/templates/agents/seo-snippet-hunter.agent.md +0 -94
  136. package/templates/agents/seo-specialist.agent.md +0 -57
  137. package/templates/agents/seo-structure-architect.agent.md +0 -88
  138. package/templates/agents/service-mesh-expert.agent.md +0 -41
  139. package/templates/agents/sql-pro.agent.md +0 -146
  140. package/templates/agents/sre-engineer.agent.md +0 -58
  141. package/templates/agents/swift-expert.agent.md +0 -49
  142. package/templates/agents/task-distributor.agent.md +0 -47
  143. package/templates/agents/tdd-orchestrator.agent.md +0 -183
  144. package/templates/agents/technical-writer.agent.md +0 -48
  145. package/templates/agents/temporal-python-pro.agent.md +0 -349
  146. package/templates/agents/terraform-engineer.agent.md +0 -57
  147. package/templates/agents/terraform-specialist.agent.md +0 -137
  148. package/templates/agents/test-automator.agent.md +0 -203
  149. package/templates/agents/test-engineer.agent.md +0 -55
  150. package/templates/agents/threat-modeling-expert.agent.md +0 -44
  151. package/templates/agents/trend-analyst.agent.md +0 -47
  152. package/templates/agents/tutorial-engineer.agent.md +0 -118
  153. package/templates/agents/typescript-pro.agent.md +0 -48
  154. package/templates/agents/ui-designer.agent.md +0 -48
  155. package/templates/agents/ui-ux-designer.agent.md +0 -188
  156. package/templates/agents/ui-visual-validator.agent.md +0 -192
  157. package/templates/agents/ux-researcher.agent.md +0 -48
  158. package/templates/agents/vector-database-engineer.agent.md +0 -43
  159. package/templates/agents/vue-expert.agent.md +0 -48
  160. package/templates/agents/websocket-engineer.agent.md +0 -49
  161. package/templates/agents/workflow-orchestrator.agent.md +0 -48
  162. package/templates/skills/angular-migration/SKILL.md +0 -410
  163. package/templates/skills/api-design-principles/SKILL.md +0 -528
  164. package/templates/skills/api-design-principles/assets/api-design-checklist.md +0 -155
  165. package/templates/skills/api-design-principles/assets/rest-api-template.py +0 -182
  166. package/templates/skills/api-design-principles/references/graphql-schema-design.md +0 -583
  167. package/templates/skills/api-design-principles/references/rest-best-practices.md +0 -408
  168. package/templates/skills/architecture-decision-records/SKILL.md +0 -428
  169. package/templates/skills/architecture-patterns/SKILL.md +0 -494
  170. package/templates/skills/async-python-patterns/SKILL.md +0 -694
  171. package/templates/skills/auth-implementation-patterns/SKILL.md +0 -634
  172. package/templates/skills/changelog-automation/SKILL.md +0 -552
  173. package/templates/skills/code-review/SKILL.md +0 -62
  174. package/templates/skills/code-review-excellence/SKILL.md +0 -520
  175. package/templates/skills/competitive-landscape/SKILL.md +0 -479
  176. package/templates/skills/context-driven-development/SKILL.md +0 -385
  177. package/templates/skills/cost-optimization/SKILL.md +0 -274
  178. package/templates/skills/cqrs-implementation/SKILL.md +0 -554
  179. package/templates/skills/data-quality-frameworks/SKILL.md +0 -587
  180. package/templates/skills/data-storytelling/SKILL.md +0 -453
  181. package/templates/skills/database-migration/SKILL.md +0 -424
  182. package/templates/skills/dbt-transformation-patterns/SKILL.md +0 -561
  183. package/templates/skills/debugging-strategies/SKILL.md +0 -527
  184. package/templates/skills/defi-protocol-templates/SKILL.md +0 -454
  185. package/templates/skills/dependency-upgrade/SKILL.md +0 -409
  186. package/templates/skills/deployment-pipeline-design/SKILL.md +0 -359
  187. package/templates/skills/distributed-tracing/SKILL.md +0 -438
  188. package/templates/skills/dotnet-backend-patterns/SKILL.md +0 -815
  189. package/templates/skills/dotnet-backend-patterns/assets/repository-template.cs +0 -523
  190. package/templates/skills/dotnet-backend-patterns/assets/service-template.cs +0 -336
  191. package/templates/skills/dotnet-backend-patterns/references/dapper-patterns.md +0 -544
  192. package/templates/skills/dotnet-backend-patterns/references/ef-core-best-practices.md +0 -355
  193. package/templates/skills/e2e-testing-patterns/SKILL.md +0 -547
  194. package/templates/skills/employment-contract-templates/SKILL.md +0 -507
  195. package/templates/skills/error-handling-patterns/SKILL.md +0 -636
  196. package/templates/skills/event-store-design/SKILL.md +0 -437
  197. package/templates/skills/fastapi-templates/SKILL.md +0 -567
  198. package/templates/skills/git-advanced-workflows/SKILL.md +0 -400
  199. package/templates/skills/github-actions-templates/SKILL.md +0 -333
  200. package/templates/skills/go-concurrency-patterns/SKILL.md +0 -655
  201. package/templates/skills/grafana-dashboards/SKILL.md +0 -369
  202. package/templates/skills/helm-chart-scaffolding/SKILL.md +0 -544
  203. package/templates/skills/helm-chart-scaffolding/assets/Chart.yaml.template +0 -42
  204. package/templates/skills/helm-chart-scaffolding/assets/values.yaml.template +0 -185
  205. package/templates/skills/helm-chart-scaffolding/references/chart-structure.md +0 -500
  206. package/templates/skills/helm-chart-scaffolding/scripts/validate-chart.sh +0 -244
  207. package/templates/skills/javascript-testing-patterns/SKILL.md +0 -1025
  208. package/templates/skills/langchain-architecture/SKILL.md +0 -338
  209. package/templates/skills/llm-evaluation/SKILL.md +0 -471
  210. package/templates/skills/microservices-patterns/SKILL.md +0 -595
  211. package/templates/skills/modern-javascript-patterns/SKILL.md +0 -911
  212. package/templates/skills/monorepo-management/SKILL.md +0 -622
  213. package/templates/skills/nextjs-app-router-patterns/SKILL.md +0 -544
  214. package/templates/skills/nodejs-backend-patterns/SKILL.md +0 -1020
  215. package/templates/skills/nx-workspace-patterns/SKILL.md +0 -452
  216. package/templates/skills/openapi-spec-generation/SKILL.md +0 -1028
  217. package/templates/skills/paypal-integration/SKILL.md +0 -467
  218. package/templates/skills/pci-compliance/SKILL.md +0 -466
  219. package/templates/skills/postgresql/SKILL.md +0 -204
  220. package/templates/skills/projection-patterns/SKILL.md +0 -490
  221. package/templates/skills/prometheus-configuration/SKILL.md +0 -392
  222. package/templates/skills/prompt-engineering-patterns/SKILL.md +0 -201
  223. package/templates/skills/prompt-engineering-patterns/assets/few-shot-examples.json +0 -106
  224. package/templates/skills/prompt-engineering-patterns/assets/prompt-template-library.md +0 -246
  225. package/templates/skills/prompt-engineering-patterns/references/chain-of-thought.md +0 -399
  226. package/templates/skills/prompt-engineering-patterns/references/few-shot-learning.md +0 -369
  227. package/templates/skills/prompt-engineering-patterns/references/prompt-optimization.md +0 -414
  228. package/templates/skills/prompt-engineering-patterns/references/prompt-templates.md +0 -470
  229. package/templates/skills/prompt-engineering-patterns/references/system-prompts.md +0 -189
  230. package/templates/skills/prompt-engineering-patterns/scripts/optimize-prompt.py +0 -279
  231. package/templates/skills/python-packaging/SKILL.md +0 -870
  232. package/templates/skills/python-performance-optimization/SKILL.md +0 -869
  233. package/templates/skills/python-testing-patterns/SKILL.md +0 -907
  234. package/templates/skills/rag-implementation/SKILL.md +0 -403
  235. package/templates/skills/react-modernization/SKILL.md +0 -513
  236. package/templates/skills/react-native-architecture/SKILL.md +0 -671
  237. package/templates/skills/react-state-management/SKILL.md +0 -429
  238. package/templates/skills/risk-metrics-calculation/SKILL.md +0 -555
  239. package/templates/skills/rust-async-patterns/SKILL.md +0 -517
  240. package/templates/skills/secrets-management/SKILL.md +0 -346
  241. package/templates/skills/security-requirement-extraction/SKILL.md +0 -677
  242. package/templates/skills/security-review/SKILL.md +0 -78
  243. package/templates/skills/shellcheck-configuration/SKILL.md +0 -454
  244. package/templates/skills/similarity-search-patterns/SKILL.md +0 -558
  245. package/templates/skills/slo-implementation/SKILL.md +0 -329
  246. package/templates/skills/sql-optimization-patterns/SKILL.md +0 -493
  247. package/templates/skills/stripe-integration/SKILL.md +0 -442
  248. package/templates/skills/systematic-debugging/SKILL.md +0 -57
  249. package/templates/skills/tailwind-design-system/SKILL.md +0 -666
  250. package/templates/skills/temporal-python-testing/SKILL.md +0 -158
  251. package/templates/skills/temporal-python-testing/resources/integration-testing.md +0 -455
  252. package/templates/skills/temporal-python-testing/resources/local-setup.md +0 -553
  253. package/templates/skills/temporal-python-testing/resources/replay-testing.md +0 -462
  254. package/templates/skills/temporal-python-testing/resources/unit-testing.md +0 -328
  255. package/templates/skills/terraform-module-library/SKILL.md +0 -249
  256. package/templates/skills/terraform-module-library/references/aws-modules.md +0 -63
  257. package/templates/skills/test-driven-development/SKILL.md +0 -46
  258. package/templates/skills/threat-mitigation-mapping/SKILL.md +0 -745
  259. package/templates/skills/track-management/SKILL.md +0 -593
  260. package/templates/skills/typescript-advanced-types/SKILL.md +0 -717
  261. package/templates/skills/ui-ux-pro-max/SKILL.md +0 -352
  262. package/templates/skills/ui-ux-pro-max/data/charts.csv +0 -26
  263. package/templates/skills/ui-ux-pro-max/data/colors.csv +0 -97
  264. package/templates/skills/ui-ux-pro-max/data/icons.csv +0 -101
  265. package/templates/skills/ui-ux-pro-max/data/landing.csv +0 -31
  266. package/templates/skills/ui-ux-pro-max/data/products.csv +0 -97
  267. package/templates/skills/ui-ux-pro-max/data/prompts.csv +0 -24
  268. package/templates/skills/ui-ux-pro-max/data/react-performance.csv +0 -45
  269. package/templates/skills/ui-ux-pro-max/data/styles.csv +0 -59
  270. package/templates/skills/ui-ux-pro-max/data/typography.csv +0 -58
  271. package/templates/skills/ui-ux-pro-max/data/ui-reasoning.csv +0 -101
  272. package/templates/skills/ui-ux-pro-max/data/ux-guidelines.csv +0 -100
  273. package/templates/skills/ui-ux-pro-max/data/web-interface.csv +0 -31
  274. package/templates/skills/ui-ux-pro-max/scripts/core.py +0 -258
  275. package/templates/skills/ui-ux-pro-max/scripts/design_system.py +0 -547
  276. package/templates/skills/ui-ux-pro-max/scripts/search.py +0 -76
  277. package/templates/skills/uv-package-manager/SKILL.md +0 -831
  278. package/templates/skills/vector-index-tuning/SKILL.md +0 -521
  279. package/templates/skills/wcag-audit-patterns/SKILL.md +0 -555
  280. package/templates/skills/workflow-orchestration-patterns/SKILL.md +0 -316
  281. package/templates/skills/workflow-patterns/SKILL.md +0 -623
  282. package/templates/skills/writing-plans/SKILL.md +0 -64
@@ -1,1020 +0,0 @@
1
- ---
2
- name: nodejs-backend-patterns
3
- description: Build production-ready Node.js backend services with Express/Fastify, implementing middleware patterns, error handling, authentication, database integration, and API design best practices. Use when creating Node.js servers, REST APIs, GraphQL backends, or microservices architectures.
4
- ---
5
-
6
- # Node.js Backend Patterns
7
-
8
- Comprehensive guidance for building scalable, maintainable, and production-ready Node.js backend applications with modern frameworks, architectural patterns, and best practices.
9
-
10
- ## When to Use This Skill
11
-
12
- - Building REST APIs or GraphQL servers
13
- - Creating microservices with Node.js
14
- - Implementing authentication and authorization
15
- - Designing scalable backend architectures
16
- - Setting up middleware and error handling
17
- - Integrating databases (SQL and NoSQL)
18
- - Building real-time applications with WebSockets
19
- - Implementing background job processing
20
-
21
- ## Core Frameworks
22
-
23
- ### Express.js - Minimalist Framework
24
-
25
- **Basic Setup:**
26
- ```typescript
27
- import express, { Request, Response, NextFunction } from 'express';
28
- import helmet from 'helmet';
29
- import cors from 'cors';
30
- import compression from 'compression';
31
-
32
- const app = express();
33
-
34
- // Security middleware
35
- app.use(helmet());
36
- app.use(cors({ origin: process.env.ALLOWED_ORIGINS?.split(',') }));
37
- app.use(compression());
38
-
39
- // Body parsing
40
- app.use(express.json({ limit: '10mb' }));
41
- app.use(express.urlencoded({ extended: true, limit: '10mb' }));
42
-
43
- // Request logging
44
- app.use((req: Request, res: Response, next: NextFunction) => {
45
- console.log(`${req.method} ${req.path}`);
46
- next();
47
- });
48
-
49
- const PORT = process.env.PORT || 3000;
50
- app.listen(PORT, () => {
51
- console.log(`Server running on port ${PORT}`);
52
- });
53
- ```
54
-
55
- ### Fastify - High Performance Framework
56
-
57
- **Basic Setup:**
58
- ```typescript
59
- import Fastify from 'fastify';
60
- import helmet from '@fastify/helmet';
61
- import cors from '@fastify/cors';
62
- import compress from '@fastify/compress';
63
-
64
- const fastify = Fastify({
65
- logger: {
66
- level: process.env.LOG_LEVEL || 'info',
67
- transport: {
68
- target: 'pino-pretty',
69
- options: { colorize: true }
70
- }
71
- }
72
- });
73
-
74
- // Plugins
75
- await fastify.register(helmet);
76
- await fastify.register(cors, { origin: true });
77
- await fastify.register(compress);
78
-
79
- // Type-safe routes with schema validation
80
- fastify.post<{
81
- Body: { name: string; email: string };
82
- Reply: { id: string; name: string };
83
- }>('/users', {
84
- schema: {
85
- body: {
86
- type: 'object',
87
- required: ['name', 'email'],
88
- properties: {
89
- name: { type: 'string', minLength: 1 },
90
- email: { type: 'string', format: 'email' }
91
- }
92
- }
93
- }
94
- }, async (request, reply) => {
95
- const { name, email } = request.body;
96
- return { id: '123', name };
97
- });
98
-
99
- await fastify.listen({ port: 3000, host: '0.0.0.0' });
100
- ```
101
-
102
- ## Architectural Patterns
103
-
104
- ### Pattern 1: Layered Architecture
105
-
106
- **Structure:**
107
- ```
108
- src/
109
- ├── controllers/ # Handle HTTP requests/responses
110
- ├── services/ # Business logic
111
- ├── repositories/ # Data access layer
112
- ├── models/ # Data models
113
- ├── middleware/ # Express/Fastify middleware
114
- ├── routes/ # Route definitions
115
- ├── utils/ # Helper functions
116
- ├── config/ # Configuration
117
- └── types/ # TypeScript types
118
- ```
119
-
120
- **Controller Layer:**
121
- ```typescript
122
- // controllers/user.controller.ts
123
- import { Request, Response, NextFunction } from 'express';
124
- import { UserService } from '../services/user.service';
125
- import { CreateUserDTO, UpdateUserDTO } from '../types/user.types';
126
-
127
- export class UserController {
128
- constructor(private userService: UserService) {}
129
-
130
- async createUser(req: Request, res: Response, next: NextFunction) {
131
- try {
132
- const userData: CreateUserDTO = req.body;
133
- const user = await this.userService.createUser(userData);
134
- res.status(201).json(user);
135
- } catch (error) {
136
- next(error);
137
- }
138
- }
139
-
140
- async getUser(req: Request, res: Response, next: NextFunction) {
141
- try {
142
- const { id } = req.params;
143
- const user = await this.userService.getUserById(id);
144
- res.json(user);
145
- } catch (error) {
146
- next(error);
147
- }
148
- }
149
-
150
- async updateUser(req: Request, res: Response, next: NextFunction) {
151
- try {
152
- const { id } = req.params;
153
- const updates: UpdateUserDTO = req.body;
154
- const user = await this.userService.updateUser(id, updates);
155
- res.json(user);
156
- } catch (error) {
157
- next(error);
158
- }
159
- }
160
-
161
- async deleteUser(req: Request, res: Response, next: NextFunction) {
162
- try {
163
- const { id } = req.params;
164
- await this.userService.deleteUser(id);
165
- res.status(204).send();
166
- } catch (error) {
167
- next(error);
168
- }
169
- }
170
- }
171
- ```
172
-
173
- **Service Layer:**
174
- ```typescript
175
- // services/user.service.ts
176
- import { UserRepository } from '../repositories/user.repository';
177
- import { CreateUserDTO, UpdateUserDTO, User } from '../types/user.types';
178
- import { NotFoundError, ValidationError } from '../utils/errors';
179
- import bcrypt from 'bcrypt';
180
-
181
- export class UserService {
182
- constructor(private userRepository: UserRepository) {}
183
-
184
- async createUser(userData: CreateUserDTO): Promise<User> {
185
- // Validation
186
- const existingUser = await this.userRepository.findByEmail(userData.email);
187
- if (existingUser) {
188
- throw new ValidationError('Email already exists');
189
- }
190
-
191
- // Hash password
192
- const hashedPassword = await bcrypt.hash(userData.password, 10);
193
-
194
- // Create user
195
- const user = await this.userRepository.create({
196
- ...userData,
197
- password: hashedPassword
198
- });
199
-
200
- // Remove password from response
201
- const { password, ...userWithoutPassword } = user;
202
- return userWithoutPassword as User;
203
- }
204
-
205
- async getUserById(id: string): Promise<User> {
206
- const user = await this.userRepository.findById(id);
207
- if (!user) {
208
- throw new NotFoundError('User not found');
209
- }
210
- const { password, ...userWithoutPassword } = user;
211
- return userWithoutPassword as User;
212
- }
213
-
214
- async updateUser(id: string, updates: UpdateUserDTO): Promise<User> {
215
- const user = await this.userRepository.update(id, updates);
216
- if (!user) {
217
- throw new NotFoundError('User not found');
218
- }
219
- const { password, ...userWithoutPassword } = user;
220
- return userWithoutPassword as User;
221
- }
222
-
223
- async deleteUser(id: string): Promise<void> {
224
- const deleted = await this.userRepository.delete(id);
225
- if (!deleted) {
226
- throw new NotFoundError('User not found');
227
- }
228
- }
229
- }
230
- ```
231
-
232
- **Repository Layer:**
233
- ```typescript
234
- // repositories/user.repository.ts
235
- import { Pool } from 'pg';
236
- import { CreateUserDTO, UpdateUserDTO, UserEntity } from '../types/user.types';
237
-
238
- export class UserRepository {
239
- constructor(private db: Pool) {}
240
-
241
- async create(userData: CreateUserDTO & { password: string }): Promise<UserEntity> {
242
- const query = `
243
- INSERT INTO users (name, email, password)
244
- VALUES ($1, $2, $3)
245
- RETURNING id, name, email, password, created_at, updated_at
246
- `;
247
- const { rows } = await this.db.query(query, [
248
- userData.name,
249
- userData.email,
250
- userData.password
251
- ]);
252
- return rows[0];
253
- }
254
-
255
- async findById(id: string): Promise<UserEntity | null> {
256
- const query = 'SELECT * FROM users WHERE id = $1';
257
- const { rows } = await this.db.query(query, [id]);
258
- return rows[0] || null;
259
- }
260
-
261
- async findByEmail(email: string): Promise<UserEntity | null> {
262
- const query = 'SELECT * FROM users WHERE email = $1';
263
- const { rows } = await this.db.query(query, [email]);
264
- return rows[0] || null;
265
- }
266
-
267
- async update(id: string, updates: UpdateUserDTO): Promise<UserEntity | null> {
268
- const fields = Object.keys(updates);
269
- const values = Object.values(updates);
270
-
271
- const setClause = fields
272
- .map((field, idx) => `${field} = $${idx + 2}`)
273
- .join(', ');
274
-
275
- const query = `
276
- UPDATE users
277
- SET ${setClause}, updated_at = CURRENT_TIMESTAMP
278
- WHERE id = $1
279
- RETURNING *
280
- `;
281
-
282
- const { rows } = await this.db.query(query, [id, ...values]);
283
- return rows[0] || null;
284
- }
285
-
286
- async delete(id: string): Promise<boolean> {
287
- const query = 'DELETE FROM users WHERE id = $1';
288
- const { rowCount } = await this.db.query(query, [id]);
289
- return rowCount > 0;
290
- }
291
- }
292
- ```
293
-
294
- ### Pattern 2: Dependency Injection
295
-
296
- **DI Container:**
297
- ```typescript
298
- // di-container.ts
299
- import { Pool } from 'pg';
300
- import { UserRepository } from './repositories/user.repository';
301
- import { UserService } from './services/user.service';
302
- import { UserController } from './controllers/user.controller';
303
- import { AuthService } from './services/auth.service';
304
-
305
- class Container {
306
- private instances = new Map<string, any>();
307
-
308
- register<T>(key: string, factory: () => T): void {
309
- this.instances.set(key, factory);
310
- }
311
-
312
- resolve<T>(key: string): T {
313
- const factory = this.instances.get(key);
314
- if (!factory) {
315
- throw new Error(`No factory registered for ${key}`);
316
- }
317
- return factory();
318
- }
319
-
320
- singleton<T>(key: string, factory: () => T): void {
321
- let instance: T;
322
- this.instances.set(key, () => {
323
- if (!instance) {
324
- instance = factory();
325
- }
326
- return instance;
327
- });
328
- }
329
- }
330
-
331
- export const container = new Container();
332
-
333
- // Register dependencies
334
- container.singleton('db', () => new Pool({
335
- host: process.env.DB_HOST,
336
- port: parseInt(process.env.DB_PORT || '5432'),
337
- database: process.env.DB_NAME,
338
- user: process.env.DB_USER,
339
- password: process.env.DB_PASSWORD,
340
- max: 20,
341
- idleTimeoutMillis: 30000,
342
- connectionTimeoutMillis: 2000,
343
- }));
344
-
345
- container.singleton('userRepository', () =>
346
- new UserRepository(container.resolve('db'))
347
- );
348
-
349
- container.singleton('userService', () =>
350
- new UserService(container.resolve('userRepository'))
351
- );
352
-
353
- container.register('userController', () =>
354
- new UserController(container.resolve('userService'))
355
- );
356
-
357
- container.singleton('authService', () =>
358
- new AuthService(container.resolve('userRepository'))
359
- );
360
- ```
361
-
362
- ## Middleware Patterns
363
-
364
- ### Authentication Middleware
365
-
366
- ```typescript
367
- // middleware/auth.middleware.ts
368
- import { Request, Response, NextFunction } from 'express';
369
- import jwt from 'jsonwebtoken';
370
- import { UnauthorizedError } from '../utils/errors';
371
-
372
- interface JWTPayload {
373
- userId: string;
374
- email: string;
375
- }
376
-
377
- declare global {
378
- namespace Express {
379
- interface Request {
380
- user?: JWTPayload;
381
- }
382
- }
383
- }
384
-
385
- export const authenticate = async (
386
- req: Request,
387
- res: Response,
388
- next: NextFunction
389
- ) => {
390
- try {
391
- const token = req.headers.authorization?.replace('Bearer ', '');
392
-
393
- if (!token) {
394
- throw new UnauthorizedError('No token provided');
395
- }
396
-
397
- const payload = jwt.verify(
398
- token,
399
- process.env.JWT_SECRET!
400
- ) as JWTPayload;
401
-
402
- req.user = payload;
403
- next();
404
- } catch (error) {
405
- next(new UnauthorizedError('Invalid token'));
406
- }
407
- };
408
-
409
- export const authorize = (...roles: string[]) => {
410
- return async (req: Request, res: Response, next: NextFunction) => {
411
- if (!req.user) {
412
- return next(new UnauthorizedError('Not authenticated'));
413
- }
414
-
415
- // Check if user has required role
416
- const hasRole = roles.some(role =>
417
- req.user?.roles?.includes(role)
418
- );
419
-
420
- if (!hasRole) {
421
- return next(new UnauthorizedError('Insufficient permissions'));
422
- }
423
-
424
- next();
425
- };
426
- };
427
- ```
428
-
429
- ### Validation Middleware
430
-
431
- ```typescript
432
- // middleware/validation.middleware.ts
433
- import { Request, Response, NextFunction } from 'express';
434
- import { AnyZodObject, ZodError } from 'zod';
435
- import { ValidationError } from '../utils/errors';
436
-
437
- export const validate = (schema: AnyZodObject) => {
438
- return async (req: Request, res: Response, next: NextFunction) => {
439
- try {
440
- await schema.parseAsync({
441
- body: req.body,
442
- query: req.query,
443
- params: req.params
444
- });
445
- next();
446
- } catch (error) {
447
- if (error instanceof ZodError) {
448
- const errors = error.errors.map(err => ({
449
- field: err.path.join('.'),
450
- message: err.message
451
- }));
452
- next(new ValidationError('Validation failed', errors));
453
- } else {
454
- next(error);
455
- }
456
- }
457
- };
458
- };
459
-
460
- // Usage with Zod
461
- import { z } from 'zod';
462
-
463
- const createUserSchema = z.object({
464
- body: z.object({
465
- name: z.string().min(1),
466
- email: z.string().email(),
467
- password: z.string().min(8)
468
- })
469
- });
470
-
471
- router.post('/users', validate(createUserSchema), userController.createUser);
472
- ```
473
-
474
- ### Rate Limiting Middleware
475
-
476
- ```typescript
477
- // middleware/rate-limit.middleware.ts
478
- import rateLimit from 'express-rate-limit';
479
- import RedisStore from 'rate-limit-redis';
480
- import Redis from 'ioredis';
481
-
482
- const redis = new Redis({
483
- host: process.env.REDIS_HOST,
484
- port: parseInt(process.env.REDIS_PORT || '6379')
485
- });
486
-
487
- export const apiLimiter = rateLimit({
488
- store: new RedisStore({
489
- client: redis,
490
- prefix: 'rl:',
491
- }),
492
- windowMs: 15 * 60 * 1000, // 15 minutes
493
- max: 100, // Limit each IP to 100 requests per windowMs
494
- message: 'Too many requests from this IP, please try again later',
495
- standardHeaders: true,
496
- legacyHeaders: false,
497
- });
498
-
499
- export const authLimiter = rateLimit({
500
- store: new RedisStore({
501
- client: redis,
502
- prefix: 'rl:auth:',
503
- }),
504
- windowMs: 15 * 60 * 1000,
505
- max: 5, // Stricter limit for auth endpoints
506
- skipSuccessfulRequests: true,
507
- });
508
- ```
509
-
510
- ### Request Logging Middleware
511
-
512
- ```typescript
513
- // middleware/logger.middleware.ts
514
- import { Request, Response, NextFunction } from 'express';
515
- import pino from 'pino';
516
-
517
- const logger = pino({
518
- level: process.env.LOG_LEVEL || 'info',
519
- transport: {
520
- target: 'pino-pretty',
521
- options: { colorize: true }
522
- }
523
- });
524
-
525
- export const requestLogger = (
526
- req: Request,
527
- res: Response,
528
- next: NextFunction
529
- ) => {
530
- const start = Date.now();
531
-
532
- // Log response when finished
533
- res.on('finish', () => {
534
- const duration = Date.now() - start;
535
- logger.info({
536
- method: req.method,
537
- url: req.url,
538
- status: res.statusCode,
539
- duration: `${duration}ms`,
540
- userAgent: req.headers['user-agent'],
541
- ip: req.ip
542
- });
543
- });
544
-
545
- next();
546
- };
547
-
548
- export { logger };
549
- ```
550
-
551
- ## Error Handling
552
-
553
- ### Custom Error Classes
554
-
555
- ```typescript
556
- // utils/errors.ts
557
- export class AppError extends Error {
558
- constructor(
559
- public message: string,
560
- public statusCode: number = 500,
561
- public isOperational: boolean = true
562
- ) {
563
- super(message);
564
- Object.setPrototypeOf(this, AppError.prototype);
565
- Error.captureStackTrace(this, this.constructor);
566
- }
567
- }
568
-
569
- export class ValidationError extends AppError {
570
- constructor(message: string, public errors?: any[]) {
571
- super(message, 400);
572
- }
573
- }
574
-
575
- export class NotFoundError extends AppError {
576
- constructor(message: string = 'Resource not found') {
577
- super(message, 404);
578
- }
579
- }
580
-
581
- export class UnauthorizedError extends AppError {
582
- constructor(message: string = 'Unauthorized') {
583
- super(message, 401);
584
- }
585
- }
586
-
587
- export class ForbiddenError extends AppError {
588
- constructor(message: string = 'Forbidden') {
589
- super(message, 403);
590
- }
591
- }
592
-
593
- export class ConflictError extends AppError {
594
- constructor(message: string) {
595
- super(message, 409);
596
- }
597
- }
598
- ```
599
-
600
- ### Global Error Handler
601
-
602
- ```typescript
603
- // middleware/error-handler.ts
604
- import { Request, Response, NextFunction } from 'express';
605
- import { AppError } from '../utils/errors';
606
- import { logger } from './logger.middleware';
607
-
608
- export const errorHandler = (
609
- err: Error,
610
- req: Request,
611
- res: Response,
612
- next: NextFunction
613
- ) => {
614
- if (err instanceof AppError) {
615
- return res.status(err.statusCode).json({
616
- status: 'error',
617
- message: err.message,
618
- ...(err instanceof ValidationError && { errors: err.errors })
619
- });
620
- }
621
-
622
- // Log unexpected errors
623
- logger.error({
624
- error: err.message,
625
- stack: err.stack,
626
- url: req.url,
627
- method: req.method
628
- });
629
-
630
- // Don't leak error details in production
631
- const message = process.env.NODE_ENV === 'production'
632
- ? 'Internal server error'
633
- : err.message;
634
-
635
- res.status(500).json({
636
- status: 'error',
637
- message
638
- });
639
- };
640
-
641
- // Async error wrapper
642
- export const asyncHandler = (
643
- fn: (req: Request, res: Response, next: NextFunction) => Promise<any>
644
- ) => {
645
- return (req: Request, res: Response, next: NextFunction) => {
646
- Promise.resolve(fn(req, res, next)).catch(next);
647
- };
648
- };
649
- ```
650
-
651
- ## Database Patterns
652
-
653
- ### PostgreSQL with Connection Pool
654
-
655
- ```typescript
656
- // config/database.ts
657
- import { Pool, PoolConfig } from 'pg';
658
-
659
- const poolConfig: PoolConfig = {
660
- host: process.env.DB_HOST,
661
- port: parseInt(process.env.DB_PORT || '5432'),
662
- database: process.env.DB_NAME,
663
- user: process.env.DB_USER,
664
- password: process.env.DB_PASSWORD,
665
- max: 20,
666
- idleTimeoutMillis: 30000,
667
- connectionTimeoutMillis: 2000,
668
- };
669
-
670
- export const pool = new Pool(poolConfig);
671
-
672
- // Test connection
673
- pool.on('connect', () => {
674
- console.log('Database connected');
675
- });
676
-
677
- pool.on('error', (err) => {
678
- console.error('Unexpected database error', err);
679
- process.exit(-1);
680
- });
681
-
682
- // Graceful shutdown
683
- export const closeDatabase = async () => {
684
- await pool.end();
685
- console.log('Database connection closed');
686
- };
687
- ```
688
-
689
- ### MongoDB with Mongoose
690
-
691
- ```typescript
692
- // config/mongoose.ts
693
- import mongoose from 'mongoose';
694
-
695
- const connectDB = async () => {
696
- try {
697
- await mongoose.connect(process.env.MONGODB_URI!, {
698
- maxPoolSize: 10,
699
- serverSelectionTimeoutMS: 5000,
700
- socketTimeoutMS: 45000,
701
- });
702
-
703
- console.log('MongoDB connected');
704
- } catch (error) {
705
- console.error('MongoDB connection error:', error);
706
- process.exit(1);
707
- }
708
- };
709
-
710
- mongoose.connection.on('disconnected', () => {
711
- console.log('MongoDB disconnected');
712
- });
713
-
714
- mongoose.connection.on('error', (err) => {
715
- console.error('MongoDB error:', err);
716
- });
717
-
718
- export { connectDB };
719
-
720
- // Model example
721
- import { Schema, model, Document } from 'mongoose';
722
-
723
- interface IUser extends Document {
724
- name: string;
725
- email: string;
726
- password: string;
727
- createdAt: Date;
728
- updatedAt: Date;
729
- }
730
-
731
- const userSchema = new Schema<IUser>({
732
- name: { type: String, required: true },
733
- email: { type: String, required: true, unique: true },
734
- password: { type: String, required: true },
735
- }, {
736
- timestamps: true
737
- });
738
-
739
- // Indexes
740
- userSchema.index({ email: 1 });
741
-
742
- export const User = model<IUser>('User', userSchema);
743
- ```
744
-
745
- ### Transaction Pattern
746
-
747
- ```typescript
748
- // services/order.service.ts
749
- import { Pool } from 'pg';
750
-
751
- export class OrderService {
752
- constructor(private db: Pool) {}
753
-
754
- async createOrder(userId: string, items: any[]) {
755
- const client = await this.db.connect();
756
-
757
- try {
758
- await client.query('BEGIN');
759
-
760
- // Create order
761
- const orderResult = await client.query(
762
- 'INSERT INTO orders (user_id, total) VALUES ($1, $2) RETURNING id',
763
- [userId, calculateTotal(items)]
764
- );
765
- const orderId = orderResult.rows[0].id;
766
-
767
- // Create order items
768
- for (const item of items) {
769
- await client.query(
770
- 'INSERT INTO order_items (order_id, product_id, quantity, price) VALUES ($1, $2, $3, $4)',
771
- [orderId, item.productId, item.quantity, item.price]
772
- );
773
-
774
- // Update inventory
775
- await client.query(
776
- 'UPDATE products SET stock = stock - $1 WHERE id = $2',
777
- [item.quantity, item.productId]
778
- );
779
- }
780
-
781
- await client.query('COMMIT');
782
- return orderId;
783
- } catch (error) {
784
- await client.query('ROLLBACK');
785
- throw error;
786
- } finally {
787
- client.release();
788
- }
789
- }
790
- }
791
- ```
792
-
793
- ## Authentication & Authorization
794
-
795
- ### JWT Authentication
796
-
797
- ```typescript
798
- // services/auth.service.ts
799
- import jwt from 'jsonwebtoken';
800
- import bcrypt from 'bcrypt';
801
- import { UserRepository } from '../repositories/user.repository';
802
- import { UnauthorizedError } from '../utils/errors';
803
-
804
- export class AuthService {
805
- constructor(private userRepository: UserRepository) {}
806
-
807
- async login(email: string, password: string) {
808
- const user = await this.userRepository.findByEmail(email);
809
-
810
- if (!user) {
811
- throw new UnauthorizedError('Invalid credentials');
812
- }
813
-
814
- const isValid = await bcrypt.compare(password, user.password);
815
-
816
- if (!isValid) {
817
- throw new UnauthorizedError('Invalid credentials');
818
- }
819
-
820
- const token = this.generateToken({
821
- userId: user.id,
822
- email: user.email
823
- });
824
-
825
- const refreshToken = this.generateRefreshToken({
826
- userId: user.id
827
- });
828
-
829
- return {
830
- token,
831
- refreshToken,
832
- user: {
833
- id: user.id,
834
- name: user.name,
835
- email: user.email
836
- }
837
- };
838
- }
839
-
840
- async refreshToken(refreshToken: string) {
841
- try {
842
- const payload = jwt.verify(
843
- refreshToken,
844
- process.env.REFRESH_TOKEN_SECRET!
845
- ) as { userId: string };
846
-
847
- const user = await this.userRepository.findById(payload.userId);
848
-
849
- if (!user) {
850
- throw new UnauthorizedError('User not found');
851
- }
852
-
853
- const token = this.generateToken({
854
- userId: user.id,
855
- email: user.email
856
- });
857
-
858
- return { token };
859
- } catch (error) {
860
- throw new UnauthorizedError('Invalid refresh token');
861
- }
862
- }
863
-
864
- private generateToken(payload: any): string {
865
- return jwt.sign(payload, process.env.JWT_SECRET!, {
866
- expiresIn: '15m'
867
- });
868
- }
869
-
870
- private generateRefreshToken(payload: any): string {
871
- return jwt.sign(payload, process.env.REFRESH_TOKEN_SECRET!, {
872
- expiresIn: '7d'
873
- });
874
- }
875
- }
876
- ```
877
-
878
- ## Caching Strategies
879
-
880
- ```typescript
881
- // utils/cache.ts
882
- import Redis from 'ioredis';
883
-
884
- const redis = new Redis({
885
- host: process.env.REDIS_HOST,
886
- port: parseInt(process.env.REDIS_PORT || '6379'),
887
- retryStrategy: (times) => {
888
- const delay = Math.min(times * 50, 2000);
889
- return delay;
890
- }
891
- });
892
-
893
- export class CacheService {
894
- async get<T>(key: string): Promise<T | null> {
895
- const data = await redis.get(key);
896
- return data ? JSON.parse(data) : null;
897
- }
898
-
899
- async set(key: string, value: any, ttl?: number): Promise<void> {
900
- const serialized = JSON.stringify(value);
901
- if (ttl) {
902
- await redis.setex(key, ttl, serialized);
903
- } else {
904
- await redis.set(key, serialized);
905
- }
906
- }
907
-
908
- async delete(key: string): Promise<void> {
909
- await redis.del(key);
910
- }
911
-
912
- async invalidatePattern(pattern: string): Promise<void> {
913
- const keys = await redis.keys(pattern);
914
- if (keys.length > 0) {
915
- await redis.del(...keys);
916
- }
917
- }
918
- }
919
-
920
- // Cache decorator
921
- export function Cacheable(ttl: number = 300) {
922
- return function (
923
- target: any,
924
- propertyKey: string,
925
- descriptor: PropertyDescriptor
926
- ) {
927
- const originalMethod = descriptor.value;
928
-
929
- descriptor.value = async function (...args: any[]) {
930
- const cache = new CacheService();
931
- const cacheKey = `${propertyKey}:${JSON.stringify(args)}`;
932
-
933
- const cached = await cache.get(cacheKey);
934
- if (cached) {
935
- return cached;
936
- }
937
-
938
- const result = await originalMethod.apply(this, args);
939
- await cache.set(cacheKey, result, ttl);
940
-
941
- return result;
942
- };
943
-
944
- return descriptor;
945
- };
946
- }
947
- ```
948
-
949
- ## API Response Format
950
-
951
- ```typescript
952
- // utils/response.ts
953
- import { Response } from 'express';
954
-
955
- export class ApiResponse {
956
- static success<T>(res: Response, data: T, message?: string, statusCode = 200) {
957
- return res.status(statusCode).json({
958
- status: 'success',
959
- message,
960
- data
961
- });
962
- }
963
-
964
- static error(res: Response, message: string, statusCode = 500, errors?: any) {
965
- return res.status(statusCode).json({
966
- status: 'error',
967
- message,
968
- ...(errors && { errors })
969
- });
970
- }
971
-
972
- static paginated<T>(
973
- res: Response,
974
- data: T[],
975
- page: number,
976
- limit: number,
977
- total: number
978
- ) {
979
- return res.json({
980
- status: 'success',
981
- data,
982
- pagination: {
983
- page,
984
- limit,
985
- total,
986
- pages: Math.ceil(total / limit)
987
- }
988
- });
989
- }
990
- }
991
- ```
992
-
993
- ## Best Practices
994
-
995
- 1. **Use TypeScript**: Type safety prevents runtime errors
996
- 2. **Implement proper error handling**: Use custom error classes
997
- 3. **Validate input**: Use libraries like Zod or Joi
998
- 4. **Use environment variables**: Never hardcode secrets
999
- 5. **Implement logging**: Use structured logging (Pino, Winston)
1000
- 6. **Add rate limiting**: Prevent abuse
1001
- 7. **Use HTTPS**: Always in production
1002
- 8. **Implement CORS properly**: Don't use `*` in production
1003
- 9. **Use dependency injection**: Easier testing and maintenance
1004
- 10. **Write tests**: Unit, integration, and E2E tests
1005
- 11. **Handle graceful shutdown**: Clean up resources
1006
- 12. **Use connection pooling**: For databases
1007
- 13. **Implement health checks**: For monitoring
1008
- 14. **Use compression**: Reduce response size
1009
- 15. **Monitor performance**: Use APM tools
1010
-
1011
- ## Testing Patterns
1012
-
1013
- See `javascript-testing-patterns` skill for comprehensive testing guidance.
1014
-
1015
- ## Resources
1016
-
1017
- - **Node.js Best Practices**: https://github.com/goldbergyoni/nodebestpractices
1018
- - **Express.js Guide**: https://expressjs.com/en/guide/
1019
- - **Fastify Documentation**: https://www.fastify.io/docs/
1020
- - **TypeScript Node Starter**: https://github.com/microsoft/TypeScript-Node-Starter