nodejs-quickstart-structure 1.4.2 → 1.6.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 (31) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/README.md +14 -18
  3. package/bin/index.js +1 -1
  4. package/docs/generateCase.md +23 -7
  5. package/docs/generatorFlow.md +5 -1
  6. package/docs/releaseNoteRule.md +42 -0
  7. package/lib/generator.js +41 -316
  8. package/lib/modules/app-setup.js +91 -0
  9. package/lib/modules/config-files.js +88 -0
  10. package/lib/modules/database-setup.js +99 -0
  11. package/lib/modules/kafka-setup.js +112 -0
  12. package/lib/modules/project-setup.js +31 -0
  13. package/lib/prompts.js +3 -3
  14. package/package.json +4 -3
  15. package/templates/clean-architecture/js/src/index.js.ejs +19 -6
  16. package/templates/clean-architecture/js/src/infrastructure/log/logger.js +16 -2
  17. package/templates/clean-architecture/js/src/infrastructure/repositories/UserRepository.js.ejs +18 -6
  18. package/templates/clean-architecture/js/src/infrastructure/webserver/server.js.ejs +2 -0
  19. package/templates/clean-architecture/ts/src/index.ts.ejs +27 -19
  20. package/templates/clean-architecture/ts/src/infrastructure/log/logger.ts +16 -2
  21. package/templates/clean-architecture/ts/src/infrastructure/repositories/userRepository.ts.ejs +17 -6
  22. package/templates/common/Dockerfile +3 -0
  23. package/templates/common/docker-compose.yml.ejs +47 -24
  24. package/templates/common/package.json.ejs +9 -2
  25. package/templates/mvc/js/src/controllers/userController.js.ejs +13 -3
  26. package/templates/mvc/js/src/index.js.ejs +26 -17
  27. package/templates/mvc/js/src/utils/logger.js +16 -6
  28. package/templates/mvc/ts/src/controllers/userController.ts.ejs +13 -3
  29. package/templates/mvc/ts/src/index.ts.ejs +27 -18
  30. package/templates/mvc/ts/src/utils/logger.ts +16 -2
  31. package/templates/mvc/js/src/config/database.js +0 -12
@@ -5,6 +5,7 @@ import hpp from 'hpp';
5
5
  import rateLimit from 'express-rate-limit';
6
6
  import dotenv from 'dotenv';
7
7
  import logger from '@/infrastructure/log/logger';
8
+ import morgan from 'morgan';
8
9
  <% if (communication === 'REST APIs') { %>import userRoutes from '@/interfaces/routes/userRoutes';<% } -%>
