nodejs-quickstart-structure 1.18.1 → 1.19.1

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 (235) hide show
  1. package/CHANGELOG.md +309 -294
  2. package/LICENSE +15 -15
  3. package/README.md +2 -1
  4. package/lib/generator.js +139 -139
  5. package/lib/modules/app-setup.js +401 -401
  6. package/lib/modules/caching-setup.js +76 -73
  7. package/lib/modules/config-files.js +151 -151
  8. package/lib/modules/database-setup.js +116 -116
  9. package/lib/modules/kafka-setup.js +249 -191
  10. package/lib/modules/project-setup.js +32 -31
  11. package/lib/prompts.js +100 -100
  12. package/package.json +78 -67
  13. package/templates/clean-architecture/js/src/domain/models/User.js +9 -9
  14. package/templates/clean-architecture/js/src/errors/ApiError.js +14 -14
  15. package/templates/clean-architecture/js/src/errors/BadRequestError.js +11 -10
  16. package/templates/clean-architecture/js/src/errors/BadRequestError.spec.js.ejs +22 -21
  17. package/templates/clean-architecture/js/src/errors/NotFoundError.js +11 -10
  18. package/templates/clean-architecture/js/src/errors/NotFoundError.spec.js.ejs +22 -21
  19. package/templates/clean-architecture/js/src/index.js.ejs +55 -55
  20. package/templates/clean-architecture/js/src/infrastructure/config/env.js.ejs +47 -47
  21. package/templates/clean-architecture/js/src/infrastructure/log/logger.js +36 -36
  22. package/templates/clean-architecture/js/src/infrastructure/log/logger.spec.js.ejs +63 -63
  23. package/templates/clean-architecture/js/src/infrastructure/repositories/UserRepository.js.ejs +69 -39
  24. package/templates/clean-architecture/js/src/infrastructure/repositories/UserRepository.spec.js.ejs +142 -81
  25. package/templates/clean-architecture/js/src/infrastructure/webserver/middleware/errorMiddleware.js +30 -30
  26. package/templates/clean-architecture/js/src/infrastructure/webserver/server.js.ejs +89 -89
  27. package/templates/clean-architecture/js/src/infrastructure/webserver/swagger.js.ejs +6 -6
  28. package/templates/clean-architecture/js/src/interfaces/controllers/userController.js.ejs +156 -75
  29. package/templates/clean-architecture/js/src/interfaces/controllers/userController.spec.js.ejs +234 -138
  30. package/templates/clean-architecture/js/src/interfaces/graphql/context.js.ejs +13 -13
  31. package/templates/clean-architecture/js/src/interfaces/graphql/context.spec.js.ejs +31 -31
  32. package/templates/clean-architecture/js/src/interfaces/graphql/index.js.ejs +5 -5
  33. package/templates/clean-architecture/js/src/interfaces/graphql/resolvers/index.js.ejs +6 -6
  34. package/templates/clean-architecture/js/src/interfaces/graphql/resolvers/user.resolvers.js.ejs +27 -21
  35. package/templates/clean-architecture/js/src/interfaces/graphql/resolvers/user.resolvers.spec.js.ejs +66 -49
  36. package/templates/clean-architecture/js/src/interfaces/graphql/typeDefs/index.js.ejs +6 -6
  37. package/templates/clean-architecture/js/src/interfaces/graphql/typeDefs/user.types.js.ejs +19 -17
  38. package/templates/clean-architecture/js/src/interfaces/routes/api.js +12 -10
  39. package/templates/clean-architecture/js/src/interfaces/routes/api.spec.js.ejs +38 -38
  40. package/templates/clean-architecture/js/src/usecases/CreateUser.js +14 -14
  41. package/templates/clean-architecture/js/src/usecases/CreateUser.spec.js.ejs +51 -51
  42. package/templates/clean-architecture/js/src/usecases/DeleteUser.js +11 -0
  43. package/templates/clean-architecture/js/src/usecases/DeleteUser.spec.js.ejs +47 -0
  44. package/templates/clean-architecture/js/src/usecases/GetAllUsers.js +12 -12
  45. package/templates/clean-architecture/js/src/usecases/GetAllUsers.spec.js.ejs +61 -61
  46. package/templates/clean-architecture/js/src/usecases/UpdateUser.js +11 -0
  47. package/templates/clean-architecture/js/src/usecases/UpdateUser.spec.js.ejs +48 -0
  48. package/templates/clean-architecture/js/src/utils/errorMessages.js +14 -0
  49. package/templates/clean-architecture/js/src/utils/httpCodes.js +9 -9
  50. package/templates/clean-architecture/ts/src/config/env.ts.ejs +46 -46
  51. package/templates/clean-architecture/ts/src/config/swagger.ts.ejs +6 -6
  52. package/templates/clean-architecture/ts/src/domain/user.ts +7 -7
  53. package/templates/clean-architecture/ts/src/errors/ApiError.ts +15 -15
  54. package/templates/clean-architecture/ts/src/errors/BadRequestError.spec.ts.ejs +22 -21
  55. package/templates/clean-architecture/ts/src/errors/BadRequestError.ts +9 -8
  56. package/templates/clean-architecture/ts/src/errors/NotFoundError.spec.ts.ejs +22 -21
  57. package/templates/clean-architecture/ts/src/errors/NotFoundError.ts +9 -8
  58. package/templates/clean-architecture/ts/src/index.ts.ejs +139 -139
  59. package/templates/clean-architecture/ts/src/infrastructure/log/logger.spec.ts.ejs +63 -63
  60. package/templates/clean-architecture/ts/src/infrastructure/log/logger.ts +36 -36
  61. package/templates/clean-architecture/ts/src/infrastructure/repositories/UserRepository.spec.ts.ejs +175 -85
  62. package/templates/clean-architecture/ts/src/infrastructure/repositories/userRepository.ts.ejs +74 -0
  63. package/templates/clean-architecture/ts/src/interfaces/controllers/userController.spec.ts.ejs +331 -185
  64. package/templates/clean-architecture/ts/src/interfaces/controllers/userController.ts.ejs +173 -84
  65. package/templates/clean-architecture/ts/src/interfaces/graphql/context.spec.ts.ejs +32 -32
  66. package/templates/clean-architecture/ts/src/interfaces/graphql/context.ts.ejs +17 -17
  67. package/templates/clean-architecture/ts/src/interfaces/graphql/index.ts.ejs +3 -3
  68. package/templates/clean-architecture/ts/src/interfaces/graphql/resolvers/index.ts.ejs +4 -4
  69. package/templates/clean-architecture/ts/src/interfaces/graphql/resolvers/user.resolvers.spec.ts.ejs +68 -51
  70. package/templates/clean-architecture/ts/src/interfaces/graphql/resolvers/user.resolvers.ts.ejs +29 -21
  71. package/templates/clean-architecture/ts/src/interfaces/graphql/typeDefs/index.ts.ejs +4 -4
  72. package/templates/clean-architecture/ts/src/interfaces/graphql/typeDefs/user.types.ts.ejs +17 -15
  73. package/templates/clean-architecture/ts/src/interfaces/routes/userRoutes.spec.ts.ejs +40 -40
  74. package/templates/clean-architecture/ts/src/interfaces/routes/userRoutes.ts +13 -11
  75. package/templates/clean-architecture/ts/src/usecases/createUser.spec.ts.ejs +51 -51
  76. package/templates/clean-architecture/ts/src/usecases/createUser.ts +13 -13
  77. package/templates/clean-architecture/ts/src/usecases/deleteUser.spec.ts.ejs +47 -0
  78. package/templates/clean-architecture/ts/src/usecases/deleteUser.ts +9 -0
  79. package/templates/clean-architecture/ts/src/usecases/getAllUsers.spec.ts.ejs +63 -63
  80. package/templates/clean-architecture/ts/src/usecases/getAllUsers.ts +10 -10
  81. package/templates/clean-architecture/ts/src/usecases/updateUser.spec.ts.ejs +48 -0
  82. package/templates/clean-architecture/ts/src/usecases/updateUser.ts +9 -0
  83. package/templates/clean-architecture/ts/src/utils/errorMessages.ts +12 -0
  84. package/templates/clean-architecture/ts/src/utils/errorMiddleware.ts.ejs +27 -27
  85. package/templates/clean-architecture/ts/src/utils/httpCodes.ts +7 -7
  86. package/templates/common/.cursorrules.ejs +60 -60
  87. package/templates/common/.dockerignore +12 -12
  88. package/templates/common/.env.example.ejs +41 -41
  89. package/templates/common/.gitattributes +46 -0
  90. package/templates/common/.gitlab-ci.yml.ejs +86 -86
  91. package/templates/common/.lintstagedrc +6 -6
  92. package/templates/common/.prettierrc +7 -7
  93. package/templates/common/Dockerfile +73 -73
  94. package/templates/common/Jenkinsfile.ejs +87 -87
  95. package/templates/common/README.md.ejs +294 -270
  96. package/templates/common/SECURITY.md +20 -20
  97. package/templates/common/_github/workflows/ci.yml.ejs +46 -46
  98. package/templates/common/_github/workflows/security.yml.ejs +36 -36
  99. package/templates/common/_gitignore +5 -5
  100. package/templates/common/_husky/pre-commit +4 -4
  101. package/templates/common/caching/clean/js/CreateUser.js.ejs +29 -29
  102. package/templates/common/caching/clean/js/DeleteUser.js.ejs +27 -0
  103. package/templates/common/caching/clean/js/GetAllUsers.js.ejs +37 -37
  104. package/templates/common/caching/clean/js/UpdateUser.js.ejs +27 -0
  105. package/templates/common/caching/clean/ts/createUser.ts.ejs +27 -27
  106. package/templates/common/caching/clean/ts/deleteUser.ts.ejs +24 -0
  107. package/templates/common/caching/clean/ts/getAllUsers.ts.ejs +34 -34
  108. package/templates/common/caching/clean/ts/updateUser.ts.ejs +25 -0
  109. package/templates/common/caching/js/memoryCache.js.ejs +60 -60
  110. package/templates/common/caching/js/memoryCache.spec.js.ejs +101 -101
  111. package/templates/common/caching/js/redisClient.js.ejs +75 -75
  112. package/templates/common/caching/js/redisClient.spec.js.ejs +147 -147
  113. package/templates/common/caching/ts/memoryCache.spec.ts.ejs +102 -102
  114. package/templates/common/caching/ts/memoryCache.ts.ejs +73 -64
  115. package/templates/common/caching/ts/redisClient.spec.ts.ejs +157 -157
  116. package/templates/common/caching/ts/redisClient.ts.ejs +89 -80
  117. package/templates/common/database/js/database.js.ejs +19 -19
  118. package/templates/common/database/js/database.spec.js.ejs +56 -56
  119. package/templates/common/database/js/models/User.js.ejs +79 -53
  120. package/templates/common/database/js/models/User.js.mongoose.ejs +23 -19
  121. package/templates/common/database/js/models/User.spec.js.ejs +94 -84
  122. package/templates/common/database/js/mongoose.js.ejs +33 -33
  123. package/templates/common/database/js/mongoose.spec.js.ejs +43 -43
  124. package/templates/common/database/ts/database.spec.ts.ejs +56 -56
  125. package/templates/common/database/ts/database.ts.ejs +21 -21
  126. package/templates/common/database/ts/models/User.spec.ts.ejs +100 -84
  127. package/templates/common/database/ts/models/User.ts.ejs +87 -61
  128. package/templates/common/database/ts/models/User.ts.mongoose.ejs +30 -25
  129. package/templates/common/database/ts/mongoose.spec.ts.ejs +42 -42
  130. package/templates/common/database/ts/mongoose.ts.ejs +28 -28
  131. package/templates/common/docker-compose.yml.ejs +159 -159
  132. package/templates/common/ecosystem.config.js.ejs +40 -40
  133. package/templates/common/eslint.config.mjs.ejs +77 -77
  134. package/templates/common/health/js/healthRoute.js.ejs +50 -47
  135. package/templates/common/health/js/healthRoute.spec.js.ejs +70 -70
  136. package/templates/common/health/ts/healthRoute.spec.ts.ejs +76 -76
  137. package/templates/common/health/ts/healthRoute.ts.ejs +49 -46
  138. package/templates/common/jest.config.js.ejs +32 -32
  139. package/templates/common/jest.e2e.config.js.ejs +8 -8
  140. package/templates/common/kafka/js/config/kafka.js +9 -9
  141. package/templates/common/kafka/js/config/kafka.spec.js.ejs +27 -27
  142. package/templates/common/kafka/js/messaging/baseConsumer.js.ejs +30 -30
  143. package/templates/common/kafka/js/messaging/baseConsumer.spec.js.ejs +58 -58
  144. package/templates/common/kafka/js/messaging/userEventSchema.js.ejs +12 -11
  145. package/templates/common/kafka/js/messaging/userEventSchema.spec.js.ejs +27 -27
  146. package/templates/common/kafka/js/messaging/welcomeEmailConsumer.js.ejs +44 -31
  147. package/templates/common/kafka/js/messaging/welcomeEmailConsumer.spec.js.ejs +86 -49
  148. package/templates/common/kafka/js/services/kafkaService.js.ejs +93 -93
  149. package/templates/common/kafka/js/services/kafkaService.spec.js.ejs +106 -106
  150. package/templates/common/kafka/js/utils/kafkaEvents.js.ejs +7 -0
  151. package/templates/common/kafka/ts/config/kafka.spec.ts.ejs +27 -27
  152. package/templates/common/kafka/ts/config/kafka.ts +7 -7
  153. package/templates/common/kafka/ts/messaging/baseConsumer.spec.ts.ejs +50 -50
  154. package/templates/common/kafka/ts/messaging/baseConsumer.ts.ejs +27 -27
  155. package/templates/common/kafka/ts/messaging/userEventSchema.spec.ts.ejs +51 -51
  156. package/templates/common/kafka/ts/messaging/userEventSchema.ts.ejs +12 -11
  157. package/templates/common/kafka/ts/messaging/welcomeEmailConsumer.spec.ts.ejs +86 -49
  158. package/templates/common/kafka/ts/messaging/welcomeEmailConsumer.ts.ejs +38 -25
  159. package/templates/common/kafka/ts/services/kafkaService.spec.ts.ejs +81 -81
  160. package/templates/common/kafka/ts/services/kafkaService.ts.ejs +95 -95
  161. package/templates/common/kafka/ts/utils/kafkaEvents.ts.ejs +5 -0
  162. package/templates/common/migrate-mongo-config.js.ejs +31 -31
  163. package/templates/common/migrations/init.js.ejs +23 -23
  164. package/templates/common/package.json.ejs +119 -118
  165. package/templates/common/prompts/add-feature.md.ejs +26 -26
  166. package/templates/common/prompts/project-context.md.ejs +43 -43
  167. package/templates/common/prompts/troubleshoot.md.ejs +28 -28
  168. package/templates/common/public/css/style.css +147 -147
  169. package/templates/common/scripts/run-e2e.js.ejs +63 -63
  170. package/templates/common/shutdown/js/gracefulShutdown.js.ejs +65 -61
  171. package/templates/common/shutdown/js/gracefulShutdown.spec.js.ejs +149 -160
  172. package/templates/common/shutdown/ts/gracefulShutdown.spec.ts.ejs +179 -158
  173. package/templates/common/shutdown/ts/gracefulShutdown.ts.ejs +59 -55
  174. package/templates/common/sonar-project.properties.ejs +27 -27
  175. package/templates/common/src/tests/e2e/e2e.users.test.js.ejs +120 -49
  176. package/templates/common/src/tests/e2e/e2e.users.test.ts.ejs +120 -49
  177. package/templates/common/src/utils/errorMiddleware.spec.js.ejs +79 -79
  178. package/templates/common/src/utils/errorMiddleware.spec.ts.ejs +94 -94
  179. package/templates/common/swagger.yml.ejs +118 -66
  180. package/templates/common/tsconfig.json +22 -22
  181. package/templates/common/views/ejs/index.ejs +55 -55
  182. package/templates/common/views/pug/index.pug +40 -40
  183. package/templates/db/mysql/V1__Initial_Setup.sql.ejs +10 -9
  184. package/templates/db/postgres/V1__Initial_Setup.sql.ejs +10 -9
  185. package/templates/mvc/js/src/config/env.js.ejs +46 -46
  186. package/templates/mvc/js/src/config/swagger.js.ejs +6 -6
  187. package/templates/mvc/js/src/controllers/userController.js.ejs +246 -105
  188. package/templates/mvc/js/src/controllers/userController.spec.js.ejs +481 -209
  189. package/templates/mvc/js/src/errors/ApiError.js +14 -14
  190. package/templates/mvc/js/src/errors/BadRequestError.js +11 -10
  191. package/templates/mvc/js/src/errors/BadRequestError.spec.js.ejs +22 -21
  192. package/templates/mvc/js/src/errors/NotFoundError.js +11 -10
  193. package/templates/mvc/js/src/errors/NotFoundError.spec.js.ejs +22 -21
  194. package/templates/mvc/js/src/graphql/context.js.ejs +7 -7
  195. package/templates/mvc/js/src/graphql/context.spec.js.ejs +29 -29
  196. package/templates/mvc/js/src/graphql/index.js.ejs +5 -5
  197. package/templates/mvc/js/src/graphql/resolvers/index.js.ejs +6 -6
  198. package/templates/mvc/js/src/graphql/resolvers/user.resolvers.js.ejs +25 -19
  199. package/templates/mvc/js/src/graphql/resolvers/user.resolvers.spec.js.ejs +64 -47
  200. package/templates/mvc/js/src/graphql/typeDefs/index.js.ejs +6 -6
  201. package/templates/mvc/js/src/graphql/typeDefs/user.types.js.ejs +19 -17
  202. package/templates/mvc/js/src/index.js.ejs +136 -136
  203. package/templates/mvc/js/src/routes/api.js +10 -8
  204. package/templates/mvc/js/src/routes/api.spec.js.ejs +41 -36
  205. package/templates/mvc/js/src/utils/errorMessages.js +14 -0
  206. package/templates/mvc/js/src/utils/errorMiddleware.js +29 -29
  207. package/templates/mvc/js/src/utils/httpCodes.js +9 -9
  208. package/templates/mvc/js/src/utils/logger.js +40 -40
  209. package/templates/mvc/js/src/utils/logger.spec.js.ejs +63 -63
  210. package/templates/mvc/ts/src/config/env.ts.ejs +45 -45
  211. package/templates/mvc/ts/src/config/swagger.ts.ejs +6 -6
  212. package/templates/mvc/ts/src/controllers/userController.spec.ts.ejs +481 -203
  213. package/templates/mvc/ts/src/controllers/userController.ts.ejs +248 -107
  214. package/templates/mvc/ts/src/errors/ApiError.ts +15 -15
  215. package/templates/mvc/ts/src/errors/BadRequestError.spec.ts.ejs +22 -21
  216. package/templates/mvc/ts/src/errors/BadRequestError.ts +9 -8
  217. package/templates/mvc/ts/src/errors/NotFoundError.spec.ts.ejs +27 -21
  218. package/templates/mvc/ts/src/errors/NotFoundError.ts +9 -8
  219. package/templates/mvc/ts/src/graphql/context.spec.ts.ejs +30 -30
  220. package/templates/mvc/ts/src/graphql/context.ts.ejs +12 -12
  221. package/templates/mvc/ts/src/graphql/index.ts.ejs +3 -3
  222. package/templates/mvc/ts/src/graphql/resolvers/index.ts.ejs +4 -4
  223. package/templates/mvc/ts/src/graphql/resolvers/user.resolvers.spec.ts.ejs +68 -51
  224. package/templates/mvc/ts/src/graphql/resolvers/user.resolvers.ts.ejs +29 -21
  225. package/templates/mvc/ts/src/graphql/typeDefs/index.ts.ejs +4 -4
  226. package/templates/mvc/ts/src/graphql/typeDefs/user.types.ts.ejs +17 -15
  227. package/templates/mvc/ts/src/index.ts.ejs +156 -153
  228. package/templates/mvc/ts/src/routes/api.spec.ts.ejs +59 -40
  229. package/templates/mvc/ts/src/routes/api.ts +12 -10
  230. package/templates/mvc/ts/src/utils/errorMessages.ts +12 -0
  231. package/templates/mvc/ts/src/utils/errorMiddleware.ts.ejs +27 -27
  232. package/templates/mvc/ts/src/utils/httpCodes.ts +7 -7
  233. package/templates/mvc/ts/src/utils/logger.spec.ts.ejs +63 -63
  234. package/templates/mvc/ts/src/utils/logger.ts +36 -36
  235. package/templates/clean-architecture/ts/src/infrastructure/repositories/UserRepository.ts.ejs +0 -37
