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,40 +1,40 @@
1
- import request from 'supertest';
2
- import express, { Express } from 'express';
3
- import router from '@/interfaces/routes/userRoutes';
4
-
5
- const mockGetUsers = jest.fn().mockImplementation((req, res) => res.status(200).json([{ id: '1', name: 'John Doe' }]));
6
- const mockCreateUser = jest.fn().mockImplementation((req, res) => res.status(201).json({ id: '1', name: 'Test' }));
7
-
8
- jest.mock('@/interfaces/controllers/userController', () => {
9
- return {
10
- UserController: jest.fn().mockImplementation(() => ({
11
- getUsers: (...args: unknown[]) => mockGetUsers(...args),
12
- createUser: (...args: unknown[]) => mockCreateUser(...args)
13
- }))
14
- };
15
- });
16
-
17
- describe('UserRoutes', () => {
18
- let app: Express;
19
-
20
- beforeEach(() => {
21
- app = express();
22
- app.use(express.json());
23
- app.use('/users', router);
24
- });
25
-
26
- it('POST /users should call controller.createUser', async () => {
27
- await request(app)
28
- .post('/users')
29
- .send({ name: 'Test', email: 'test@example.com' });
30
-
31
- expect(mockCreateUser).toHaveBeenCalledTimes(1);
32
- });
33
-
34
- it('GET /users should call controller.getUsers', async () => {
35
- await request(app)
36
- .get('/users');
37
-
38
- expect(mockGetUsers).toHaveBeenCalledTimes(1);
39
- });
40
- });
1
+ import request from 'supertest';
2
+ import express, { Express } from 'express';
3
+ import router from '@/interfaces/routes/userRoutes';
4
+
5
+ const mockGetUsers = jest.fn().mockImplementation((req, res) => res.status(200).json([{ id: '1', name: 'John Doe' }]));
6
+ const mockCreateUser = jest.fn().mockImplementation((req, res) => res.status(201).json({ id: '1', name: 'Test' }));
7
+
8
+ jest.mock('@/interfaces/controllers/userController', () => {
9
+ return {
10
+ UserController: jest.fn().mockImplementation(() => ({
11
+ getUsers: (...args: unknown[]) => mockGetUsers(...args),
12
+ createUser: (...args: unknown[]) => mockCreateUser(...args)
13
+ }))
14
+ };
15
+ });
16
+
17
+ describe('UserRoutes', () => {
18
+ let app: Express;
19
+
20
+ beforeEach(() => {
21
+ app = express();
22
+ app.use(express.json());
23
+ app.use('/users', router);
24
+ });
25
+
26
+ it('POST /users should call controller.createUser', async () => {
27
+ await request(app)
28
+ .post('/users')
29
+ .send({ name: 'Test', email: 'test@example.com' });
30
+
31
+ expect(mockCreateUser).toHaveBeenCalledTimes(1);
32
+ });
33
+
34
+ it('GET /users should call controller.getUsers', async () => {
35
+ await request(app)
36
+ .get('/users');
37
+
38
+ expect(mockGetUsers).toHaveBeenCalledTimes(1);
39
+ });
40
+ });
@@ -1,11 +1,13 @@
1
- import { Router, Request, Response, NextFunction } from 'express';
2
- import { UserController } from '@/interfaces/controllers/userController';
3
-
4
- const router = Router();
5
- const userController = new UserController();
6
-
7
- router.post('/', (req: Request, res: Response, next: NextFunction) => userController.createUser(req, res, next));
8
- router.get('/', (req: Request, res: Response, next: NextFunction) => userController.getUsers(req, res, next));
9
-
10
- export default router;
11
-
1
+ import { Router, Request, Response, NextFunction } from 'express';
2
+ import { UserController } from '@/interfaces/controllers/userController';
3
+
4
+ const router = Router();
5
+ const userController = new UserController();
6
+
7
+ router.post('/', (req: Request, res: Response, next: NextFunction) => userController.createUser(req, res, next));
8
+ router.get('/', (req: Request, res: Response, next: NextFunction) => userController.getUsers(req, res, next));
9
+ router.patch('/:id', (req: Request, res: Response, next: NextFunction) => userController.updateUser(req, res, next));
10
+ router.delete('/:id', (req: Request, res: Response, next: NextFunction) => userController.deleteUser(req, res, next));
11
+
12
+ export default router;
13
+
@@ -1,51 +1,51 @@
1
- import CreateUser from '@/usecases/createUser';
2
- import { UserRepository } from '@/infrastructure/repositories/UserRepository';
3
- <%_ if (caching !== 'None') { -%>
4
- import cacheService from '<% if (caching === "Redis") { %>@/infrastructure/caching/redisClient<% } else { %>@/infrastructure/caching/memoryCache<% } %>';
5
- <%_ } -%>
6
-
7
- jest.mock('@/infrastructure/repositories/UserRepository');
8
- <%_ if (caching !== 'None') { -%>
9
- jest.mock('<% if (caching === "Redis") { %>@/infrastructure/caching/redisClient<% } else { %>@/infrastructure/caching/memoryCache<% } %>', () => ({
10
- get: jest.fn(),
11
- set: jest.fn(),
12
- del: jest.fn()
13
- }));
14
- <%_ } -%>
15
-
16
- describe('CreateUser UseCase', () => {
17
- let createUser: CreateUser;
18
- let mockUserRepository: jest.Mocked<UserRepository>;
19
-
20
- beforeEach(() => {
21
- mockUserRepository = new UserRepository() as jest.Mocked<UserRepository>;
22
- createUser = new CreateUser(mockUserRepository);
23
- jest.clearAllMocks();
24
- });
25
-
26
- it('should create and save a new user', async () => {
27
- const name = 'Test User';
28
- const email = 'test@example.com';
29
- const expectedResult = { id: 1, name, email };
30
-
31
- mockUserRepository.save.mockResolvedValue(expectedResult as any);
32
-
33
- const result = await createUser.execute(name, email);
34
-
35
- expect(mockUserRepository.save).toHaveBeenCalledTimes(1);
36
- const savedUser = mockUserRepository.save.mock.calls[0][0];
37
- expect(savedUser.name).toBe(name);
38
- expect(savedUser.email).toBe(email);
39
- expect(result).toEqual(expectedResult);
40
- <%_ if (caching !== 'None') { -%>
41
- expect(cacheService.del).toHaveBeenCalledWith('users:all');
42
- <%_ } %>
43
- });
44
-
45
- it('should throw an error if repository fails', async () => {
46
- const error = new Error('Database error');
47
- mockUserRepository.save.mockRejectedValue(error);
48
-
49
- await expect(createUser.execute('Test', 'test@test.com')).rejects.toThrow(error);
50
- });
51
- });
1
+ import CreateUser from '@/usecases/createUser';
2
+ import { UserRepository } from '@/infrastructure/repositories/UserRepository';
3
+ <%_ if (caching !== 'None') { -%>
4
+ import cacheService from '<% if (caching === "Redis") { %>@/infrastructure/caching/redisClient<% } else { %>@/infrastructure/caching/memoryCache<% } %>';
5
+ <%_ } -%>
6
+
7
+ jest.mock('@/infrastructure/repositories/UserRepository');
8
+ <%_ if (caching !== 'None') { -%>
9
+ jest.mock('<% if (caching === "Redis") { %>@/infrastructure/caching/redisClient<% } else { %>@/infrastructure/caching/memoryCache<% } %>', () => ({
10
+ get: jest.fn(),
11
+ set: jest.fn(),
12
+ del: jest.fn()
13
+ }));
14
+ <%_ } -%>
15
+
16
+ describe('CreateUser UseCase', () => {
17
+ let createUser: CreateUser;
18
+ let mockUserRepository: jest.Mocked<UserRepository>;
19
+
20
+ beforeEach(() => {
21
+ mockUserRepository = new UserRepository() as jest.Mocked<UserRepository>;
22
+ createUser = new CreateUser(mockUserRepository);
23
+ jest.clearAllMocks();
24
+ });
25
+
26
+ it('should create and save a new user', async () => {
27
+ const name = 'Test User';
28
+ const email = 'test@example.com';
29
+ const expectedResult = { id: 1, name, email };
30
+
31
+ mockUserRepository.save.mockResolvedValue(expectedResult as any);
32
+
33
+ const result = await createUser.execute(name, email);
34
+
35
+ expect(mockUserRepository.save).toHaveBeenCalledTimes(1);
36
+ const savedUser = mockUserRepository.save.mock.calls[0][0];
37
+ expect(savedUser.name).toBe(name);
38
+ expect(savedUser.email).toBe(email);
39
+ expect(result).toEqual(expectedResult);
40
+ <%_ if (caching !== 'None') { -%>
41
+ expect(cacheService.del).toHaveBeenCalledWith('users:all');
42
+ <%_ } %>
43
+ });
44
+
45
+ it('should throw an error if repository fails', async () => {
46
+ const error = new Error('Database error');
47
+ mockUserRepository.save.mockRejectedValue(error);
48
+
49
+ await expect(createUser.execute('Test', 'test@test.com')).rejects.toThrow(error);
50
+ });
51
+ });
@@ -1,13 +1,13 @@
1
- import { User } from '@/domain/user';
2
-
3
- import { UserRepository } from '@/infrastructure/repositories/UserRepository';
4
-
5
- export default class CreateUser {
6
- constructor(private userRepository: UserRepository) {}
7
-
8
- async execute(name: string, email: string) {
9
- const user = new User(null, name, email);
10
- return this.userRepository.save(user);
11
- }
12
- }
13
-
1
+ import { User } from '@/domain/user';
2
+
3
+ import { UserRepository } from '@/infrastructure/repositories/UserRepository';
4
+
5
+ export default class CreateUser {
6
+ constructor(private userRepository: UserRepository) {}
7
+
8
+ async execute(name: string, email: string) {
9
+ const user = new User(null, name, email);
10
+ return this.userRepository.save(user);
11
+ }
12
+ }
13
+
@@ -0,0 +1,47 @@
1
+ import DeleteUser from '@/usecases/deleteUser';
2
+ import { UserRepository } from '@/infrastructure/repositories/UserRepository';
3
+ <%_ if (caching !== 'None') { -%>
4
+ import cacheService from '<% if (caching === "Redis") { %>@/infrastructure/caching/redisClient<% } else { %>@/infrastructure/caching/memoryCache<% } %>';
5
+ <%_ } -%>
6
+
7
+ jest.mock('@/infrastructure/repositories/UserRepository');
8
+ <%_ if (caching !== 'None') { -%>
9
+ jest.mock('<% if (caching === "Redis") { %>@/infrastructure/caching/redisClient<% } else { %>@/infrastructure/caching/memoryCache<% } %>', () => ({
10
+ get: jest.fn(),
11
+ set: jest.fn(),
12
+ del: jest.fn()
13
+ }));
14
+ <%_ } -%>
15
+
16
+ describe('DeleteUser UseCase', () => {
17
+ let deleteUser: DeleteUser;
18
+ let mockUserRepository: jest.Mocked<UserRepository>;
19
+
20
+ beforeEach(() => {
21
+ mockUserRepository = new UserRepository() as jest.Mocked<UserRepository>;
22
+ deleteUser = new DeleteUser(mockUserRepository);
23
+ jest.clearAllMocks();
24
+ });
25
+
26
+ it('should delete and return the user', async () => {
27
+ const id = 1;
28
+ const expectedResult = { id, name: 'Deleted User', email: 'test@test.com' };
29
+
30
+ mockUserRepository.delete.mockResolvedValue(expectedResult as any);
31
+
32
+ const result = await deleteUser.execute(id);
33
+
34
+ expect(mockUserRepository.delete).toHaveBeenCalledWith(id);
35
+ expect(result).toEqual(expectedResult);
36
+ <%_ if (caching !== 'None') { -%>
37
+ expect(cacheService.del).toHaveBeenCalledWith('users:all');
38
+ <%_ } %>
39
+ });
40
+
41
+ it('should throw an error if repository fails', async () => {
42
+ const error = new Error('Database error');
43
+ mockUserRepository.delete.mockRejectedValue(error);
44
+
45
+ await expect(deleteUser.execute(1)).rejects.toThrow(error);
46
+ });
47
+ });
@@ -0,0 +1,9 @@
1
+ import { UserRepository } from '@/infrastructure/repositories/UserRepository';
2
+
3
+ export default class DeleteUser {
4
+ constructor(private userRepository: UserRepository) {}
5
+
6
+ async execute(id: number | string) {
7
+ return this.userRepository.delete(id);
8
+ }
9
+ }
@@ -1,63 +1,63 @@
1
- import GetAllUsers from '@/usecases/getAllUsers';
2
- import { UserRepository } from '@/infrastructure/repositories/UserRepository';
3
- <%_ if (caching !== 'None') { -%>
4
- import cacheService from '<% if (caching === "Redis") { %>@/infrastructure/caching/redisClient<% } else { %>@/infrastructure/caching/memoryCache<% } %>';
5
- <%_ } -%>
6
-
7
- jest.mock('@/infrastructure/repositories/UserRepository');
8
- <%_ if (caching !== 'None') { -%>
9
- jest.mock('<% if (caching === "Redis") { %>@/infrastructure/caching/redisClient<% } else { %>@/infrastructure/caching/memoryCache<% } %>', () => ({
10
- get: jest.fn(),
11
- set: jest.fn(),
12
- del: jest.fn()
13
- }));
14
- <%_ } -%>
15
-
16
- describe('GetAllUsers UseCase', () => {
17
- let getAllUsers: GetAllUsers;
18
- let mockUserRepository: jest.Mocked<UserRepository>;
19
-
20
- beforeEach(() => {
21
- mockUserRepository = new UserRepository() as jest.Mocked<UserRepository>;
22
- getAllUsers = new GetAllUsers(mockUserRepository);
23
- jest.clearAllMocks();
24
- });
25
-
26
- it('should retrieve all users', async () => {
27
- const expectedUsers = [{ id: 1, name: 'Alice', email: 'alice@example.com' }];
28
- mockUserRepository.getUsers.mockResolvedValue(expectedUsers as any);
29
- <%_ if (caching !== 'None') { -%>
30
- (cacheService.get as jest.Mock).mockResolvedValue(null);
31
- <%_ } %>
32
-
33
- const result = await getAllUsers.execute();
34
-
35
- expect(mockUserRepository.getUsers).toHaveBeenCalledTimes(1);
36
- expect(result).toEqual(expectedUsers);
37
- <%_ if (caching !== 'None') { -%>
38
- expect(cacheService.set).toHaveBeenCalled();
39
- <%_ } %>
40
- });
41
-
42
- <%_ if (caching !== 'None') { -%>
43
- it('should return from cache if available', async () => {
44
- const cachedUsers = [{ id: 1, name: 'Cached', email: 'cached@example.com' }];
45
- (cacheService.get as jest.Mock).mockResolvedValue(cachedUsers);
46
-
47
- const result = await getAllUsers.execute();
48
-
49
- expect(mockUserRepository.getUsers).not.toHaveBeenCalled();
50
- expect(result).toEqual(cachedUsers);
51
- });
52
- <%_ } -%>
53
-
54
- it('should throw an error if repository fails', async () => {
55
- const error = new Error('Database error');
56
- mockUserRepository.getUsers.mockRejectedValue(error);
57
- <%_ if (caching !== 'None') { -%>
58
- (cacheService.get as jest.Mock).mockResolvedValue(null);
59
- <%_ } -%>
60
-
61
- await expect(getAllUsers.execute()).rejects.toThrow(error);
62
- });
63
- });
1
+ import GetAllUsers from '@/usecases/getAllUsers';
2
+ import { UserRepository } from '@/infrastructure/repositories/UserRepository';
3
+ <%_ if (caching !== 'None') { -%>
4
+ import cacheService from '<% if (caching === "Redis") { %>@/infrastructure/caching/redisClient<% } else { %>@/infrastructure/caching/memoryCache<% } %>';
5
+ <%_ } -%>
6
+
7
+ jest.mock('@/infrastructure/repositories/UserRepository');
8
+ <%_ if (caching !== 'None') { -%>
9
+ jest.mock('<% if (caching === "Redis") { %>@/infrastructure/caching/redisClient<% } else { %>@/infrastructure/caching/memoryCache<% } %>', () => ({
10
+ get: jest.fn(),
11
+ set: jest.fn(),
12
+ del: jest.fn()
13
+ }));
14
+ <%_ } -%>
15
+
16
+ describe('GetAllUsers UseCase', () => {
17
+ let getAllUsers: GetAllUsers;
18
+ let mockUserRepository: jest.Mocked<UserRepository>;
19
+
20
+ beforeEach(() => {
21
+ mockUserRepository = new UserRepository() as jest.Mocked<UserRepository>;
22
+ getAllUsers = new GetAllUsers(mockUserRepository);
23
+ jest.clearAllMocks();
24
+ });
25
+
26
+ it('should retrieve all users', async () => {
27
+ const expectedUsers = [{ id: 1, name: 'Alice', email: 'alice@example.com' }];
28
+ mockUserRepository.getUsers.mockResolvedValue(expectedUsers as any);
29
+ <%_ if (caching !== 'None') { -%>
30
+ (cacheService.get as jest.Mock).mockResolvedValue(null);
31
+ <%_ } %>
32
+
33
+ const result = await getAllUsers.execute();
34
+
35
+ expect(mockUserRepository.getUsers).toHaveBeenCalledTimes(1);
36
+ expect(result).toEqual(expectedUsers);
37
+ <%_ if (caching !== 'None') { -%>
38
+ expect(cacheService.set).toHaveBeenCalled();
39
+ <%_ } %>
40
+ });
41
+
42
+ <%_ if (caching !== 'None') { -%>
43
+ it('should return from cache if available', async () => {
44
+ const cachedUsers = [{ id: 1, name: 'Cached', email: 'cached@example.com' }];
45
+ (cacheService.get as jest.Mock).mockResolvedValue(cachedUsers);
46
+
47
+ const result = await getAllUsers.execute();
48
+
49
+ expect(mockUserRepository.getUsers).not.toHaveBeenCalled();
50
+ expect(result).toEqual(cachedUsers);
51
+ });
52
+ <%_ } -%>
53
+
54
+ it('should throw an error if repository fails', async () => {
55
+ const error = new Error('Database error');
56
+ mockUserRepository.getUsers.mockRejectedValue(error);
57
+ <%_ if (caching !== 'None') { -%>
58
+ (cacheService.get as jest.Mock).mockResolvedValue(null);
59
+ <%_ } -%>
60
+
61
+ await expect(getAllUsers.execute()).rejects.toThrow(error);
62
+ });
63
+ });
@@ -1,10 +1,10 @@
1
- import { UserRepository } from '@/infrastructure/repositories/UserRepository';
2
-
3
- export default class GetAllUsers {
4
- constructor(private userRepository: UserRepository) {}
5
-
6
- async execute() {
7
- return this.userRepository.getUsers();
8
- }
9
- }
10
-
1
+ import { UserRepository } from '@/infrastructure/repositories/UserRepository';
2
+
3
+ export default class GetAllUsers {
4
+ constructor(private userRepository: UserRepository) {}
5
+
6
+ async execute() {
7
+ return this.userRepository.getUsers();
8
+ }
9
+ }
10
+
@@ -0,0 +1,48 @@
1
+ import UpdateUser from '@/usecases/updateUser';
2
+ import { UserRepository } from '@/infrastructure/repositories/UserRepository';
3
+ <%_ if (caching !== 'None') { -%>
4
+ import cacheService from '<% if (caching === "Redis") { %>@/infrastructure/caching/redisClient<% } else { %>@/infrastructure/caching/memoryCache<% } %>';
5
+ <%_ } -%>
6
+
7
+ jest.mock('@/infrastructure/repositories/UserRepository');
8
+ <%_ if (caching !== 'None') { -%>
9
+ jest.mock('<% if (caching === "Redis") { %>@/infrastructure/caching/redisClient<% } else { %>@/infrastructure/caching/memoryCache<% } %>', () => ({
10
+ get: jest.fn(),
11
+ set: jest.fn(),
12
+ del: jest.fn()
13
+ }));
14
+ <%_ } -%>
15
+
16
+ describe('UpdateUser UseCase', () => {
17
+ let updateUser: UpdateUser;
18
+ let mockUserRepository: jest.Mocked<UserRepository>;
19
+
20
+ beforeEach(() => {
21
+ mockUserRepository = new UserRepository() as jest.Mocked<UserRepository>;
22
+ updateUser = new UpdateUser(mockUserRepository);
23
+ jest.clearAllMocks();
24
+ });
25
+
26
+ it('should update and return the user', async () => {
27
+ const id = 1;
28
+ const data = { name: 'Updated Name' };
29
+ const expectedUser = { id, name: 'Updated Name', email: 'test@test.com' };
30
+
31
+ mockUserRepository.update.mockResolvedValue(expectedUser as any);
32
+
33
+ const result = await updateUser.execute(id, data);
34
+
35
+ expect(mockUserRepository.update).toHaveBeenCalledWith(id, data);
36
+ expect(result).toEqual(expectedUser);
37
+ <%_ if (caching !== 'None') { -%>
38
+ expect(cacheService.del).toHaveBeenCalledWith('users:all');
39
+ <%_ } %>
40
+ });
41
+
42
+ it('should throw an error if repository fails', async () => {
43
+ const error = new Error('Database error');
44
+ mockUserRepository.update.mockRejectedValue(error);
45
+
46
+ await expect(updateUser.execute(1, { name: 'Test' })).rejects.toThrow(error);
47
+ });
48
+ });
@@ -0,0 +1,9 @@
1
+ import { UserRepository } from '@/infrastructure/repositories/UserRepository';
2
+
3
+ export default class UpdateUser {
4
+ constructor(private userRepository: UserRepository) {}
5
+
6
+ async execute(id: number | string, data: { name?: string, email?: string }) {
7
+ return this.userRepository.update(id, data);
8
+ }
9
+ }
@@ -0,0 +1,12 @@
1
+ export const ERROR_MESSAGES = {
2
+ USER_NOT_FOUND: 'User not found',
3
+ RESOURCE_NOT_FOUND: 'Resource not found',
4
+ INVALID_USER_DATA: 'Invalid user event data',
5
+ INTERNAL_SERVER_ERROR: 'Internal Server Error',
6
+ BAD_REQUEST: 'Bad Request',
7
+ FETCH_USERS_ERROR: 'Error fetching users',
8
+ CREATE_USER_ERROR: 'Error creating user',
9
+ UPDATE_USER_ERROR: 'Error updating user',
10
+ DELETE_USER_ERROR: 'Error deleting user',
11
+ DATABASE_PING_FAILED: 'Health Check Database Ping Failed',
12
+ } as const;
@@ -1,27 +1,27 @@
1
- import { Request, Response } from 'express';
2
- import logger from '@/infrastructure/log/logger';
3
- import { ApiError } from '@/errors/ApiError';
4
- import { HTTP_STATUS } from '@/utils/httpCodes';
5
-
6
- export const errorMiddleware = (err: Error, req: Request, res: Response, _next: unknown) => {
7
- let error = err;
8
-
9
- if (!(error instanceof ApiError)) {
10
- const statusCode = HTTP_STATUS.INTERNAL_SERVER_ERROR;
11
- const message = error.message || 'Internal Server Error';
12
- error = new ApiError(statusCode, message, false, err.stack);
13
- }
14
-
15
- const { statusCode, message } = error as ApiError;
16
-
17
- if (statusCode === HTTP_STATUS.INTERNAL_SERVER_ERROR) {
18
- logger.error(`${statusCode} - ${message} - ${req.originalUrl} - ${req.method} - ${req.ip}`);
19
- logger.error(error.stack || 'No stack trace');
20
- }
21
-
22
- res.status(statusCode).json({
23
- statusCode,
24
- message,
25
- ...(process.env.NODE_ENV === 'development' && { stack: error.stack }),
26
- });
27
- };
1
+ import { Request, Response } from 'express';
2
+ import logger from '@/infrastructure/log/logger';
3
+ import { ApiError } from '@/errors/ApiError';
4
+ import { HTTP_STATUS } from '@/utils/httpCodes';
5
+
6
+ export const errorMiddleware = (err: Error, req: Request, res: Response, _next: unknown) => {
7
+ let error = err;
8
+
9
+ if (!(error instanceof ApiError)) {
10
+ const statusCode = HTTP_STATUS.INTERNAL_SERVER_ERROR;
11
+ const message = error.message || 'Internal Server Error';
12
+ error = new ApiError(statusCode, message, false, err.stack);
13
+ }
14
+
15
+ const { statusCode, message } = error as ApiError;
16
+
17
+ if (statusCode === HTTP_STATUS.INTERNAL_SERVER_ERROR) {
18
+ logger.error(`${statusCode} - ${message} - ${req.originalUrl} - ${req.method} - ${req.ip}`);
19
+ logger.error(error.stack || 'No stack trace');
20
+ }
21
+
22
+ res.status(statusCode).json({
23
+ statusCode,
24
+ message,
25
+ ...(process.env.NODE_ENV === 'development' && { stack: error.stack }),
26
+ });
27
+ };
@@ -1,7 +1,7 @@
1
- export const HTTP_STATUS = {
2
- OK: 200,
3
- CREATED: 201,
4
- BAD_REQUEST: 400,
5
- NOT_FOUND: 404,
6
- INTERNAL_SERVER_ERROR: 500
7
- } as const;
1
+ export const HTTP_STATUS = {
2
+ OK: 200,
3
+ CREATED: 201,
4
+ BAD_REQUEST: 400,
5
+ NOT_FOUND: 404,
6
+ INTERNAL_SERVER_ERROR: 500
7
+ } as const;