create-jinmankn-app 1.0.12 → 1.0.14

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 (55) hide show
  1. package/package.json +1 -1
  2. package/templates/EPMS(Employee Payroll Managment System)/package-lock.json +13 -0
  3. package/templates/HRMS (reba kuri iyi bro)/README.md +1 -0
  4. package/templates/HRMS (reba kuri iyi bro)/backend/config/db.js +12 -0
  5. package/templates/HRMS (reba kuri iyi bro)/backend/controllers/authController.js +138 -0
  6. package/templates/HRMS (reba kuri iyi bro)/backend/controllers/departmentController.js +74 -0
  7. package/templates/HRMS (reba kuri iyi bro)/backend/controllers/employeeController.js +204 -0
  8. package/templates/HRMS (reba kuri iyi bro)/backend/controllers/positionController.js +78 -0
  9. package/templates/HRMS (reba kuri iyi bro)/backend/controllers/reportController.js +45 -0
  10. package/templates/HRMS (reba kuri iyi bro)/backend/middleware/auth.js +28 -0
  11. package/templates/HRMS (reba kuri iyi bro)/backend/models/Department.js +15 -0
  12. package/templates/HRMS (reba kuri iyi bro)/backend/models/Employee.js +73 -0
  13. package/templates/HRMS (reba kuri iyi bro)/backend/models/Position.js +20 -0
  14. package/templates/HRMS (reba kuri iyi bro)/backend/models/User.js +37 -0
  15. package/templates/HRMS (reba kuri iyi bro)/backend/package-lock.json +2231 -0
  16. package/templates/HRMS (reba kuri iyi bro)/backend/package.json +23 -0
  17. package/templates/HRMS (reba kuri iyi bro)/backend/routes/authRoutes.js +13 -0
  18. package/templates/HRMS (reba kuri iyi bro)/backend/routes/departmentRoutes.js +17 -0
  19. package/templates/HRMS (reba kuri iyi bro)/backend/routes/employeeRoutes.js +19 -0
  20. package/templates/HRMS (reba kuri iyi bro)/backend/routes/positionRoutes.js +17 -0
  21. package/templates/HRMS (reba kuri iyi bro)/backend/routes/protectedRoutes.js +10 -0
  22. package/templates/HRMS (reba kuri iyi bro)/backend/routes/reportRoutes.js +9 -0
  23. package/templates/HRMS (reba kuri iyi bro)/backend/server.js +49 -0
  24. package/templates/HRMS (reba kuri iyi bro)/frontend/README.md +16 -0
  25. package/templates/HRMS (reba kuri iyi bro)/frontend/eslint.config.js +21 -0
  26. package/templates/HRMS (reba kuri iyi bro)/frontend/index.html +13 -0
  27. package/templates/HRMS (reba kuri iyi bro)/frontend/package-lock.json +3095 -0
  28. package/templates/HRMS (reba kuri iyi bro)/frontend/package.json +31 -0
  29. package/templates/HRMS (reba kuri iyi bro)/frontend/public/favicon.svg +1 -0
  30. package/templates/HRMS (reba kuri iyi bro)/frontend/src/App.css +0 -0
  31. package/templates/HRMS (reba kuri iyi bro)/frontend/src/App.jsx +37 -0
  32. package/templates/HRMS (reba kuri iyi bro)/frontend/src/assets/hero.png +0 -0
  33. package/templates/HRMS (reba kuri iyi bro)/frontend/src/components/DashboardLayout.jsx +108 -0
  34. package/templates/HRMS (reba kuri iyi bro)/frontend/src/components/ProtectedRoute.jsx +9 -0
  35. package/templates/HRMS (reba kuri iyi bro)/frontend/src/index.css +59 -0
  36. package/templates/HRMS (reba kuri iyi bro)/frontend/src/main.jsx +11 -0
  37. package/templates/HRMS (reba kuri iyi bro)/frontend/src/pages/CreateUser.jsx +149 -0
  38. package/templates/HRMS (reba kuri iyi bro)/frontend/src/pages/DashboardHome.jsx +57 -0
  39. package/templates/HRMS (reba kuri iyi bro)/frontend/src/pages/Department.jsx +160 -0
  40. package/templates/HRMS (reba kuri iyi bro)/frontend/src/pages/Employee.jsx +376 -0
  41. package/templates/HRMS (reba kuri iyi bro)/frontend/src/pages/Login.jsx +84 -0
  42. package/templates/HRMS (reba kuri iyi bro)/frontend/src/pages/Position.jsx +179 -0
  43. package/templates/HRMS (reba kuri iyi bro)/frontend/src/pages/Register.jsx +105 -0
  44. package/templates/HRMS (reba kuri iyi bro)/frontend/src/pages/Reports.jsx +92 -0
  45. package/templates/HRMS (reba kuri iyi bro)/frontend/vite.config.js +7 -0
  46. package/templates/SMS(Stock Managment System)/backend-project/server.js +1 -1
  47. package/templates/SMS(Stock Managment System)/frontend-project/src/components/AppLayout.jsx +1 -1
  48. package/templates/SMS(Stock Managment System)/frontend-project/src/pages/Login.jsx +1 -1
  49. package/templates/SMS(Stock Managment System)/frontend-project/src/pages/Product.jsx +211 -78
  50. package/templates/SMS(Stock Managment System)/frontend-project/src/pages/Profile.jsx +1 -1
  51. package/templates/SMS(Stock Managment System)/frontend-project/src/pages/Register.jsx +1 -1
  52. package/templates/SMS(Stock Managment System)/frontend-project/src/pages/Reports.jsx +1 -1
  53. package/templates/SMS(Stock Managment System)/frontend-project/src/pages/Sales.jsx +6 -6
  54. package/templates/SMS(Stock Managment System)/frontend-project/src/pages/Warehouse.jsx +150 -44
  55. package/templates/SMS(Stock Managment System)/package-lock.json +13 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-jinmankn-app",