@@ -1,107 +1,248 @@
1
- <% if (communication !== 'GraphQL') { -%>
2
- import { Request, Response, NextFunction } from 'express';
3
- import { HTTP_STATUS } from '@/utils/httpCodes';
4
- <% } -%>
5
- import User from '@/models/User';
6
- import logger from '@/utils/logger';
7
- <%_ if (caching === 'Redis') { -%>
8
- import cacheService from '@/config/redisClient';
9
- <%_ } else if (caching === 'Memory Cache') { -%>
10
- import cacheService from '@/config/memoryCache';
11
- <%_ } -%><%_ if (communication === 'Kafka') { -%>
12
- import { kafkaService } from '@/services/kafkaService';
13
- <%_ } -%>
14
-
15
- export class UserController {
16
- <% if (communication === 'GraphQL') { -%>
17
- async getUsers() {
18
- try {
19
- <%_ if (caching === 'Redis' || caching === 'Memory Cache') { -%>
20
- const users = await cacheService.getOrSet('users:all', async () => {
21
- <%_ if (database === 'MongoDB' || database === 'None') { -%>
22
- return await User.find();
23
- <%_ } else { -%>
24
- return await User.findAll();
25
- <%_ } -%>
26
- }, 60);
27
- <%_ } else { -%>
28
- <%_ if (database === 'MongoDB' || database === 'None') { -%>
29
- const users = await User.find();
30
- <%_ } else { -%>
31
- const users = await User.findAll();
32
- <%_ } -%>
33
- <%_ } -%>
34
- return users;
35
- } catch (error) {
36
- logger.error('Error fetching users:', error);
37
- throw error;
38
- }
39
- }
40
-
41
- async createUser(data: { name: string, email: string }) {
42
- try {
43
- const { name, email } = data;
44
- const user = await User.create({ name, email });
45
- <%_ if (caching === 'Redis' || caching === 'Memory Cache') { -%>
46
- await cacheService.del('users:all');
47
- <%_ } -%>
48
- <%_ if (communication === 'Kafka') { -%>
49
- await kafkaService.sendMessage('user-topic', JSON.stringify({
50
- action: 'USER_CREATED',
51
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
52
- payload: { id: (user as any).id || (user as any)._id, email: user.email }
53
- }));
54
- <%_ } -%>
55
- return user;
56
- } catch (error) {
57
- logger.error('Error creating user:', error);
58
- throw error;
59
- }
60
- }
61
- <% } else { -%>
62
- async getUsers(req: Request, res: Response, next: NextFunction) {
63
- try {
64
- <%_ if (caching === 'Redis' || caching === 'Memory Cache') { -%>
65
- const users = await cacheService.getOrSet('users:all', async () => {
66
- <%_ if (database === 'MongoDB' || database === 'None') { -%>
67
- return await User.find();
68
- <%_ } else { -%>
69
- return await User.findAll();
70
- <%_ } -%>
71
- }, 60);
72
- <%_ } else { -%>
73
- <%_ if (database === 'MongoDB' || database === 'None') { -%>
74
- const users = await User.find();
75
- <%_ } else { -%>
76
- const users = await User.findAll();
77
- <%_ } -%>
78
- <%_ } -%>
79
- res.json(users);
80
- } catch (error) {
81
- logger.error('Error fetching user:', error);
82
- next(error);
83
- }
84
- }
85
-
86
- async createUser(req: Request, res: Response, next: NextFunction) {
87
- try {
88
- const { name, email } = req.body;
89
- const user = await User.create({ name, email });
90
- <%_ if (caching === 'Redis' || caching === 'Memory Cache') { -%>
91
- await cacheService.del('users:all');
92
- <%_ } -%>
93
- <%_ if (communication === 'Kafka') { -%>
94
- await kafkaService.sendMessage('user-topic', JSON.stringify({
95
- action: 'USER_CREATED',
96
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
97
- payload: { id: (user as any).id || (user as any)._id, email: user.email }
98
- }));
99
- <%_ } -%>
100
- res.status(HTTP_STATUS.CREATED).json(user);
101
- } catch (error) {
102
- logger.error('Error creating user:', error);
103
- next(error);
104
- }
105
- }
106
- <% } -%>
107
- }
1
+ import { ERROR_MESSAGES } from '@/utils/errorMessages';
2
+ <% if (communication !== 'GraphQL') { -%>
3
+ import { Request, Response, NextFunction } from 'express';
4
+ import { HTTP_STATUS } from '@/utils/httpCodes';
5
+ <% } -%>
6
+ import User from '@/models/User';
7
+ import logger from '@/utils/logger';
8
+ <%_ if (caching === 'Redis') { -%>
9
+ import cacheService from '@/config/redisClient';
10
+ <%_ } else if (caching === 'Memory Cache') { -%>
11
+ import cacheService from '@/config/memoryCache';
12
+ <%_ } -%><%_ if (communication === 'Kafka') { -%>
13
+ import { kafkaService } from '@/services/kafkaService';
14
+ import { KAFKA_ACTIONS } from '@/utils/kafkaEvents';
15
+ <%_ } -%>
16
+
17
+ export class UserController {
18
+ <% if (communication === 'GraphQL') { -%>
19
+ async getUsers() {
20
+ try {
21
+ <%_ if (caching === 'Redis' || caching === 'Memory Cache') { -%>
22
+ const users = await cacheService.getOrSet('users:all', async () => {
23
+ <%_ if (database === 'MongoDB' || database === 'None') { -%>
24
+ return await User.find();
25
+ <%_ } else { -%>
26
+ return await User.findAll();
27
+ <%_ } -%>
28
+ }, 60);
29
+ <%_ } else { -%>
30
+ <%_ if (database === 'MongoDB' || database === 'None') { -%>
31
+ const users = await User.find();
32
+ <%_ } else { -%>
33
+ const users = await User.findAll();
34
+ <%_ } -%>
35
+ <%_ } -%>
36
+ return users;
37
+ } catch (error) {
38
+ logger.error(`${ERROR_MESSAGES.FETCH_USERS_ERROR}:`, error);
39
+ throw error;
40
+ }
41
+ }
42
+
43
+ async createUser(data: { name: string, email: string }) {
44
+ try {
45
+ const { name, email } = data;
46
+ const user = await User.create({ name, email });
47
+ <%_ if (caching === 'Redis' || caching === 'Memory Cache') { -%>
48
+ await cacheService.del('users:all');
49
+ <%_ } -%>
50
+ <%_ if (communication === 'Kafka') { -%>
51
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
52
+ const userId = (user as any).id || (user as any)._id;
53
+ await kafkaService.sendMessage('user-topic', JSON.stringify({
54
+ action: KAFKA_ACTIONS.USER_CREATED,
55
+ payload: { id: userId, email: user.email }
56
+ }), userId?.toString() || '');
57
+ <%_ } -%>
58
+ return user;
59
+ } catch (error) {
60
+ logger.error(`${ERROR_MESSAGES.CREATE_USER_ERROR}:`, error);
61
+ throw error;
62
+ }
63
+ }
64
+
65
+ async updateUser(id: string, data: { name?: string, email?: string }) {
66
+ try {
67
+ <%_ if (database === 'MongoDB') { -%>
68
+ const updatedUser = await User.findByIdAndUpdate(id, data, { new: true });
69
+ if (!updatedUser) throw new Error(ERROR_MESSAGES.USER_NOT_FOUND);
70
+ <%_ } else if (database === 'None') { -%>
71
+ const user = await User.findByPk(id);
72
+ if (!user) throw new Error(ERROR_MESSAGES.USER_NOT_FOUND);
73
+ await User.update(id, data);
74
+ const updatedUser = await User.findByPk(id);
75
+ <%_ } else { -%>
76
+ const user = await User.findByPk(id);
77
+ if (!user) throw new Error(ERROR_MESSAGES.USER_NOT_FOUND);
78
+ await user.update(data);
79
+ const updatedUser = user;
80
+ <%_ } -%>
81
+ <%_ if (caching === 'Redis' || caching === 'Memory Cache') { -%>
82
+ await cacheService.del('users:all');
83
+ <%_ } -%>
84
+ <%_ if (communication === 'Kafka') { -%>
85
+ await kafkaService.sendMessage('user-topic', JSON.stringify({
86
+ action: KAFKA_ACTIONS.USER_UPDATED,
87
+ payload: { id, email: updatedUser?.email }
88
+ }), id);
89
+ <%_ } -%>
90
+ return updatedUser;
91
+ } catch (error) {
92
+ logger.error(`${ERROR_MESSAGES.UPDATE_USER_ERROR}:`, error);
93
+ throw error;
94
+ }
95
+ }
96
+
97
+ async deleteUser(id: string) {
98
+ try {
99
+ <%_ if (database === 'MongoDB') { -%>
100
+ const deleted = await User.findByIdAndDelete(id);
101
+ if (!deleted) throw new Error(ERROR_MESSAGES.USER_NOT_FOUND);
102
+ <%_ } else if (database === 'None') { -%>
103
+ const deleted = await User.destroy(id);
104
+ if (!deleted) throw new Error(ERROR_MESSAGES.USER_NOT_FOUND);
105
+ <%_ } else { -%>
106
+ const user = await User.findByPk(id);
107
+ if (!user) throw new Error(ERROR_MESSAGES.USER_NOT_FOUND);
108
+ await user.destroy();
109
+ <%_ } -%>
110
+ <%_ if (caching === 'Redis' || caching === 'Memory Cache') { -%>
111
+ await cacheService.del('users:all');
112
+ <%_ } -%>
113
+ <%_ if (communication === 'Kafka') { -%>
114
+ await kafkaService.sendMessage('user-topic', JSON.stringify({
115
+ action: KAFKA_ACTIONS.USER_DELETED,
116
+ payload: { id }
117
+ }), id);
118
+ <%_ } -%>
119
+ return true;
120
+ } catch (error) {
121
+ logger.error(`${ERROR_MESSAGES.DELETE_USER_ERROR}:`, error);
122
+ throw error;
123
+ }
124
+ }
125
+ <% } else { -%>
126
+ async getUsers(req: Request, res: Response, next: NextFunction) {
127
+ try {
128
+ <%_ if (caching === 'Redis' || caching === 'Memory Cache') { -%>
129
+ const users = await cacheService.getOrSet('users:all', async () => {
130
+ <%_ if (database === 'MongoDB' || database === 'None') { -%>
131
+ return await User.find();
132
+ <%_ } else { -%>
133
+ return await User.findAll();
134
+ <%_ } -%>
135
+ }, 60);
136
+ <%_ } else { -%>
137
+ <%_ if (database === 'MongoDB' || database === 'None') { -%>
138
+ const users = await User.find();
139
+ <%_ } else { -%>
140
+ const users = await User.findAll();
141
+ <%_ } -%>
142
+ <%_ } -%>
143
+ res.json(users);
144
+ } catch (error) {
145
+ logger.error(`${ERROR_MESSAGES.FETCH_USERS_ERROR}:`, error);
146
+ next(error);
147
+ }
148
+ }
149
+
150
+ async createUser(req: Request, res: Response, next: NextFunction) {
151
+ try {
152
+ const { name, email } = req.body || {};
153
+ const user = await User.create({ name, email });
154
+ <%_ if (caching === 'Redis' || caching === 'Memory Cache') { -%>
155
+ await cacheService.del('users:all');
156
+ <%_ } -%>
157
+ <%_ if (communication === 'Kafka') { -%>
158
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
159
+ const userId = (user as any).id || (user as any)._id;
160
+ await kafkaService.sendMessage('user-topic', JSON.stringify({
161
+ action: KAFKA_ACTIONS.USER_CREATED,
162
+ payload: { id: userId, email: user.email }
163
+ }), userId?.toString() || '');
164
+ <%_ } -%>
165
+ res.status(HTTP_STATUS.CREATED).json(user);
166
+ } catch (error) {
167
+ logger.error('Error creating user:', error);
168
+ next(error);
169
+ }
170
+ }
171
+
172
+ async updateUser(req: Request, res: Response, next: NextFunction) {
173
+ try {
174
+ const { id } = req.params;
175
+ const { name, email } = req.body || {};
176
+ <%_ if (database === 'MongoDB') { -%>
177
+ const updatedUser = await User.findByIdAndUpdate(id, { name, email }, { new: true });
178
+ if (!updatedUser) {
179
+ return res.status(HTTP_STATUS.NOT_FOUND).json({ error: ERROR_MESSAGES.USER_NOT_FOUND });
180
+ }
181
+ <%_ } else if (database === 'None') { -%>
182
+ const user = await User.findByPk(id);
183
+ if (!user) {
184
+ return res.status(HTTP_STATUS.NOT_FOUND).json({ error: ERROR_MESSAGES.USER_NOT_FOUND });
185
+ }
186
+ await User.update(id, { name, email });
187
+ const updatedUser = await User.findByPk(id);
188
+ <%_ } else { -%>
189
+ const user = await User.findByPk(id);
190
+ if (!user) {
191
+ return res.status(HTTP_STATUS.NOT_FOUND).json({ error: ERROR_MESSAGES.USER_NOT_FOUND });
192
+ }
193
+ await user.update({ name, email });
194
+ const updatedUser = user;
195
+ <%_ } -%>
196
+ <%_ if (caching === 'Redis' || caching === 'Memory Cache') { -%>
197
+ await cacheService.del('users:all');
198
+ <%_ } -%>
199
+ <%_ if (communication === 'Kafka') { -%>
200
+ await kafkaService.sendMessage('user-topic', JSON.stringify({
201
+ action: KAFKA_ACTIONS.USER_UPDATED,
202
+ payload: { id, email: updatedUser?.email }
203
+ }), id);
204
+ <%_ } -%>
205
+ res.status(HTTP_STATUS.OK).json(updatedUser);
206
+ } catch (error) {
207
+ logger.error(`${ERROR_MESSAGES.UPDATE_USER_ERROR}:`, error);
208
+ next(error);
209
+ }
210
+ }
211
+
212
+ async deleteUser(req: Request, res: Response, next: NextFunction) {
213
+ try {
214
+ const { id } = req.params;
215
+ <%_ if (database === 'MongoDB') { -%>
216
+ const deleted = await User.findByIdAndDelete(id);
217
+ if (!deleted) {
218
+ return res.status(HTTP_STATUS.NOT_FOUND).json({ error: ERROR_MESSAGES.USER_NOT_FOUND });
219
+ }
220
+ <%_ } else if (database === 'None') { -%>
221
+ const deleted = await User.destroy(id);
222
+ if (!deleted) {
223
+ return res.status(HTTP_STATUS.NOT_FOUND).json({ error: ERROR_MESSAGES.USER_NOT_FOUND });
224
+ }
225
+ <%_ } else { -%>
226
+ const user = await User.findByPk(id);
227
+ if (!user) {
228
+ return res.status(HTTP_STATUS.NOT_FOUND).json({ error: ERROR_MESSAGES.USER_NOT_FOUND });
229
+ }
230
+ await user.destroy();
231
+ <%_ } -%>
232
+ <%_ if (caching === 'Redis' || caching === 'Memory Cache') { -%>
233
+ await cacheService.del('users:all');
234
+ <%_ } -%>
235
+ <%_ if (communication === 'Kafka') { -%>
236
+ await kafkaService.sendMessage('user-topic', JSON.stringify({
237
+ action: KAFKA_ACTIONS.USER_DELETED,
238
+ payload: { id }
239
+ }), id);
240
+ <%_ } -%>
241
+ res.status(HTTP_STATUS.OK).json({ message: 'User deleted successfully' });
242
+ } catch (error) {
243
+ logger.error(`${ERROR_MESSAGES.DELETE_USER_ERROR}:`, error);
244
+ next(error);
245
+ }
246
+ }
247
+ <% } -%>
248
+ }
@@ -1,15 +1,15 @@
1
- export class ApiError extends Error {
2
- statusCode: number;
3
- isOperational: boolean;
4
-
5
- constructor(statusCode: number, message: string, isOperational = true, stack = '') {
6
- super(message);
7
- this.statusCode = statusCode;
8
- this.isOperational = isOperational;
9
- if (stack) {
10
- this.stack = stack;
11
- } else {
12
- Error.captureStackTrace(this, this.constructor);
13
- }
14
- }
15
- }
1
+ export class ApiError extends Error {
2
+ statusCode: number;
3
+ isOperational: boolean;
4
+
5
+ constructor(statusCode: number, message: string, isOperational = true, stack = '') {
6
+ super(message);
7
+ this.statusCode = statusCode;
8
+ this.isOperational = isOperational;
9
+ if (stack) {
10
+ this.stack = stack;
11
+ } else {
12
+ Error.captureStackTrace(this, this.constructor);
13
+ }
14
+ }
15
+ }
@@ -1,21 +1,22 @@
1
- import { BadRequestError } from '@/errors/BadRequestError';
2
- import { ApiError } from '@/errors/ApiError';
3
- import { HTTP_STATUS } from '@/utils/httpCodes';
4
-
5
- describe('BadRequestError', () => {
6
- it('should extend ApiError', () => {
7
- const error = new BadRequestError();
8
- expect(error).toBeInstanceOf(ApiError);
9
- });
10
-
11
- it('should have default message "Bad request"', () => {
12
- const error = new BadRequestError();
13
- expect(error.message).toBe('Bad request');
14
- expect(error.statusCode).toBe(HTTP_STATUS.BAD_REQUEST);
15
- });
16
-
17
- it('should accept a custom message', () => {
18
- const error = new BadRequestError('Custom bad request');
19
- expect(error.message).toBe('Custom bad request');
20
- });
21
- });
1
+ import { BadRequestError } from '@/errors/BadRequestError';
2
+ import { ApiError } from '@/errors/ApiError';
3
+ import { HTTP_STATUS } from '@/utils/httpCodes';
4
+ import { ERROR_MESSAGES } from '@/utils/errorMessages';
5
+
6
+ describe('BadRequestError', () => {
7
+ it('should extend ApiError', () => {
8
+ const error = new BadRequestError();
9
+ expect(error).toBeInstanceOf(ApiError);
10
+ });
11
+
12
+ it('should have default message "Bad Request"', () => {
13
+ const error = new BadRequestError();
14
+ expect(error.message).toBe(ERROR_MESSAGES.BAD_REQUEST);
15
+ expect(error.statusCode).toBe(HTTP_STATUS.BAD_REQUEST);
16
+ });
17
+
18
+ it('should accept a custom message', () => {
19
+ const error = new BadRequestError('Custom bad request');
20
+ expect(error.message).toBe('Custom bad request');
21
+ });
22
+ });
@@ -1,8 +1,9 @@
1
- import { ApiError } from '@/errors/ApiError';
2
- import { HTTP_STATUS } from '@/utils/httpCodes';
3
-
4
- export class BadRequestError extends ApiError {
5
- constructor(message = 'Bad request') {
6
- super(HTTP_STATUS.BAD_REQUEST, message);
7
- }
8
- }
1
+ import { ApiError } from '@/errors/ApiError';
2
+ import { HTTP_STATUS } from '@/utils/httpCodes';
3
+ import { ERROR_MESSAGES } from '@/utils/errorMessages';
4
+
5
+ export class BadRequestError extends ApiError {
6
+ constructor(message: string = ERROR_MESSAGES.BAD_REQUEST) {
7
+ super(HTTP_STATUS.BAD_REQUEST, message);
8
+ }
9
+ }
@@ -1,21 +1,27 @@
1
- import { NotFoundError } from '@/errors/NotFoundError';
2
- import { ApiError } from '@/errors/ApiError';
3
- import { HTTP_STATUS } from '@/utils/httpCodes';
4
-
5
- describe('NotFoundError', () => {
6
- it('should extend ApiError', () => {
7
- const error = new NotFoundError();
8
- expect(error).toBeInstanceOf(ApiError);
9
- });
10
-
11
- it('should have default message "Resource not found"', () => {
12
- const error = new NotFoundError();
13
- expect(error.message).toBe('Resource not found');
14
- expect(error.statusCode).toBe(HTTP_STATUS.NOT_FOUND);
15
- });
16
-
17
- it('should accept a custom message', () => {
18
- const error = new NotFoundError('User not found');
19
- expect(error.message).toBe('User not found');
20
- });
21
- });
1
+ import { NotFoundError } from '@/errors/NotFoundError';
2
+ import { ApiError } from '@/errors/ApiError';
3
+ import { HTTP_STATUS } from '@/utils/httpCodes';
4
+ import { ERROR_MESSAGES } from '@/utils/errorMessages';
5
+
6
+ describe('NotFoundError', () => {
7
+ it('should extend ApiError', () => {
8
+ const error = new NotFoundError();
9
+ expect(error).toBeInstanceOf(ApiError);
10
+ });
11
+
12
+ it('should have default message "Resource not found"', () => {
13
+ const error = new NotFoundError();
14
+ expect(error.message).toBe(ERROR_MESSAGES.RESOURCE_NOT_FOUND);
15
+ expect(error.statusCode).toBe(HTTP_STATUS.NOT_FOUND);
16
+ });
17
+
18
+ it('should accept a custom message', () => {
19
+ const error = new NotFoundError(ERROR_MESSAGES.USER_NOT_FOUND);
20
+ expect(error.message).toBe(ERROR_MESSAGES.USER_NOT_FOUND);
21
+ });
22
+
23
+ it('should have the correct status code', () => {
24
+ const error = new NotFoundError();
25
+ expect(error.statusCode).toBe(HTTP_STATUS.NOT_FOUND);
26
+ });
27
+ });
@@ -1,8 +1,9 @@
1
- import { ApiError } from '@/errors/ApiError';
2
- import { HTTP_STATUS } from '@/utils/httpCodes';
3
-
4
- export class NotFoundError extends ApiError {
5
- constructor(message = 'Resource not found') {
6
- super(HTTP_STATUS.NOT_FOUND, message);
7
- }
8
- }
1
+ import { ApiError } from '@/errors/ApiError';
2
+ import { HTTP_STATUS } from '@/utils/httpCodes';
3
+ import { ERROR_MESSAGES } from '@/utils/errorMessages';
4
+
5
+ export class NotFoundError extends ApiError {
6
+ constructor(message: string = ERROR_MESSAGES.RESOURCE_NOT_FOUND) {
7
+ super(HTTP_STATUS.NOT_FOUND, message);
8
+ }
9
+ }
@@ -1,30 +1,30 @@
1
- import { gqlContext } from '@/graphql/context';
2
- import { Request } from 'express';
3
- import { resolvers } from '@/graphql/resolvers';
4
- import { typeDefs } from '@/graphql/typeDefs';
5
-
6
- describe('GraphQL Context', () => {
7
- it('should exercise GraphQL index entry points', () => {
8
- expect(resolvers).toBeDefined();
9
- expect(typeDefs).toBeDefined();
10
- });
11
- it('should return context with token when authorization header is present', async () => {
12
- const mockRequest = {
13
- headers: {
14
- authorization: 'Bearer token123',
15
- },
16
- } as Request;
17
-
18
- const context = await gqlContext({ req: mockRequest });
19
- expect(context).toEqual({ token: 'Bearer token123' });
20
- });
21
-
22
- it('should return context with empty token when authorization header is missing', async () => {
23
- const mockRequest = {
24
- headers: {},
25
- } as Request;
26
-
27
- const context = await gqlContext({ req: mockRequest });
28
- expect(context).toEqual({ token: '' });
29
- });
30
- });
1
+ import { gqlContext } from '@/graphql/context';
2
+ import { Request } from 'express';
3
+ import { resolvers } from '@/graphql/resolvers';
4
+ import { typeDefs } from '@/graphql/typeDefs';
5
+
6
+ describe('GraphQL Context', () => {
7
+ it('should exercise GraphQL index entry points', () => {
8
+ expect(resolvers).toBeDefined();
9
+ expect(typeDefs).toBeDefined();
10
+ });
11
+ it('should return context with token when authorization header is present', async () => {
12
+ const mockRequest = {
13
+ headers: {
14
+ authorization: 'Bearer token123',
15
+ },
16
+ } as Request;
17
+
18
+ const context = await gqlContext({ req: mockRequest });
19
+ expect(context).toEqual({ token: 'Bearer token123' });
20
+ });
21
+
22
+ it('should return context with empty token when authorization header is missing', async () => {
23
+ const mockRequest = {
24
+ headers: {},
25
+ } as Request;
26
+
27
+ const context = await gqlContext({ req: mockRequest });
28
+ expect(context).toEqual({ token: '' });
29
+ });
30
+ });
@@ -1,12 +1,12 @@
1
- import { Request } from 'express';
2
-
3
- export interface MyContext {
4
- token?: string;
5
- // user?: User;
6
- }
7
-
8
- export const gqlContext = async ({ req }: { req: Request }): Promise<MyContext> => {
9
- // Setup authorization or context here
10
- const token = req.headers.authorization || '';
11
- return { token };
12
- };
1
+ import { Request } from 'express';
2
+
3
+ export interface MyContext {
4
+ token?: string;
5
+ // user?: User;
6
+ }
7
+
8
+ export const gqlContext = async ({ req }: { req: Request }): Promise<MyContext> => {
9
+ // Setup authorization or context here
10
+ const token = req.headers.authorization || '';
11
+ return { token };
12
+ };
@@ -1,3 +1,3 @@
1
- export { typeDefs } from '@/graphql/typeDefs';
2
- export { resolvers } from '@/graphql/resolvers';
3
- export { gqlContext, MyContext } from '@/graphql/context';
1
+ export { typeDefs } from '@/graphql/typeDefs';
2
+ export { resolvers } from '@/graphql/resolvers';
3
+ export { gqlContext, MyContext } from '@/graphql/context';
@@ -1,4 +1,4 @@
1
- import { mergeResolvers } from '@graphql-tools/merge';
2
- import { userResolvers } from '@/graphql/resolvers/user.resolvers';
3
-
4
- export const resolvers = mergeResolvers([userResolvers]);
1
+ import { mergeResolvers } from '@graphql-tools/merge';
2
+ import { userResolvers } from '@/graphql/resolvers/user.resolvers';
3
+
4
+ export const resolvers = mergeResolvers([userResolvers]);