nodejs-quickstart-structure 1.18.0 → 1.19.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 (113) hide show
  1. package/CHANGELOG.md +17 -4
  2. package/README.md +2 -1
  3. package/bin/index.js +93 -92
  4. package/lib/generator.js +1 -1
  5. package/lib/modules/caching-setup.js +76 -73
  6. package/lib/modules/config-files.js +4 -0
  7. package/lib/modules/kafka-setup.js +249 -191
  8. package/lib/modules/project-setup.js +1 -0
  9. package/package.json +13 -2
  10. package/templates/clean-architecture/js/src/errors/BadRequestError.js +11 -10
  11. package/templates/clean-architecture/js/src/errors/BadRequestError.spec.js.ejs +22 -21
  12. package/templates/clean-architecture/js/src/errors/NotFoundError.js +11 -10
  13. package/templates/clean-architecture/js/src/errors/NotFoundError.spec.js.ejs +22 -21
  14. package/templates/clean-architecture/js/src/infrastructure/repositories/UserRepository.js.ejs +69 -39
  15. package/templates/clean-architecture/js/src/infrastructure/repositories/UserRepository.spec.js.ejs +142 -81
  16. package/templates/clean-architecture/js/src/infrastructure/webserver/server.js.ejs +1 -1
  17. package/templates/clean-architecture/js/src/interfaces/controllers/userController.js.ejs +156 -75
  18. package/templates/clean-architecture/js/src/interfaces/controllers/userController.spec.js.ejs +234 -138
  19. package/templates/clean-architecture/js/src/interfaces/graphql/resolvers/user.resolvers.js.ejs +27 -21
  20. package/templates/clean-architecture/js/src/interfaces/graphql/resolvers/user.resolvers.spec.js.ejs +66 -49
  21. package/templates/clean-architecture/js/src/interfaces/graphql/typeDefs/user.types.js.ejs +19 -17
  22. package/templates/clean-architecture/js/src/interfaces/routes/api.js +12 -10
  23. package/templates/clean-architecture/js/src/usecases/DeleteUser.js +11 -0
  24. package/templates/clean-architecture/js/src/usecases/DeleteUser.spec.js.ejs +47 -0
  25. package/templates/clean-architecture/js/src/usecases/UpdateUser.js +11 -0
  26. package/templates/clean-architecture/js/src/usecases/UpdateUser.spec.js.ejs +48 -0
  27. package/templates/clean-architecture/js/src/utils/errorMessages.js +14 -0
  28. package/templates/clean-architecture/ts/src/errors/BadRequestError.spec.ts.ejs +22 -21
  29. package/templates/clean-architecture/ts/src/errors/BadRequestError.ts +9 -8
  30. package/templates/clean-architecture/ts/src/errors/NotFoundError.spec.ts.ejs +22 -21
  31. package/templates/clean-architecture/ts/src/errors/NotFoundError.ts +9 -8
  32. package/templates/clean-architecture/ts/src/index.ts.ejs +1 -1
  33. package/templates/clean-architecture/ts/src/infrastructure/repositories/UserRepository.spec.ts.ejs +175 -85
  34. package/templates/clean-architecture/ts/src/infrastructure/repositories/userRepository.ts.ejs +74 -0
  35. package/templates/clean-architecture/ts/src/interfaces/controllers/userController.spec.ts.ejs +331 -185
  36. package/templates/clean-architecture/ts/src/interfaces/controllers/userController.ts.ejs +173 -84
  37. package/templates/clean-architecture/ts/src/interfaces/graphql/resolvers/user.resolvers.spec.ts.ejs +68 -51
  38. package/templates/clean-architecture/ts/src/interfaces/graphql/resolvers/user.resolvers.ts.ejs +29 -21
  39. package/templates/clean-architecture/ts/src/interfaces/graphql/typeDefs/user.types.ts.ejs +17 -15
  40. package/templates/clean-architecture/ts/src/interfaces/routes/userRoutes.ts +13 -11
  41. package/templates/clean-architecture/ts/src/usecases/deleteUser.spec.ts.ejs +47 -0
  42. package/templates/clean-architecture/ts/src/usecases/deleteUser.ts +9 -0
  43. package/templates/clean-architecture/ts/src/usecases/updateUser.spec.ts.ejs +48 -0
  44. package/templates/clean-architecture/ts/src/usecases/updateUser.ts +9 -0
  45. package/templates/clean-architecture/ts/src/utils/errorMessages.ts +12 -0
  46. package/templates/common/.gitattributes +46 -0
  47. package/templates/common/.snyk.ejs +45 -0
  48. package/templates/common/Dockerfile +17 -9
  49. package/templates/common/README.md.ejs +295 -263
  50. package/templates/common/caching/clean/js/DeleteUser.js.ejs +27 -0
  51. package/templates/common/caching/clean/js/UpdateUser.js.ejs +27 -0
  52. package/templates/common/caching/clean/ts/deleteUser.ts.ejs +24 -0
  53. package/templates/common/caching/clean/ts/updateUser.ts.ejs +25 -0
  54. package/templates/common/caching/ts/memoryCache.ts.ejs +73 -64
  55. package/templates/common/caching/ts/redisClient.ts.ejs +89 -80
  56. package/templates/common/database/js/models/User.js.ejs +79 -53
  57. package/templates/common/database/js/models/User.js.mongoose.ejs +23 -19
  58. package/templates/common/database/js/models/User.spec.js.ejs +94 -84
  59. package/templates/common/database/ts/models/User.spec.ts.ejs +100 -84
  60. package/templates/common/database/ts/models/User.ts.ejs +87 -61
  61. package/templates/common/database/ts/models/User.ts.mongoose.ejs +30 -25
  62. package/templates/common/health/js/healthRoute.js.ejs +50 -47
  63. package/templates/common/health/ts/healthRoute.ts.ejs +49 -46
  64. package/templates/common/jest.e2e.config.js.ejs +8 -8
  65. package/templates/common/kafka/js/messaging/baseConsumer.js.ejs +30 -30
  66. package/templates/common/kafka/js/messaging/userEventSchema.js.ejs +12 -11
  67. package/templates/common/kafka/js/messaging/welcomeEmailConsumer.js.ejs +44 -31
  68. package/templates/common/kafka/js/messaging/welcomeEmailConsumer.spec.js.ejs +86 -49
  69. package/templates/common/kafka/js/services/kafkaService.js.ejs +93 -93
  70. package/templates/common/kafka/js/utils/kafkaEvents.js.ejs +7 -0
  71. package/templates/common/kafka/ts/messaging/userEventSchema.spec.ts.ejs +51 -51
  72. package/templates/common/kafka/ts/messaging/userEventSchema.ts.ejs +12 -11
  73. package/templates/common/kafka/ts/messaging/welcomeEmailConsumer.spec.ts.ejs +86 -49
  74. package/templates/common/kafka/ts/messaging/welcomeEmailConsumer.ts.ejs +38 -25
  75. package/templates/common/kafka/ts/services/kafkaService.ts.ejs +95 -95
  76. package/templates/common/kafka/ts/utils/kafkaEvents.ts.ejs +5 -0
  77. package/templates/common/package.json.ejs +10 -2
  78. package/templates/common/shutdown/js/gracefulShutdown.js.ejs +65 -61
  79. package/templates/common/shutdown/js/gracefulShutdown.spec.js.ejs +149 -160
  80. package/templates/common/shutdown/ts/gracefulShutdown.spec.ts.ejs +179 -158
  81. package/templates/common/shutdown/ts/gracefulShutdown.ts.ejs +59 -55
  82. package/templates/common/src/tests/e2e/e2e.users.test.js.ejs +120 -49
  83. package/templates/common/src/tests/e2e/e2e.users.test.ts.ejs +120 -49
  84. package/templates/common/swagger.yml.ejs +118 -66
  85. package/templates/db/mysql/V1__Initial_Setup.sql.ejs +10 -9
  86. package/templates/db/postgres/V1__Initial_Setup.sql.ejs +10 -9
  87. package/templates/mvc/js/src/controllers/userController.js.ejs +246 -105
  88. package/templates/mvc/js/src/controllers/userController.spec.js.ejs +481 -209
  89. package/templates/mvc/js/src/errors/BadRequestError.js +11 -10
  90. package/templates/mvc/js/src/errors/BadRequestError.spec.js.ejs +22 -21
  91. package/templates/mvc/js/src/errors/NotFoundError.js +11 -10
  92. package/templates/mvc/js/src/errors/NotFoundError.spec.js.ejs +22 -21
  93. package/templates/mvc/js/src/graphql/resolvers/user.resolvers.js.ejs +25 -19
  94. package/templates/mvc/js/src/graphql/resolvers/user.resolvers.spec.js.ejs +64 -47
  95. package/templates/mvc/js/src/graphql/typeDefs/user.types.js.ejs +19 -17
  96. package/templates/mvc/js/src/index.js.ejs +1 -1
  97. package/templates/mvc/js/src/routes/api.js +10 -8
  98. package/templates/mvc/js/src/routes/api.spec.js.ejs +41 -36
  99. package/templates/mvc/js/src/utils/errorMessages.js +14 -0
  100. package/templates/mvc/ts/src/controllers/userController.spec.ts.ejs +481 -203
  101. package/templates/mvc/ts/src/controllers/userController.ts.ejs +248 -107
  102. package/templates/mvc/ts/src/errors/BadRequestError.spec.ts.ejs +22 -21
  103. package/templates/mvc/ts/src/errors/BadRequestError.ts +9 -8
  104. package/templates/mvc/ts/src/errors/NotFoundError.spec.ts.ejs +27 -21
  105. package/templates/mvc/ts/src/errors/NotFoundError.ts +9 -8
  106. package/templates/mvc/ts/src/graphql/resolvers/user.resolvers.spec.ts.ejs +68 -51
  107. package/templates/mvc/ts/src/graphql/resolvers/user.resolvers.ts.ejs +29 -21
  108. package/templates/mvc/ts/src/graphql/typeDefs/user.types.ts.ejs +17 -15
  109. package/templates/mvc/ts/src/index.ts.ejs +156 -153
  110. package/templates/mvc/ts/src/routes/api.spec.ts.ejs +59 -40
  111. package/templates/mvc/ts/src/routes/api.ts +12 -10
  112. package/templates/mvc/ts/src/utils/errorMessages.ts +12 -0
  113. package/templates/clean-architecture/ts/src/infrastructure/repositories/UserRepository.ts.ejs +0 -37