9
10
  <% if (communication === 'REST APIs') { -%>
10
11
  import swaggerUi from 'swagger-ui-express';
@@ -24,6 +25,7 @@ const limiter = rateLimit({ windowMs: 10 * 60 * 1000, max: 100 });
24
25
  app.use(limiter);
25
26
 
26
27
  app.use(express.json());
28
+ app.use(morgan('combined', { stream: { write: (message) => logger.info(message.trim()) } }));
27
29
 
28
30
  <% if (communication === 'REST APIs') { -%>
29
31
  app.use('/api/users', userRoutes);
@@ -37,34 +39,37 @@ app.get('/health', (req: Request, res: Response) => {
37
39
  res.json({ status: 'UP' });
38
40
  });
39
41
 
42
+ // Start Server Logic
43
+ const startServer = async () => {
44
+ logger.info(`Server running on port ${port}`);
45
+ <%_ if (communication === 'Kafka') { -%>
46
+ try {
47
+ const kafkaService = new KafkaService();
48
+ await kafkaService.connect();
49
+ logger.info('Kafka connected');
50
+ // Demo
51
+ await kafkaService.sendMessage('test-topic', 'Hello Kafka from Clean Arch TS!');
52
+ } catch (err) {
53
+ logger.error('Failed to connect to Kafka:', err);
54
+ }
55
+ <%_ } -%>
56
+ };
57
+
58
+ <%_ if (database !== 'None') { -%>
40
59
  // Database Sync
41
60
  const syncDatabase = async () => {
42
61
  let retries = 30;
43
62
  while (retries) {
44
63
  try {
45
- <% if (database === 'MongoDB') { %>
64
+ <%_ if (database === 'MongoDB') { -%>
46
65
  const connectDB = (await import('@/infrastructure/database/database')).default;
47
66
  await connectDB();
48
- <% } else { %>
67
+ <%_ } else { -%>
49
68
  const sequelize = (await import('@/infrastructure/database/database')).default;
50
69
  await sequelize.sync();
51
- <% } %>
70
+ <%_ } -%>
52
71
  logger.info('Database synced');
53
-
54
- app.listen(port, async () => {
55
- logger.info(`Server running on port ${port}`);
56
- <%_ if (communication === 'Kafka') { -%>
57
- try {
58
- const kafkaService = new KafkaService();
59
- await kafkaService.connect();
60
- logger.info('Kafka connected');
61
- // Demo
62
- await kafkaService.sendMessage('test-topic', 'Hello Kafka from Clean Arch TS!');
63
- } catch (err) {
64
- logger.error('Failed to connect to Kafka:', err);
65
- }
66
- <%_ } -%>
67
- });
72
+ app.listen(port, startServer);
68
73
  break;
69
74
  } catch (error) {
70
75
  logger.error('Error syncing database:', error);
@@ -75,4 +80,7 @@ const syncDatabase = async () => {
75
80
  }
76
81
  };
77
82
 
78
- syncDatabase();
83
+ syncDatabase();
84
+ <%_ } else { -%>
85
+ app.listen(port, startServer);
86
+ <%_ } -%>
@@ -1,4 +1,5 @@
1
1
  import winston from 'winston';
2
+ import 'winston-daily-rotate-file';
2
3
 
3
4
  const logger = winston.createLogger({
4
5
  level: 'info',
@@ -8,8 +9,21 @@ const logger = winston.createLogger({
8
9
  ),
9
10
  defaultMeta: { service: 'user-service' },
10
11
  transports: [
11
- new winston.transports.File({ filename: 'error.log', level: 'error' }),
12
- new winston.transports.File({ filename: 'combined.log' }),
12
+ new winston.transports.DailyRotateFile({
13
+ filename: 'logs/error-%DATE%.log',
14
+ datePattern: 'YYYY-MM-DD',
15
+ zippedArchive: true,
16
+ maxSize: '20m',
17
+ maxFiles: '14d',
18
+ level: 'error',
19
+ }),
20
+ new winston.transports.DailyRotateFile({
21
+ filename: 'logs/combined-%DATE%.log',
22
+ datePattern: 'YYYY-MM-DD',
23
+ zippedArchive: true,
24
+ maxSize: '20m',
25
+ maxFiles: '14d',
26
+ }),
13
27
  ],
14
28
  });
15
29
 
@@ -3,25 +3,36 @@ import UserModel from '@/infrastructure/database/models/User';
3
3
 
4
4
  export class UserRepository {
5
5
  async save(user: UserEntity): Promise<UserEntity> {
6
+ <%_ if (database === 'MongoDB') { -%>
6
7
  const newUser = await UserModel.create({ name: user.name, email: user.email });
7
- <% if (database === 'MongoDB') { %> return { id: newUser._id.toString(), name: newUser.name, email: newUser.email };
8
- <% } else { %> return { id: newUser.id, name: newUser.name, email: newUser.email };
9
- <% } -%>
8
+ return { id: newUser._id.toString(), name: newUser.name, email: newUser.email };
9
+ <%_ } else if (database === 'None') { -%>
10
+ const newUser = { id: String(UserModel.mockData.length + 1), name: user.name, email: user.email };
11
+ UserModel.mockData.push(newUser);
12
+ return newUser;
13
+ <%_ } else { -%>
14
+ const newUser = await UserModel.create({ name: user.name, email: user.email });
15
+ return { id: newUser.id, name: newUser.name, email: newUser.email };
16
+ <%_ } -%>
10
17
  }
11
18
 
12
19
  async getUsers(): Promise<UserEntity[]> {
13
- <% if (database === 'MongoDB') { %> const users = await UserModel.find();
20
+ <%_ if (database === 'MongoDB') { -%>
21
+ const users = await UserModel.find();
14
22
  return users.map(user => ({
15
23
  id: user._id.toString(),
16
24
  name: user.name,
17
25
  email: user.email
18
26
  }));
19
- <% } else { %> const users = await UserModel.findAll();
27
+ <%_ } else if (database === 'None') { -%>
28
+ return UserModel.mockData;
29
+ <%_ } else { -%>
30
+ const users = await UserModel.findAll();
20
31
  return users.map(user => ({
21
32
  id: user.id,
22
33
  name: user.name,
23
34
  email: user.email
24
35
  }));
25
- <% } -%>
36
+ <%_ } -%>
26
37
  }
27
38
  }
@@ -45,6 +45,9 @@ COPY --from=builder /app/src/views ./dist/views
45
45
 
46
46
  EXPOSE 3000
47
47
 
48
+ # Create logs directory and give permissions to node user
49
+ RUN mkdir -p logs && chown -R node:node logs
50
+
48
51
  USER node
49
52
 
50
53
  CMD ["npm", "start"]
@@ -1,40 +1,54 @@
1
- version: '3.8'
2
-
3
1
  services:
4
2
  app:
5
3
  build: .
6
4
  ports:
7
5
  - "${PORT:-3000}:3000"
6
+ <%_ if (database !== 'None' || communication === 'Kafka') { -%>
8
7
  depends_on:
8
+ <%_ if (database !== 'None') { -%>
9
9
  - db
10
- <% if (communication === 'Kafka') { %> - kafka
11
- <% } -%>
12
- <% if (communication === 'Kafka') { %> environment:
10
+ <%_ } -%>
11
+ <%_ if (communication === 'Kafka') { -%>
12
+ - kafka
13
+ <%_ } -%>
14
+ <%_ } -%>
15
+ <%_ if (communication === 'Kafka') { -%>
16
+ environment:
13
17
  - KAFKA_BROKER=kafka:29092
14
18
  - KAFKAJS_NO_PARTITIONER_WARNING=1
15
19
  - PORT=3000
20
+ <%_ if (database !== 'None') { -%>
16
21
  - DB_HOST=db
17
- <% if (database === 'MySQL') { %> - DB_USER=root
22
+ <%_ if (database === 'MySQL') { -%>
23
+ - DB_USER=root
18
24
  - DB_PASSWORD=root
19
25
  - DB_NAME=<%= dbName %>
20
- <% } %><% if (database === 'PostgreSQL') { %> - DB_USER=postgres
26
+ <%_ } -%><%_ if (database === 'PostgreSQL') { -%>
27
+ - DB_USER=postgres
21
28
  - DB_PASSWORD=root
22
29
  - DB_NAME=<%= dbName %>
23
- <% } -%>
24
- <% } else { %>
30
+ <%_ } -%>
31
+ <%_ } -%>
32
+ <%_ } else { -%>
25
33
  environment:
26
34
  - PORT=3000
35
+ <%_ if (database !== 'None') { -%>
27
36
  - DB_HOST=db
28
- <% if (database === 'MySQL') { %> - DB_USER=root
37
+ <%_ if (database === 'MySQL') { -%>
38
+ - DB_USER=root
29
39
  - DB_PASSWORD=root
30
40
  - DB_NAME=<%= dbName %>
31
- <% } %><% if (database === 'PostgreSQL') { %> - DB_USER=postgres
41
+ <%_ } -%><%_ if (database === 'PostgreSQL') { -%>
42
+ - DB_USER=postgres
32
43
  - DB_PASSWORD=root
33
44
  - DB_NAME=<%= dbName %>
34
- <% } -%>
35
- <% } %>
45
+ <%_ } -%>
46
+ <%_ } -%>
47
+ <%_ } -%>
48
+ <%_ if (database !== 'None') { -%>
36
49
  db:
37
- <% if (database === 'MySQL') { %> image: mysql:8.0
50
+ <%_ if (database === 'MySQL') { -%>
51
+ image: mysql:8.0
38
52
  restart: always
39
53
  environment:
40
54
  MYSQL_ROOT_PASSWORD: root
@@ -43,7 +57,8 @@ services:
43
57
  - "${DB_PORT:-3306}:3306"
44
58
  volumes:
45
59
  - ./flyway/sql:/docker-entrypoint-initdb.d
46
- <% } else if (database === 'PostgreSQL') { %> image: postgres:15
60
+ <%_ } else if (database === 'PostgreSQL') { -%>
61
+ image: postgres:15
47
62
  restart: always
48
63
  environment:
49
64
  POSTGRES_USER: postgres
@@ -53,7 +68,8 @@ services:
53
68
  - "${DB_PORT:-5432}:5432"
54
69
  volumes:
55
70
  - ./flyway/sql:/docker-entrypoint-initdb.d
56
- <% } else if (database === 'MongoDB') { %> image: mongo:latest
71
+ <%_ } else if (database === 'MongoDB') { -%>
72
+ image: mongo:latest
57
73
  restart: always
58
74
  environment:
59
75
  MONGO_INITDB_DATABASE: <%= dbName %>
@@ -73,24 +89,29 @@ services:
73
89
  - DB_NAME=<%= dbName %>
74
90
  depends_on:
75
91
  - db
76
- <% } %>
77
- <% if (database !== 'MongoDB') { %>
92
+ <%_ } -%>
93
+ <%_ } -%>
94
+ <%_ if (database !== 'MongoDB' && database !== 'None') { -%>
78
95
  flyway:
79
96
  image: flyway/flyway
80
97
  command: -connectRetries=60 migrate
81
98
  volumes:
82
99
  - ./flyway/sql:/flyway/sql
83
100
  environment:
84
- <% if (database === 'MySQL') { %> FLYWAY_URL: jdbc:mysql://db:3306/<%= dbName %>
101
+ <%_ if (database === 'MySQL') { -%>
102
+ FLYWAY_URL: jdbc:mysql://db:3306/<%= dbName %>
85
103
  FLYWAY_USER: root
86
104
  FLYWAY_PASSWORD: root
87
- <% } %><% if (database === 'PostgreSQL') { %> FLYWAY_URL: jdbc:postgresql://db:5432/<%= dbName %>
105
+ <%_ } -%><%_ if (database === 'PostgreSQL') { -%>
106
+ FLYWAY_URL: jdbc:postgresql://db:5432/<%= dbName %>
88
107
  FLYWAY_USER: postgres
89
108
  FLYWAY_PASSWORD: root
90
- <% } %> depends_on:
109
+ <%_ } -%>
110
+ depends_on:
91
111
  - db
92
- <% } %>
93
- <% if (communication === 'Kafka') { %> zookeeper:
112
+ <%_ } -%>
113
+ <%_ if (communication === 'Kafka') { -%>
114
+ zookeeper:
94
115
  image: confluentinc/cp-zookeeper:7.4.0
95
116
  environment:
96
117
  ZOOKEEPER_CLIENT_PORT: 2181
@@ -111,6 +132,8 @@ services:
111
132
  KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
112
133
  KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
113
134
  KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
114
- <% } -%>
135
+ <%_ } -%>
136
+ <%_ if (database !== 'None') { -%>
115
137
  volumes:
116
138
  <%= database.toLowerCase() %>_data:
139
+ <%_ } -%>
@@ -13,8 +13,10 @@
13
13
  "prepare": "husky install",
14
14
  "test": "jest",
15
15
  "test:watch": "jest --watch",
16
- "test:coverage": "jest --coverage",
16
+ "test:coverage": "jest --coverage"
17
+ <%_ if (database === 'MongoDB') { -%>,
17
18
  "migrate": "migrate-mongo up"
19
+ <%_ } -%>
18
20
  },
19
21
  "dependencies": {
20
22
  "express": "^4.18.2",
@@ -38,7 +40,9 @@
38
40
  "helmet": "^7.1.0",
39
41
  "hpp": "^0.2.3",
40
42
  "express-rate-limit": "^7.1.5",
41
- "winston": "^3.11.0"<% if (communication === 'REST APIs') { %>,
43
+ "winston": "^3.11.0",
44
+ "winston-daily-rotate-file": "^5.0.0",
45
+ "morgan": "^1.10.0"<% if (communication === 'REST APIs') { %>,
42
46
  "swagger-ui-express": "^5.0.0",
43
47
  "swagger-jsdoc": "^6.2.8"<% } %>
44
48
  },
@@ -53,7 +57,10 @@
53
57
  "@types/hpp": "^0.2.3",
54
58
  <% if (database === 'PostgreSQL') { %> "@types/pg": "^8.10.9",
55
59
  <% } -%>
60
+ <%_ if (database === 'MySQL' || database === 'PostgreSQL') { -%>
56
61
  "@types/sequelize": "^4.28.19",
62
+ <%_ } -%>
63
+ "@types/morgan": "^1.9.9",
57
64
  "rimraf": "^5.0.5"<% if (viewEngine && viewEngine !== 'None') { %>,
58
65
  "copyfiles": "^2.4.1"<% } %><% } %>,
59
66
  "eslint": "^8.56.0",
@@ -4,9 +4,13 @@ const logger = require('../utils/logger');
4
4
 
5
5
  const getUsers = async (req, res) => {
6
6
  try {
7
- <% if (database === 'MongoDB') { %> const users = await User.find();
8
- <% } else { %> const users = await User.findAll();
9
- <% } -%>
7
+ <%_ if (database === 'MongoDB') { -%>
8
+ const users = await User.find();
9
+ <%_ } else if (database === 'None') { -%>
10
+ const users = User.mockData;
11
+ <%_ } else { -%>
12
+ const users = await User.findAll();
13
+ <%_ } -%>
10
14
  res.json(users);
11
15
  } catch (error) {
12
16
  logger.error('Error fetching users:', error);
@@ -17,8 +21,14 @@ const getUsers = async (req, res) => {
17
21
  const createUser = async (req, res) => {
18
22
  try {
19
23
  const { name, email } = req.body;
24
+ <%_ if (database === 'None') { -%>
25
+ const newUser = { id: String(User.mockData.length + 1), name, email };
26
+ User.mockData.push(newUser);
27
+ res.status(HTTP_STATUS.CREATED).json(newUser);
28
+ <%_ } else { -%>
20
29
  const user = await User.create({ name, email });
21
30
  res.status(HTTP_STATUS.CREATED).json(user);
31
+ <%_ } -%>
22
32
  } catch (error) {
23
33
  res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({ error: error.message });
24
34
  }
@@ -11,9 +11,11 @@ const swaggerSpecs = require('./config/swagger');
11
11
  const app = express();
12
12
  const PORT = process.env.PORT || 3000;
13
13
  const logger = require('./utils/logger');
14
+ const morgan = require('morgan');
14
15
 
15
16
  app.use(cors());
16
17
  app.use(express.json());
18
+ app.use(morgan('combined', { stream: { write: message => logger.info(message.trim()) } }));
17
19
 
18
20
  <% if (communication === 'REST APIs') { -%>
19
21
  app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpecs));
@@ -45,34 +47,38 @@ app.get('/health', (req, res) => {
45
47
  res.json({ status: 'UP' });
46
48
  });
47
49
 
50
+ // Start Server Logic
51
+ const startServer = async () => {
52
+ logger.info(`Server running on port ${PORT}`);
53
+ <%_ if (communication === 'Kafka') { -%>
54
+ try {
55
+ await connectKafka();
56
+ logger.info('Kafka connected');
57
+ // Demo: Send a test message
58
+ await sendMessage('test-topic', 'Hello Kafka from MVC JS!');
59
+ } catch (err) {
60
+ logger.error('Failed to connect to Kafka:', err);
61
+ }
62
+ <%_ } -%>
63
+ };
64
+
65
+ <%_ if (database !== 'None') { -%>
48
66
  // Database Sync
49
67
  const syncDatabase = async () => {
50
68
  let retries = 30;
51
69
  while (retries) {
52
70
  try {
53
- <% if (database === 'MongoDB') { %>
71
+ <%_ if (database === 'MongoDB') { -%>
54
72
  const connectDB = require('./config/database');
55
73
  await connectDB();
56
- <% } else { %>
74
+ <%_ } else { -%>
57
75
  const sequelize = require('./config/database');
58
76
  await sequelize.sync();
59
- <% } %>
77
+ <%_ } -%>
60
78
  logger.info('Database synced');
61
79
 
62
80
  // Start Server after DB is ready
63
- app.listen(PORT, async () => {
64
- logger.info(`Server running on port ${PORT}`);
65
- <%_ if (communication === 'Kafka') { -%>
66
- try {
67
- await connectKafka();
68
- logger.info('Kafka connected');
69
- // Demo: Send a test message
70
- await sendMessage('test-topic', 'Hello Kafka from MVC JS!');
71
- } catch (err) {
72
- logger.error('Failed to connect to Kafka:', err);
73
- }
74
- <%_ } -%>
75
- });
81
+ app.listen(PORT, startServer);
76
82
  break;
77
83
  } catch (err) {
78
84
  logger.error('Database sync failed:', err);
@@ -83,4 +89,7 @@ const syncDatabase = async () => {
83
89
  }
84
90
  };
85
91
 
86
- syncDatabase();
92
+ syncDatabase();
93
+ <%_ } else { -%>
94
+ app.listen(PORT, startServer);
95
+ <%_ } -%>
@@ -1,4 +1,5 @@
1
1
  const winston = require('winston');
2
+ require('winston-daily-rotate-file');
2
3
 
3
4
  const logger = winston.createLogger({
4
5
  level: 'info',
@@ -8,12 +9,21 @@ const logger = winston.createLogger({
8
9
  ),
9
10
  defaultMeta: { service: 'user-service' },
10
11
  transports: [
11
- //
12
- // - Write all logs with importance level of `error` or less to `error.log`
13
- // - Write all logs with importance level of `info` or less to `combined.log`
14
- //
15
- new winston.transports.File({ filename: 'error.log', level: 'error' }),
16
- new winston.transports.File({ filename: 'combined.log' }),
12
+ new winston.transports.DailyRotateFile({
13
+ filename: 'logs/error-%DATE%.log',
14
+ datePattern: 'YYYY-MM-DD',
15
+ zippedArchive: true,
16
+ maxSize: '20m',
17
+ maxFiles: '14d',
18
+ level: 'error',
19
+ }),
20
+ new winston.transports.DailyRotateFile({
21
+ filename: 'logs/combined-%DATE%.log',
22
+ datePattern: 'YYYY-MM-DD',
23
+ zippedArchive: true,
24
+ maxSize: '20m',
25
+ maxFiles: '14d',
26
+ }),
17
27
  ],
18
28
  });
19
29
 
@@ -6,9 +6,13 @@ import logger from '@/utils/logger';
6
6
  export class UserController {
7
7
  async getUsers(req: Request, res: Response) {
8
8
  try {
9
- <% if (database === 'MongoDB') { %> const users = await User.find();
10
- <% } else { %> const users = await User.findAll();
11
- <% } -%>
9
+ <%_ if (database === 'MongoDB') { -%>
10
+ const users = await User.find();
11
+ <%_ } else if (database === 'None') { -%>
12
+ const users = User.mockData;
13
+ <%_ } else { -%>
14
+ const users = await User.findAll();
15
+ <%_ } -%>
12
16
  res.json(users);
13
17
  } catch (error) {
14
18
  logger.error('Error fetching users:', error);
@@ -23,8 +27,14 @@ export class UserController {
23
27
  async createUser(req: Request, res: Response) {
24
28
  try {
25
29
  const { name, email } = req.body;
30
+ <%_ if (database === 'None') { -%>
31
+ const newUser = { id: String(User.mockData.length + 1), name, email };
32
+ User.mockData.push(newUser);
33
+ res.status(HTTP_STATUS.CREATED).json(newUser);
34
+ <%_ } else { -%>
26
35
  const user = await User.create({ name, email });
27
36
  res.status(HTTP_STATUS.CREATED).json(user);
37
+ <%_ } -%>
28
38
  } catch (error) {
29
39
  logger.error('Error creating user:', error);
30
40
  if (error instanceof Error) {
@@ -5,6 +5,7 @@ import hpp from 'hpp';
5
5
  import rateLimit from 'express-rate-limit';
6
6
  import dotenv from 'dotenv';
7
7
  import logger from '@/utils/logger';
8
+ import morgan from 'morgan';
8
9
  <% if (communication === 'REST APIs' || (viewEngine && viewEngine !== 'None')) { %>import apiRoutes from '@/routes/api';<% } -%>
9
10
  <% if (communication === 'REST APIs') { %>
10
11
  import swaggerUi from 'swagger-ui-express';
@@ -24,6 +25,7 @@ const limiter = rateLimit({ windowMs: 10 * 60 * 1000, max: 100 });
24
25
  app.use(limiter);
25
26
 
26
27
  app.use(express.json());
28
+ app.use(morgan('combined', { stream: { write: (message) => logger.info(message.trim()) } }));
27
29
 
28
30
  <% if (communication === 'REST APIs') { -%>
29
31
  app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpecs));
@@ -55,34 +57,38 @@ app.get('/health', (req: Request, res: Response) => {
55
57
  res.json({ status: 'UP' });
56
58
  });
57
59
 
60
+ // Start Server Logic
61
+ const startServer = async () => {
62
+ logger.info(`Server running on port ${port}`);
63
+ <%_ if (communication === 'Kafka') { -%>
64
+ try {
65
+ const kafkaService = new KafkaService();
66
+ await kafkaService.connect();
67
+ logger.info('Kafka connected');
68
+ // Demo: Send a test message
69
+ await kafkaService.sendMessage('test-topic', 'Hello Kafka from MVC TS!');
70
+ } catch (err) {
71
+ logger.error('Failed to connect to Kafka:', err);
72
+ }
73
+ <%_ } -%>
74
+ };
75
+
76
+ <%_ if (database !== 'None') { -%>
58
77
  // Database Sync
59
78
  const syncDatabase = async () => {
60
79
  let retries = 30;
61
80
  while (retries) {
62
81
  try {
63
- <% if (database === 'MongoDB') { %>
82
+ <%_ if (database === 'MongoDB') { -%>
64
83
  const connectDB = (await import('@/config/database')).default;
65
84
  await connectDB();
66
- <% } else { %>
85
+ <%_ } else { -%>
67
86
  const sequelize = (await import('@/config/database')).default;
68
87
  await sequelize.sync();
69
- <% } %>
88
+ <%_ } -%>
70
89
  logger.info('Database synced');
71
90
  // Start Server after DB is ready
72
- app.listen(port, async () => {
73
- logger.info(`Server running on port ${port}`);
74
- <%_ if (communication === 'Kafka') { -%>
75
- try {
76
- const kafkaService = new KafkaService();
77
- await kafkaService.connect();
78
- logger.info('Kafka connected');
79
- // Demo: Send a test message
80
- await kafkaService.sendMessage('test-topic', 'Hello Kafka from MVC TS!');
81
- } catch (err) {
82
- logger.error('Failed to connect to Kafka:', err);
83
- }
84
- <%_ } -%>
85
- });
91
+ app.listen(port, startServer);
86
92
  break;
87
93
  } catch (error) {
88
94
  logger.error('Error syncing database:', error);
@@ -93,4 +99,7 @@ const syncDatabase = async () => {
93
99
  }
94
100
  };
95
101
 
96
- syncDatabase();
102
+ syncDatabase();
103
+ <%_ } else { -%>
104
+ app.listen(port, startServer);
105
+ <%_ } -%>
@@ -1,4 +1,5 @@
1
1
  import winston from 'winston';
2
+ import 'winston-daily-rotate-file';
2
3
 
3
4
  const logger = winston.createLogger({
4
5
  level: 'info',
@@ -8,8 +9,21 @@ const logger = winston.createLogger({
8
9
  ),
9
10
  defaultMeta: { service: 'user-service' },
10
11
  transports: [
11
- new winston.transports.File({ filename: 'error.log', level: 'error' }),
12
- new winston.transports.File({ filename: 'combined.log' }),
12
+ new winston.transports.DailyRotateFile({
13
+ filename: 'logs/error-%DATE%.log',
14
+ datePattern: 'YYYY-MM-DD',
15
+ zippedArchive: true,
16
+ maxSize: '20m',
17
+ maxFiles: '14d',
18
+ level: 'error',
19
+ }),
20
+ new winston.transports.DailyRotateFile({
21
+ filename: 'logs/combined-%DATE%.log',
22
+ datePattern: 'YYYY-MM-DD',
23
+ zippedArchive: true,
24
+ maxSize: '20m',
25
+ maxFiles: '14d',
26
+ }),
13
27
  ],
14
28
  });
15
29
 
@@ -1,12 +0,0 @@
1
- // Database configuration placeholder
2
- // Use environment variables from .env depending on your DB choice (MySQL/Postgres)
3
- require('dotenv').config();
4
-
5
- const dbConfig = {
6
- host: process.env.DB_HOST,
7
- user: process.env.DB_USER,
8
- password: process.env.DB_PASSWORD,
9
- database: process.env.DB_NAME
10
- };
11
-
12
- module.exports = dbConfig;