3
- "version": "1.0.12",
3
+ "version": "1.0.14",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "create-jinmankn-app": "./bin/index.js"
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "jinman-blueprint",
3
+ "version": "1.0.0",
4
+ "lockfileVersion": 3,
5
+ "requires": true,
6
+ "packages": {
7
+ "": {
8
+ "name": "jinman-blueprint",
9
+ "version": "1.0.0",
10
+ "license": "ISC"
11
+ }
12
+ }
13
+ }
@@ -0,0 +1 @@
1
+ umvax mbaye nshyizeho iyi reka mbanze nkore test numona i dakora fresh uze gusubiroho after 10min ndaba naya updatinze
@@ -0,0 +1,12 @@
1
+ const mongoose = require('mongoose');
2
+
3
+ const connectDB = async () => {
4
+ try {
5
+ await mongoose.connect('mongodb://localhost:27017/HRMS');
6
+ console.log('MongoDB connected');
7
+ } catch (error) {
8
+ console.error('MongoDB connection error:', error);
9
+ }
10
+ };
11
+
12
+ module.exports = connectDB;
@@ -0,0 +1,138 @@
1
+ const bcrypt = require('bcrypt');
2
+ const User = require('../models/User');
3
+ const Employee = require('../models/Employee');
4
+
5
+ function formatUser(user) {
6
+ return {
7
+ id: user._id,
8
+ name: user.name,
9
+ email: user.email,
10
+ role: user.role || 'user',
11
+ employee: user.employee || null,
12
+ };
13
+ }
14
+
15
+ exports.register = async (req, res) => {
16
+ try {
17
+ const { name, email, password } = req.body;
18
+
19
+ if (!name || !email || !password) {
20
+ return res.status(400).json({ message: 'Name, email, and password are required' });
21
+ }
22
+
23
+ if (password.length < 6) {
24
+ return res.status(400).json({ message: 'Password must be at least 6 characters' });
25
+ }
26
+
27
+ const existing = await User.findOne({ email: email.trim().toLowerCase() });
28
+ if (existing) {
29
+ return res.status(409).json({ message: 'Email already registered' });
30
+ }
31
+
32
+ const userCount = await User.countDocuments();
33
+ if (userCount > 0) {
34
+ return res.status(403).json({ message: 'Registration closed. Ask an admin to create an account.' });
35
+ }
36
+
37
+ const hashedPassword = await bcrypt.hash(password, 10);
38
+ const user = await User.create({
39
+ name: name.trim(),
40
+ email: email.trim().toLowerCase(),
41
+ password: hashedPassword,
42
+ role: 'admin',
43
+ });
44
+
45
+ req.session.userId = user._id;
46
+
47
+ res.status(201).json({
48
+ user: formatUser(user),
49
+ });
50
+ } catch (err) {
51
+ res.status(500).json({ message: err.message });
52
+ }
53
+ };
54
+
55
+ exports.createUser = async (req, res) => {
56
+ try {
57
+ const { employeeId, password } = req.body;
58
+
59
+ if (!employeeId || !password) {
60
+ return res.status(400).json({ message: 'Employee and password are required' });
61
+ }
62
+
63
+ const employee = await Employee.findById(employeeId);
64
+ if (!employee) {
65
+ return res.status(404).json({ message: 'Employee not found' });
66
+ }
67
+
68
+ const existing = await User.findOne({ email: employee.email });
69
+ if (existing) {
70
+ return res.status(409).json({ message: 'A user already exists for this employee' });
71
+ }
72
+
73
+ const hashedPassword = await bcrypt.hash(password, 10);
74
+ const user = await User.create({
75
+ name: `${employee.firstName} ${employee.lastName}`.trim(),
76
+ email: employee.email,
77
+ password: hashedPassword,
78
+ role: 'user',
79
+ employee: employee._id,
80
+ });
81
+
82
+ res.status(201).json({
83
+ user: formatUser(user),
84
+ });
85
+ } catch (err) {
86
+ res.status(500).json({ message: err.message });
87
+ }
88
+ };
89
+
90
+ exports.login = async (req, res) => {
91
+ try {
92
+ const { email, password } = req.body;
93
+
94
+ if (!email || !password) {
95
+ return res.status(400).json({ message: 'Email and password are required' });
96
+ }
97
+
98
+ const user = await User.findOne({ email: email.trim().toLowerCase() });
99
+ if (!user) {
100
+ return res.status(401).json({ message: 'Invalid email or password' });
101
+ }
102
+
103
+ const match = await bcrypt.compare(password, user.password);
104
+ if (!match) {
105
+ return res.status(401).json({ message: 'Invalid email or password' });
106
+ }
107
+
108
+ req.session.userId = user._id;
109
+
110
+ res.json({
111
+ user: formatUser(user),
112
+ });
113
+ } catch (err) {
114
+ res.status(500).json({ message: err.message });
115
+ }
116
+ };
117
+
118
+ exports.getMe = async (req, res) => {
119
+ try {
120
+ res.json({ user: formatUser(req.user) });
121
+ } catch (err) {
122
+ res.status(500).json({ message: err.message });
123
+ }
124
+ };
125
+
126
+ exports.logout = async (req, res) => {
127
+ try {
128
+ req.session.destroy((err) => {
129
+ if (err) {
130
+ return res.status(500).json({ message: 'Logout failed' });
131
+ }
132
+ res.clearCookie('connect.sid');
133
+ res.json({ message: 'Logged out successfully' });
134
+ });
135
+ } catch (err) {
136
+ res.status(500).json({ message: err.message });
137
+ }
138
+ };
@@ -0,0 +1,74 @@
1
+ const Department = require('../models/Department');
2
+
3
+ exports.addDepartment = async (req, res) => {
4
+ try {
5
+ const { departmentName } = req.body;
6
+
7
+ if (!departmentName) {
8
+ return res.status(400).json({ message: 'Department name is required' });
9
+ }
10
+
11
+ const existing = await Department.findOne({ departmentName: departmentName.trim() });
12
+ if (existing) {
13
+ return res.status(409).json({ message: 'Department already exists' });
14
+ }
15
+
16
+ const dept = await Department.create({ departmentName: departmentName.trim() });
17
+ res.status(201).json(dept);
18
+ } catch (err) {
19
+ res.status(500).json({ message: err.message });
20
+ }
21
+ };
22
+
23
+ exports.getDepartments = async (req, res) => {
24
+ try {
25
+ const departments = await Department.find();
26
+ res.json(departments);
27
+ } catch (err) {
28
+ res.status(500).json({ message: err.message });
29
+ }
30
+ };
31
+
32
+ exports.updateDepartment = async (req, res) => {
33
+ try {
34
+ const { departmentName } = req.body;
35
+
36
+ if (!departmentName) {
37
+ return res.status(400).json({ message: 'Department name is required' });
38
+ }
39
+
40
+ const department = await Department.findById(req.params.id);
41
+ if (!department) {
42
+ return res.status(404).json({ message: 'Department not found' });
43
+ }
44
+
45
+ const existing = await Department.findOne({
46
+ departmentName: departmentName.trim(),
47
+ _id: { $ne: req.params.id },
48
+ });
49
+ if (existing) {
50
+ return res.status(409).json({ message: 'Department already exists' });
51
+ }
52
+
53
+ department.departmentName = departmentName.trim();
54
+ await department.save();
55
+
56
+ res.json(department);
57
+ } catch (err) {
58
+ res.status(500).json({ message: err.message });
59
+ }
60
+ };
61
+
62
+ exports.deleteDepartment = async (req, res) => {
63
+ try {
64
+ const department = await Department.findById(req.params.id);
65
+ if (!department) {
66
+ return res.status(404).json({ message: 'Department not found' });
67
+ }
68
+
69
+ await Department.findByIdAndDelete(req.params.id);
70
+ res.json({ message: 'Department deleted successfully' });
71
+ } catch (err) {
72
+ res.status(500).json({ message: err.message });
73
+ }
74
+ };
@@ -0,0 +1,204 @@
1
+ const Employee = require('../models/Employee');
2
+ const Department = require('../models/Department');
3
+ const Position = require('../models/Position');
4
+ const User = require('../models/User');
5
+
6
+ exports.addEmployee = async (req, res) => {
7
+ try {
8
+ const {
9
+ userName,
10
+ firstName,
11
+ lastName,
12
+ email,
13
+ gender,
14
+ dateOfBirth,
15
+ telephone,
16
+ address,
17
+ hireDate,
18
+ status,
19
+ department,
20
+ position,
21
+ } = req.body;
22
+
23
+ if (
24
+ !firstName ||
25
+ !lastName ||
26
+ !email ||
27
+ !gender ||
28
+ !dateOfBirth ||
29
+ !telephone ||
30
+ !address ||
31
+ !hireDate ||
32
+ !status ||
33
+ !department ||
34
+ !position
35
+ ) {
36
+ return res.status(400).json({ message: 'All employee fields are required' });
37
+ }
38
+
39
+ const existing = await Employee.findOne({ email: email.toLowerCase() });
40
+ if (existing) {
41
+ return res.status(409).json({ message: 'Employee email already exists' });
42
+ }
43
+
44
+ const departmentExists = await Department.findById(department);
45
+ if (!departmentExists) {
46
+ return res.status(404).json({ message: 'Department not found' });
47
+ }
48
+
49
+ const positionExists = await Position.findById(position);
50
+ if (!positionExists) {
51
+ return res.status(404).json({ message: 'Position not found' });
52
+ }
53
+
54
+ const employee = await Employee.create({
55
+ userName,
56
+ firstName: firstName.trim(),
57
+ lastName: lastName.trim(),
58
+ email: email.toLowerCase(),
59
+ gender,
60
+ dateOfBirth,
61
+ telephone: telephone.trim(),
62
+ address: address.trim(),
63
+ hireDate,
64
+ status,
65
+ department,
66
+ position,
67
+ });
68
+
69
+ if (email) {
70
+ const user = await User.findOne({ email: email.toLowerCase() });
71
+ if (user) {
72
+ user.employee = employee._id;
73
+ await user.save();
74
+ }
75
+ }
76
+
77
+ res.status(201).json(employee);
78
+ } catch (err) {
79
+ res.status(500).json({ message: err.message });
80
+ }
81
+ };
82
+
83
+ exports.getEmployees = async (req, res) => {
84
+ try {
85
+ const employees = await Employee.find().populate('department position');
86
+ res.json(employees);
87
+ } catch (err) {
88
+ res.status(500).json({ message: err.message });
89
+ }
90
+ };
91
+
92
+ exports.getEmployee = async (req, res) => {
93
+ try {
94
+ const employee = await Employee.findById(req.params.id).populate('department position');
95
+ if (!employee) {
96
+ return res.status(404).json({ message: 'Employee not found' });
97
+ }
98
+ res.json(employee);
99
+ } catch (err) {
100
+ res.status(500).json({ message: err.message });
101
+ }
102
+ };
103
+
104
+ exports.updateEmployee = async (req, res) => {
105
+ try {
106
+ const employee = await Employee.findById(req.params.id);
107
+ if (!employee) {
108
+ return res.status(404).json({ message: 'Employee not found' });
109
+ }
110
+
111
+ const {
112
+ userName,
113
+ firstName,
114
+ lastName,
115
+ email,
116
+ gender,
117
+ dateOfBirth,
118
+ telephone,
119
+ address,
120
+ hireDate,
121
+ status,
122
+ department,
123
+ position,
124
+ } = req.body;
125
+
126
+ if (
127
+ !firstName ||
128
+ !lastName ||
129
+ !email ||
130
+ !gender ||
131
+ !dateOfBirth ||
132
+ !telephone ||
133
+ !address ||
134
+ !hireDate ||
135
+ !status ||
136
+ !department ||
137
+ !position
138
+ ) {
139
+ return res.status(400).json({ message: 'All employee fields are required' });
140
+ }
141
+
142
+ const existing = await Employee.findOne({
143
+ email: email.toLowerCase(),
144
+ _id: { $ne: req.params.id },
145
+ });
146
+ if (existing) {
147
+ return res.status(409).json({ message: 'Employee email already exists' });
148
+ }
149
+
150
+ const departmentExists = await Department.findById(department);
151
+ if (!departmentExists) {
152
+ return res.status(404).json({ message: 'Department not found' });
153
+ }
154
+
155
+ const positionExists = await Position.findById(position);
156
+ if (!positionExists) {
157
+ return res.status(404).json({ message: 'Position not found' });
158
+ }
159
+
160
+ const oldEmail = employee.email;
161
+
162
+ employee.userName = userName;
163
+ employee.firstName = firstName.trim();
164
+ employee.lastName = lastName.trim();
165
+ employee.email = email.toLowerCase();
166
+ employee.gender = gender;
167
+ employee.dateOfBirth = dateOfBirth;
168
+ employee.telephone = telephone.trim();
169
+ employee.address = address.trim();
170
+ employee.hireDate = hireDate;
171
+ employee.status = status;
172
+ employee.department = department;
173
+ employee.position = position;
174
+
175
+ await employee.save();
176
+
177
+ if (oldEmail !== email.toLowerCase()) {
178
+ const user = await User.findOne({ email: oldEmail });
179
+ if (user) {
180
+ user.email = email.toLowerCase();
181
+ await user.save();
182
+ }
183
+ }
184
+
185
+ const updatedEmployee = await Employee.findById(req.params.id).populate('department position');
186
+ res.json(updatedEmployee);
187
+ } catch (err) {
188
+ res.status(500).json({ message: err.message });
189
+ }
190
+ };
191
+
192
+ exports.deleteEmployee = async (req, res) => {
193
+ try {
194
+ const employee = await Employee.findById(req.params.id);
195
+ if (!employee) {
196
+ return res.status(404).json({ message: 'Employee not found' });
197
+ }
198
+
199
+ await Employee.findByIdAndDelete(req.params.id);
200
+ res.json({ message: 'Employee deleted successfully' });
201
+ } catch (err) {
202
+ res.status(500).json({ message: err.message });
203
+ }
204
+ };
@@ -0,0 +1,78 @@
1
+ const Position = require('../models/Position');
2
+
3
+ exports.addPosition = async (req, res) => {
4
+ try {
5
+ const { posName, requiredQualification } = req.body;
6
+
7
+ if (!posName || !requiredQualification) {
8
+ return res.status(400).json({ message: 'Position name and qualification are required' });
9
+ }
10
+
11
+ const existing = await Position.findOne({ posName: posName.trim() });
12
+ if (existing) {
13
+ return res.status(409).json({ message: 'Position already exists' });
14
+ }
15
+
16
+ const position = await Position.create({
17
+ posName: posName.trim(),
18
+ requiredQualification: requiredQualification.trim(),
19
+ });
20
+ res.status(201).json(position);
21
+ } catch (err) {
22
+ res.status(500).json({ message: err.message });
23
+ }
24
+ };
25
+
26
+ exports.getPositions = async (req, res) => {
27
+ try {
28
+ const positions = await Position.find();
29
+ res.json(positions);
30
+ } catch (err) {
31
+ res.status(500).json({ message: err.message });
32
+ }
33
+ };
34
+
35
+ exports.updatePosition = async (req, res) => {
36
+ try {
37
+ const { posName, requiredQualification } = req.body;
38
+
39
+ if (!posName || !requiredQualification) {
40
+ return res.status(400).json({ message: 'Position name and qualification are required' });
41
+ }
42
+
43
+ const position = await Position.findById(req.params.id);
44
+ if (!position) {
45
+ return res.status(404).json({ message: 'Position not found' });
46
+ }
47
+
48
+ const existing = await Position.findOne({
49
+ posName: posName.trim(),
50
+ _id: { $ne: req.params.id },
51
+ });
52
+ if (existing) {
53
+ return res.status(409).json({ message: 'Position already exists' });
54
+ }
55
+
56
+ position.posName = posName.trim();
57
+ position.requiredQualification = requiredQualification.trim();
58
+ await position.save();
59
+
60
+ res.json(position);
61
+ } catch (err) {
62
+ res.status(500).json({ message: err.message });
63
+ }
64
+ };
65
+
66
+ exports.deletePosition = async (req, res) => {
67
+ try {
68
+ const position = await Position.findById(req.params.id);
69
+ if (!position) {
70
+ return res.status(404).json({ message: 'Position not found' });
71
+ }
72
+
73
+ await Position.findByIdAndDelete(req.params.id);
74
+ res.json({ message: 'Position deleted successfully' });
75
+ } catch (err) {
76
+ res.status(500).json({ message: err.message });
77
+ }
78
+ };
@@ -0,0 +1,45 @@
1
+ const Employee = require('../models/Employee');
2
+
3
+ const ON_LEAVE_STATUS = 'on leave';
4
+
5
+ exports.getOnLeaveByDepartment = async (req, res) => {
6
+ try {
7
+ const onLeaveEmployees = await Employee.find({ status: ON_LEAVE_STATUS })
8
+ .populate('department position')
9
+ .sort({ lastName: 1, firstName: 1 });
10
+
11
+ const byDepartment = {};
12
+
13
+ onLeaveEmployees.forEach((employee) => {
14
+ const deptName = employee.department?.departmentName || 'Unassigned';
15
+ if (!byDepartment[deptName]) {
16
+ byDepartment[deptName] = [];
17
+ }
18
+ byDepartment[deptName].push({
19
+ id: employee._id,
20
+ firstName: employee.firstName,
21
+ lastName: employee.lastName,
22
+ email: employee.email,
23
+ telephone: employee.telephone,
24
+ position: employee.position?.posName || 'N/A',
25
+ status: employee.status,
26
+ });
27
+ });
28
+
29
+ const departments = Object.keys(byDepartment)
30
+ .sort()
31
+ .map((departmentName) => ({
32
+ departmentName,
33
+ employees: byDepartment[departmentName],
34
+ count: byDepartment[departmentName].length,
35
+ }));
36
+
37
+ res.json({
38
+ reportTitle: 'Employee Status Report — On Leave',
39
+ totalOnLeave: onLeaveEmployees.length,
40
+ departments,
41
+ });
42
+ } catch (err) {
43
+ res.status(500).json({ message: err.message });
44
+ }
45
+ };
@@ -0,0 +1,28 @@
1
+
2
+ const User = require('../models/User');
3
+
4
+ exports.protect = async (req, res, next) => {
5
+ try {
6
+ if (!req.session || !req.session.userId) {
7
+ return res.status(401).json({ message: 'Not authorized' });
8
+ }
9
+
10
+ const user = await User.findById(req.session.userId).select('-password');
11
+
12
+ if (!user) {
13
+ return res.status(401).json({ message: 'Not authorized' });
14
+ }
15
+
16
+ req.user = user;
17
+ next();
18
+ } catch (err) {
19
+ return res.status(401).json({ message: 'Not authorized' });
20
+ }
21
+ };
22
+
23
+ exports.admin = (req, res, next) => {
24
+ if (!req.user || req.user.role !== 'admin') {
25
+ return res.status(403).json({ message: 'Admin access required' });
26
+ }
27
+ next();
28
+ };
@@ -0,0 +1,15 @@
1
+ const mongoose = require('mongoose');
2
+
3
+ const departmentSchema = new mongoose.Schema(
4
+ {
5
+ departmentName: {
6
+ type: String,
7
+ required: true,
8
+ unique: true,
9
+ trim: true,
10
+ },
11
+ },
12
+ { timestamps: true }
13
+ );
14
+
15
+ module.exports = mongoose.model('Department', departmentSchema);
@@ -0,0 +1,73 @@
1
+ const mongoose = require('mongoose');
2
+
3
+ const EMPLOYEE_STATUSES = ['on leave', 'left', 'blacklisted', 'deceased', 'on mission'];
4
+
5
+ const employeeSchema = new mongoose.Schema(
6
+ {
7
+ userName: {
8
+ type: String,
9
+ trim: true,
10
+ },
11
+ firstName: {
12
+ type: String,
13
+ required: true,
14
+ trim: true,
15
+ },
16
+ lastName: {
17
+ type: String,
18
+ required: true,
19
+ trim: true,
20
+ },
21
+ email: {
22
+ type: String,
23
+ required: true,
24
+ unique: true,
25
+ lowercase: true,
26
+ trim: true,
27
+ },
28
+ gender: {
29
+ type: String,
30
+ required: true,
31
+ trim: true,
32
+ },
33
+ dateOfBirth: {
34
+ type: Date,
35
+ required: true,
36
+ },
37
+ telephone: {
38
+ type: String,
39
+ required: true,
40
+ trim: true,
41
+ },
42
+ address: {
43
+ type: String,
44
+ required: true,
45
+ trim: true,
46
+ },
47
+ hireDate: {
48
+ type: Date,
49
+ required: true,
50
+ },
51
+ status: {
52
+ type: String,
53
+ required: true,
54
+ enum: EMPLOYEE_STATUSES,
55
+ default: 'on mission',
56
+ },
57
+ department: {
58
+ type: mongoose.Schema.Types.ObjectId,
59
+ ref: 'Department',
60
+ required: true,
61
+ },
62
+ position: {
63
+ type: mongoose.Schema.Types.ObjectId,
64
+ ref: 'Position',
65
+ required: true,
66
+ },
67
+ },
68
+ { timestamps: true }
69
+ );
70
+
71
+ employeeSchema.statics.STATUSES = EMPLOYEE_STATUSES;
72
+
73
+ module.exports = mongoose.model('Employee', employeeSchema);