@@ -1,263 +1,295 @@
1
- # <%= projectName %>
2
-
3
- ![Node.js](https://img.shields.io/badge/Node.js-18%2B-green.svg)
4
- ![License](https://img.shields.io/badge/License-ISC-blue.svg)
5
- <% if (language === 'TypeScript') { %>![TypeScript](https://img.shields.io/badge/Language-TypeScript-blue.svg)<% } else { %>![JavaScript](https://img.shields.io/badge/Language-JavaScript-yellow.svg)<% } %>
6
- <% if (includeSecurity) { %>
7
- [![Snyk Vulnerabilities](https://img.shields.io/snyk/vulnerabilities/github/yourusername/<%= projectName %>?style=flat-square)](https://snyk.io/)
8
- [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=<%= projectName %>&metric=alert_status)](https://sonarcloud.io/)
9
- <% } %>
10
-
11
- A production-ready Node.js microservice generated with **<%= architecture %>** and **<%= database %>**.
12
- This project comes pre-configured with industry-standard tooling for **Code Quality**, **Testing**, and **Security**.
13
-
14
- ## 🚀 Key Features
15
-
16
- - **Architecture**: <%= architecture %> (<% if (architecture === 'Clean Architecture') { %>Domain, UseCases, Infrastructure<% } else { %>MVC Pattern<% } %>).
17
- - **Database**: <%= database %> <% if (database !== 'MongoDB') { %>with **Flyway** migrations<% } else { %>with **Mongoose** schemas<% } %>.
18
- - **Security**: Helmet, CORS, Rate Limiting, HPP.
19
- - **Quality**: Eslint, Prettier, Husky, Lint-Staged.
20
- - **Testing**: Jest (Unit & Integration).
21
- - **DevOps**: Multi-stage Docker build, CI/CD ready.
22
- <% if (includeSecurity) { %>- **Enterprise Security**: Snyk SCA, SonarCloud SAST.<% } %>
23
-
24
- ## 🔄 CI/CD Pipeline
25
- <%_ if (ciProvider === 'GitHub Actions') { -%>
26
- ![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/yourusername/<%= projectName %>/ci.yml?branch=main)
27
- This project includes a **GitHub Actions** workflow located in `.github/workflows/ci.yml`.
28
- It automatically runs:
29
- - Linting
30
- - Tests
31
- - Builds
32
- <%_ } else if (ciProvider === 'GitLab CI') { -%>
33
- ![GitLab CI Status](https://img.shields.io/gitlab/pipeline/yourusername/<%= projectName %>?branch=main)
34
- This project includes a **GitLab CI** configuration in `.gitlab-ci.yml`.
35
- It automatically runs:
36
- - Linting
37
- - Tests
38
- - Builds
39
- <% } else if (ciProvider === 'Jenkins') { -%>
40
- This project includes a **Jenkinsfile** for comprehensive CI/CD.
41
- Pipeline stages:
42
- - Install Dependencies
43
- - Lint
44
- - Test
45
- <% } else { -%>
46
- CI/CD is not currently configured, but the project is ready for integration.
47
- <% } -%>
48
-
49
- ## 🛠️ Getting Started
50
-
51
- ### 1. Prerequisites
52
- - Node.js (v18+)
53
- - Docker & Docker Compose
54
-
55
- ### 2. Quick Start
56
- ```bash
57
- # Initialize Git (Mandatory for Husky hooks)
58
- git init
59
-
60
- # Install dependencies
61
- npm install
62
-
63
- # Troubleshooting Husky (if skip git init)
64
- # npx husky install
65
-
66
- # Start Infrastructure (DB, etc.)
67
- docker-compose up -d
68
-
69
- # Run Development Server
70
- docker-compose up -d<% if (database !== 'None') { %> db<% } %><% if (caching === 'Redis') { %> redis<% } %><% if (communication === 'Kafka') { %> kafka<% } %>
71
- npm run dev
72
- ```
73
-
74
- ### 3. Development Standards
75
- Ensure your code meets quality standards before committing:
76
-
77
- ```bash
78
- # Run Linter
79
- npm run lint
80
-
81
- # Run Tests
82
- npm test
83
-
84
- # Format Code
85
- npm run format
86
- ```
87
-
88
- ## 📂 Project Structure
89
-
90
- The project follows **<%= architecture %>** principles.
91
- <% if (communication === 'Kafka') { -%>
92
- Microservices communication handled via **Kafka**.
93
- <% } else if (communication === 'GraphQL') { -%>
94
- API is exposed via **GraphQL**.
95
- The Apollo Sandbox UI for API exploration and documentation is available natively, fully embedded for offline development:
96
- - **URL**: `http://localhost:3000/graphql` (Dynamic based on PORT)
97
- If you are opening `http://localhost:3000/graphql` in your browser, you can directly run the following in the Apollo Sandbox UI:
98
-
99
- **Query to get all users:**
100
- ```graphql
101
- query GetAllUsers {
102
- getAllUsers {
103
- id
104
- name
105
- email
106
- }
107
- }
108
- ```
109
-
110
- **Mutation to create a user:**
111
- ```graphql
112
- mutation CreateUser {
113
- createUser(name: "John Doe", email: "john@example.com") {
114
- id
115
- name
116
- email
117
- }
118
- }
119
- ```
120
- <% } else { -%>
121
- API is exposed via **REST**.
122
- A Swagger UI for API documentation is available at:
123
- - **URL**: `http://localhost:3000/api-docs` (Dynamic based on PORT)
124
- <%_ } -%>
125
-
126
- <% if (communication === 'Kafka') { -%>
127
- ## 📡 Testing Kafka Asynchronous Flow
128
- This project demonstrates a production-ready Kafka flow:
129
- 1. **Producer**: When a user is created via the API, a `USER_CREATED` event is sent to `user-topic`.
130
- 2. **Consumer**: `WelcomeEmailConsumer` listens to `user-topic` and simulates sending an email.
131
-
132
- ### How to verify:
133
- 1. Ensure infrastructure is running: `docker-compose up -d<% if (database !== 'None') { %> db<% } %><% if (caching === 'Redis') { %> redis<% } %><% if (communication === 'Kafka') { %> kafka<% } %>`
134
- 2. Start the app: `npm run dev`
135
- 3. Trigger an event by creating a user (via Postman or curl):
136
- ```bash
137
- curl -X POST http://localhost:3000/api/users \
138
- -H "Content-Type: application/json" \
139
- -d '{"name": "Kafka Tester", "email": "kafka@example.com"}'
140
- ```
141
- 4. Observe the logs:
142
- ```text
143
- [Kafka] Producer: Sent USER_CREATED event for 'kafka@example.com'
144
- [Kafka] Consumer: Received USER_CREATED.
145
- [Kafka] Consumer: 📧 Sending welcome email to 'kafka@example.com'... Done!
146
- ```
147
- <% } -%>
148
-
149
- <% if (caching === 'Redis') { -%>
150
- ## ⚡ Caching
151
- This project uses **Redis** for caching.
152
- - **Client**: `ioredis`
153
- - **Connection**: Configured via `REDIS_HOST`, `REDIS_PORT`, `REDIS_PASSWORD` in `.env`.
154
- <% } else if (caching === 'Memory Cache') { -%>
155
- ## Caching
156
- This project uses **Memory Cache** for in-memory caching.
157
- - **Client**: `node-cache`
158
- <% } -%>
159
-
160
- ## 📝 Logging
161
- This project uses **Winston** for structured logging.
162
- - **Development**: Logs are printed to the console.
163
- - **Production**: Logs are saved to files:
164
- - `error.log`: Only error level logs.
165
- - `combined.log`: All logs.
166
-
167
- ## 🐳 Docker Deployment
168
- This project uses a **Multi-Stage Dockerfile** for optimized production images.
169
-
170
- <% if (database !== 'None' || caching === 'Redis' || communication === 'Kafka') { -%>
171
- ### 1. Running Locally (Development)
172
- To run the Node.js application locally while using Docker for the infrastructure (Database, Redis, Kafka, etc.):
173
-
174
- ```bash
175
- # Start infrastructure
176
- docker-compose up -d<% if (database !== 'None') { %> db<% } %><% if (caching === 'Redis') { %> redis<% } %><% if (communication === 'Kafka') { %> kafka<% } %>
177
-
178
- # Start the application
179
- npm run dev
180
- ```
181
-
182
- ### 2. Running the App Container with Compose Infrastructure
183
- If you want to run the application itself inside a Docker container while connecting to the infrastructure managed by your `docker-compose.yml`:
184
-
185
- ```bash
186
- # First, ensure your infrastructure is running
187
- docker-compose up -d
188
-
189
- # Build Production Image
190
- docker build -t <%= projectName %> .
191
-
192
- # Run Container (attached to the compose network)
193
- docker run -p 3000:3000 --network <%= projectName %>_default \
194
- <% if (database !== 'None') { -%>
195
- -e DB_HOST=db \
196
- <% } -%>
197
- <% if (caching === 'Redis') { -%>
198
- -e REDIS_HOST=redis \
199
- <% } -%>
200
- <% if (communication === 'Kafka') { -%>
201
- -e KAFKA_BROKER=kafka:29092 \
202
- <% } -%>
203
- <%= projectName %>
204
- ```
205
- <% } else { -%>
206
- ```bash
207
- # Build Production Image
208
- docker build -t <%= projectName %> .
209
-
210
- # Run Container
211
- docker run -p 3000:3000 <%= projectName %>
212
- ```
213
- <% } -%>
214
-
215
- ## 🚀 PM2 Deployment (VPS/EC2)
216
- This project is pre-configured for direct deployment to a VPS/EC2 instance using **PM2** (via `ecosystem.config.js`).
217
- 1. Install dependencies
218
- ```bash
219
- npm install
220
- ```
221
- 2. **Start Infrastructure (DB, Redis, Kafka, etc.) in the background**
222
- *(This specifically starts the background services without running the application inside Docker, allowing PM2 to handle it).*
223
- ```bash
224
- docker-compose up -d<% if (database !== 'None') { %> db<% } %><% if (caching === 'Redis') { %> redis<% } %><% if (communication === 'Kafka') { %> kafka<% } %>
225
- ```
226
- 3. **Wait 5-10s** for the database to fully initialize.
227
- 4. **Deploy the App using PM2 in Cluster Mode**
228
- ```bash
229
- <% if (language === 'TypeScript') { %>npm run build
230
- <% } %>npm run deploy
231
- ```
232
- 5. **Check logs**
233
- ```bash
234
- npx pm2 logs
235
- ```
236
- 6. Stop and remove the PM2 application
237
- ```bash
238
- npx pm2 delete <%= projectName %>
239
- ```
240
- 7. Stop and remove the Docker infrastructure
241
- ```bash
242
- docker-compose down
243
- ```
244
-
245
- ## 🔒 Security Features
246
- - **Helmet**: Sets secure HTTP headers.
247
- - **CORS**: Configured for cross-origin requests.
248
- - **Rate Limiting**: Protects against DDoS / Brute-force.
249
- - **HPP**: Prevents HTTP Parameter Pollution attacks.
250
- <% if (includeSecurity) { %>
251
- ### 🛡️ Enterprise Hardening (Big Tech Standard)
252
- - **Snyk SCA**: Automated dependency vulnerability scanning.
253
- - **SonarCloud**: Deep static analysis for code quality and security hotspots.
254
- - **Security Policy**: Standard `SECURITY.md` for vulnerability reporting.
255
- <% } %>
256
- ## 🤖 AI-Native Development
257
-
258
- This project is "AI-Ready" out of the box. We have pre-configured industry-leading AI context files to bridge the gap between "Generated Code" and "AI-Assisted Development."
259
-
260
- - **Magic Defaults**: We've automatically tailored your AI context to focus on **<%= projectName %>** and its specific architectural stack (<%= architecture %>, <%= database %>, etc.).
261
- - **Use Cursor?** We've configured **`.cursorrules`** at the root. It enforces project standards (80% coverage, MVC/Clean) directly within the editor.
262
- - *Pro-tip*: You can customize the `Project Goal` placeholder in `.cursorrules` to help the AI understand your specific business logic!
263
- - **Use ChatGPT/Gemini/Claude?** Check the **`prompts/`** directory. It contains highly-specialized Agent Skill templates. You can copy-paste these into any LLM to give it a "Senior Developer" understanding of your codebase immediately.
1
+ # <%= projectName %>
2
+
3
+ ![Node.js](https://img.shields.io/badge/Node.js-18%2B-green.svg)
4
+ ![License](https://img.shields.io/badge/License-ISC-blue.svg)
5
+ <% if (language === 'TypeScript') { %>![TypeScript](https://img.shields.io/badge/Language-TypeScript-blue.svg)<% } else { %>![JavaScript](https://img.shields.io/badge/Language-JavaScript-yellow.svg)<% } %>
6
+ <% if (includeSecurity) { %>
7
+ [![Snyk Vulnerabilities](https://img.shields.io/snyk/vulnerabilities/github/yourusername/<%= projectName %>?style=flat-square)](https://snyk.io/)
8
+ [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=<%= projectName %>&metric=alert_status)](https://sonarcloud.io/)
9
+ <% } %>
10
+
11
+ A production-ready Node.js microservice generated with **<%= architecture %>** and **<%= database %>**.
12
+ This project follows a strict **7-Step Production-Ready Process** to ensure quality and scalability from day one.
13
+
14
+ ---
15
+
16
+ ## 🚀 7-Step Production-Ready Process
17
+
18
+ 1. **Initialize Git**: `git init` (Required for Husky hooks and security gates).
19
+ 2. **Install Dependencies**: `npm install`.
20
+ 3. **Configure Environment**: Copy `.env.example` to `.env`.
21
+ 4. **Start Infrastructure**: `docker-compose up -d<% if (database !== 'None') { %> db<% } %><% if (caching === 'Redis') { %> redis<% } %><% if (communication === 'Kafka') { %> kafka<% } %>`.
22
+ 5. **Run Development**: `npm run dev`.
23
+ 6. **Verify Standards**: `npm run lint` and `npm test` (Enforce 80% coverage).
24
+ 7. **Build & Deploy**: `npm run build` followed by `npm run deploy` (via PM2).
25
+
26
+ ---
27
+
28
+ ## 🚀 Key Features
29
+
30
+ - **Architecture**: <%= architecture %> (<% if (architecture === 'Clean Architecture') { %>Domain, UseCases, Infrastructure<% } else { %>MVC Pattern<% } %>).
31
+ - **Database**: <%= database %> <% if (database !== 'None') { %>(via <%= database === 'MongoDB' ? 'Mongoose' : 'Sequelize' %>)<% } %>.
32
+ - **Security**: Helmet, CORS, Rate Limiting, HPP, Snyk SCA.
33
+ - **Quality**: 80%+ Test Coverage, Eslint, Prettier, Husky.
34
+ - **DevOps**: Multi-stage Docker, CI/CD ready (GitHub/GitLab/Jenkins).
35
+ <% if (includeSecurity) { %>- **Enterprise Hardening**: SonarCloud SAST, Security Policies.<% } %>
36
+
37
+ ## 📂 Project Structure
38
+
39
+ The project follows **<%= architecture %>** principles.
40
+ <% if (architecture === 'Clean Architecture') { -%>
41
+ - **Domain**: Pure business logic (Entities/Interfaces).
42
+ - **Use Case**: Application-specific business rules.
43
+ - **Infrastructure**: External concerns (DB, Messaging, Caching).
44
+ <% } else { -%>
45
+ - **Model**: Database schemas and data logic.
46
+ - **View**: Template engines or API responders.
47
+ - **Controller**: Orchestrates flow between Model and View.
48
+ <% } -%>
49
+
50
+ ---
51
+
52
+ ## 🛠️ Detailed Getting Started
53
+
54
+ Follow the **🚀 7-Step Production-Ready Process** summary at the top, or follow these detailed instructions:
55
+
56
+ ### 1. Prerequisites
57
+ - Node.js (v18+)
58
+ - Docker & Docker Compose
59
+
60
+ ### 2. Environment Setup
61
+ Copy the example environment file and adjust the values as needed:
62
+ ```bash
63
+ cp .env.example .env
64
+ ```
65
+
66
+ ### 3. Infrastructure & App Launch
67
+ ```bash
68
+ # Initialize Git for security hooks
69
+ git init
70
+
71
+ # Install dependencies
72
+ npm install
73
+
74
+ # Start required services
75
+ docker-compose up -d<% if (database !== 'None') { %> db<% } %><% if (caching === 'Redis') { %> redis<% } %><% if (communication === 'Kafka') { %> kafka<% } %>
76
+
77
+ # Run the app in development mode
78
+ npm run dev
79
+ ```
80
+
81
+ ### 4. Quality & Standards
82
+ ```bash
83
+ # Lint & Format
84
+ npm run lint
85
+ npm run format
86
+
87
+ # Run Unit/Integration Tests
88
+ npm test
89
+ npm run test:coverage
90
+ ```
91
+
92
+ <% if (communication === 'Kafka') { -%>
93
+ Microservices communication handled via **Kafka**.
94
+ <% } else if (communication === 'GraphQL') { -%>
95
+ API is exposed via **GraphQL**.
96
+ The Apollo Sandbox UI for API exploration and documentation is available natively, fully embedded for offline development:
97
+ - **URL**: `http://localhost:3000/graphql` (Dynamic based on PORT)
98
+ If you are opening `http://localhost:3000/graphql` in your browser, you can directly run the following in the Apollo Sandbox UI:
99
+
100
+ **Query to get all users:**
101
+ ```graphql
102
+ query GetAllUsers {
103
+ getAllUsers {
104
+ id
105
+ name
106
+ email
107
+ }
108
+ }
109
+ ```
110
+
111
+ **Mutation to create a user:**
112
+ ```graphql
113
+ mutation CreateUser {
114
+ createUser(name: "John Doe", email: "john@example.com") {
115
+ id
116
+ name
117
+ email
118
+ }
119
+ }
120
+ ```
121
+
122
+ **Mutation to update a user:**
123
+ ```graphql
124
+ mutation UpdateUser {
125
+ updateUser(id: "1", name: "John Updated") {
126
+ id
127
+ name
128
+ email
129
+ }
130
+ }
131
+ ```
132
+
133
+ **Mutation to delete a user:**
134
+ ```graphql
135
+ mutation DeleteUser {
136
+ deleteUser(id: "1")
137
+ }
138
+ ```
139
+ <% } else { -%>
140
+ API is exposed via **REST**.
141
+ A Swagger UI for API documentation is available at:
142
+ - **URL**: `http://localhost:3000/api-docs` (Dynamic based on PORT)
143
+
144
+ ### 🛣️ User Endpoints:
145
+ - `GET /api/users`: List all users.
146
+ - `POST /api/users`: Create a new user.
147
+ - `PATCH /api/users/:id`: Partially update a user.
148
+ - `DELETE /api/users/:id`: Delete a user (Soft Delete).
149
+ <%_ } -%>
150
+
151
+ <% if (communication === 'Kafka') { -%>
152
+ ## 📡 Testing Kafka Asynchronous Flow
153
+ This project demonstrates a production-ready Kafka flow:
154
+ 1. **Producer**: When a user is created via the API, a `USER_CREATED` event is sent to `user-topic`.
155
+ 2. **Consumer**: `WelcomeEmailConsumer` listens to `user-topic` and simulates sending an email.
156
+
157
+ ### How to verify:
158
+ 1. Ensure infrastructure is running: `docker-compose up -d<% if (database !== 'None') { %> db<% } %><% if (caching === 'Redis') { %> redis<% } %><% if (communication === 'Kafka') { %> kafka<% } %>`
159
+ 2. Start the app: `npm run dev`
160
+ 3. Trigger an event by creating a user (via Postman or curl):
161
+ ```bash
162
+ curl -X POST http://localhost:3000/api/users \
163
+ -H "Content-Type: application/json" \
164
+ -d '{"name": "Kafka Tester", "email": "kafka@example.com"}'
165
+ ```
166
+ 4. Observe the logs:
167
+ ```text
168
+ [Kafka] Producer: Sent USER_CREATED event for 'kafka@example.com'
169
+ [Kafka] Consumer: Received USER_CREATED.
170
+ [Kafka] Consumer: 📧 Sending welcome email to 'kafka@example.com'... Done!
171
+ ```
172
+
173
+ ### 🛠️ Kafka Troubleshooting
174
+ If the connection or events are failing:
175
+ 1. **Check Docker**: Ensure Kafka container is running (`docker ps`).
176
+ 2. **Verify Broker**: `KAFKA_BROKER` in `.env` must match your host/port (standard: 9093).
177
+ 3. **Advertised Listeners**: If using Windows/WSL, check `docker-compose.yml` advertisers are correct.
178
+ 4. **Logs**: Check `docker compose logs -f kafka` for start-up errors.
179
+ <% } -%>
180
+
181
+ <% if (caching === 'Redis') { -%>
182
+ ## Caching
183
+ This project uses **Redis** for caching.
184
+ - **Client**: `ioredis`
185
+ - **Connection**: Configured via `REDIS_HOST`, `REDIS_PORT`, `REDIS_PASSWORD` in `.env`.
186
+ <% } else if (caching === 'Memory Cache') { -%>
187
+ ## Caching
188
+ This project uses **Memory Cache** for in-memory caching.
189
+ - **Client**: `node-cache`
190
+ <% } -%>
191
+
192
+ ## 📝 Logging
193
+ This project uses **Winston** for structured logging.
194
+ - **Development**: Logs are printed to the console.
195
+ - **Production**: Logs are saved to files:
196
+ - `error.log`: Only error level logs.
197
+ - `combined.log`: All logs.
198
+
199
+ ## 🐳 Docker Deployment
200
+ This project uses a **Multi-Stage Dockerfile** for optimized production images.
201
+
202
+ <% if (database !== 'None' || caching === 'Redis' || communication === 'Kafka') { -%>
203
+ ### 1. Running Locally (Development)
204
+ To run the Node.js application locally while using Docker for the infrastructure (Database, Redis, Kafka, etc.):
205
+
206
+ ```bash
207
+ # Start infrastructure
208
+ docker-compose up -d<% if (database !== 'None') { %> db<% } %><% if (caching === 'Redis') { %> redis<% } %><% if (communication === 'Kafka') { %> kafka<% } %>
209
+
210
+ # Start the application
211
+ npm run dev
212
+ ```
213
+
214
+ ### 2. Running the App Container with Compose Infrastructure
215
+ If you want to run the application itself inside a Docker container while connecting to the infrastructure managed by your `docker-compose.yml`:
216
+
217
+ ```bash
218
+ # First, ensure your infrastructure is running
219
+ docker-compose up -d
220
+
221
+ # Build Production Image
222
+ docker build -t <%= projectName %> .
223
+
224
+ # Run Container (attached to the compose network)
225
+ docker run -p 3000:3000 --network <%= projectName %>_default \
226
+ <% if (database !== 'None') { -%>
227
+ -e DB_HOST=db \
228
+ <% } -%>
229
+ <% if (caching === 'Redis') { -%>
230
+ -e REDIS_HOST=redis \
231
+ <% } -%>
232
+ <% if (communication === 'Kafka') { -%>
233
+ -e KAFKA_BROKER=kafka:29092 \
234
+ <% } -%>
235
+ <%= projectName %>
236
+ ```
237
+ <% } else { -%>
238
+ ```bash
239
+ # Build Production Image
240
+ docker build -t <%= projectName %> .
241
+
242
+ # Run Container
243
+ docker run -p 3000:3000 <%= projectName %>
244
+ ```
245
+ <% } -%>
246
+ ## 🚀 PM2 Deployment (VPS/EC2)
247
+ This project is pre-configured for direct deployment to a VPS/EC2 instance using **PM2** (via `ecosystem.config.js`).
248
+ 1. Install dependencies
249
+ ```bash
250
+ npm install
251
+ ```
252
+ 2. **Start Infrastructure (DB, Redis, Kafka, etc.) in the background**
253
+ *(This specifically starts the background services without running the application inside Docker, allowing PM2 to handle it).*
254
+ ```bash
255
+ docker-compose up -d<% if (database !== 'None') { %> db<% } %><% if (caching === 'Redis') { %> redis<% } %><% if (communication === 'Kafka') { %> kafka<% } %>
256
+ ```
257
+ 3. **Wait 5-10s** for the database to fully initialize.
258
+ 4. **Deploy the App using PM2 in Cluster Mode**
259
+ ```bash
260
+ <% if (language === 'TypeScript') { %>npm run build
261
+ <% } %>npm run deploy
262
+ ```
263
+ 5. **Check logs**
264
+ ```bash
265
+ npx pm2 logs
266
+ ```
267
+ 6. Stop and remove the PM2 application
268
+ ```bash
269
+ npx pm2 delete <%= projectName %>
270
+ ```
271
+ 7. Stop and remove the Docker infrastructure
272
+ ```bash
273
+ docker-compose down
274
+ ```
275
+
276
+ ## 🔒 Security Features
277
+ - **Helmet**: Sets secure HTTP headers.
278
+ - **CORS**: Configured for cross-origin requests.
279
+ - **Rate Limiting**: Protects against DDoS / Brute-force.
280
+ - **HPP**: Prevents HTTP Parameter Pollution attacks.
281
+ <% if (includeSecurity) { %>
282
+ ### 🛡️ Enterprise Hardening (Big Tech Standard)
283
+ - **Snyk SCA**: Run `npm run snyk:test` for dependency scanning.
284
+ - **SonarCloud**: Automated SAST on every Push/PR.
285
+ - **Digital Guardians**: Recommended Gitleaks integration for secret protection.
286
+ - **Security Policy**: Standard `SECURITY.md` for vulnerability reporting.
287
+ <% } %>
288
+ ## 🤖 AI-Native Development
289
+
290
+ This project is "AI-Ready" out of the box. We have pre-configured industry-leading AI context files to bridge the gap between "Generated Code" and "AI-Assisted Development."
291
+
292
+ - **Magic Defaults**: We've automatically tailored your AI context to focus on **<%= projectName %>** and its specific architectural stack (<%= architecture %>, <%= database %>, etc.).
293
+ - **Use Cursor?** We've configured **`.cursorrules`** at the root. It enforces project standards (80% coverage, MVC/Clean) directly within the editor.
294
+ - *Pro-tip*: You can customize the `Project Goal` placeholder in `.cursorrules` to help the AI understand your specific business logic!
295
+ - **Use ChatGPT/Gemini/Claude?** Check the **`prompts/`** directory. It contains highly-specialized Agent Skill templates. You can copy-paste these into any LLM to give it a "Senior Developer" understanding of your codebase immediately.
@@ -0,0 +1,27 @@
1
+ <%_ if (caching === 'Redis') { -%>
2
+ const cacheService = require('../infrastructure/caching/redisClient');
3
+ <%_ } else if (caching === 'Memory Cache') { -%>
4
+ const cacheService = require('../infrastructure/caching/memoryCache');
5
+ <%_ } -%>
6
+ const logger = require('../infrastructure/log/logger');
7
+
8
+ class DeleteUser {
9
+ constructor(userRepository) {
10
+ this.userRepository = userRepository;
11
+ }
12
+
13
+ async execute(id) {
14
+ const result = await this.userRepository.delete(id);
15
+
16
+ try {
17
+ await cacheService.del('users:all');
18
+ logger.info('Invalidated users:all cache');
19
+ } catch (error) {
20
+ logger.error('Cache error (del):', error);
21
+ }
22
+
23
+ return result;
24
+ }
25
+ }
26
+
27
+ module.exports = DeleteUser;
@@ -0,0 +1,27 @@
1
+ <%_ if (caching === 'Redis') { -%>
2
+ const cacheService = require('../infrastructure/caching/redisClient');
3
+ <%_ } else if (caching === 'Memory Cache') { -%>
4
+ const cacheService = require('../infrastructure/caching/memoryCache');
5
+ <%_ } -%>
6
+ const logger = require('../infrastructure/log/logger');
7
+
8
+ class UpdateUser {
9
+ constructor(userRepository) {
10
+ this.userRepository = userRepository;
11
+ }
12
+
13
+ async execute(id, data) {
14
+ const updatedUser = await this.userRepository.update(id, data);
15
+
16
+ try {
17
+ await cacheService.del('users:all');
18
+ logger.info('Invalidated users:all cache');
19
+ } catch (error) {
20
+ logger.error('Cache error (del):', error);
21
+ }
22
+
23
+ return updatedUser;
24
+ }
25
+ }
26
+
27
+ module.exports = UpdateUser;