aloux-iam 0.0.114 → 0.0.115
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.
- package/.gitattributes +2 -2
- package/CONTRIBUTING.md +1 -1
- package/LICENSE +21 -21
- package/README.md +271 -271
- package/index.js +38 -38
- package/lib/config/utils.js +13 -13
- package/lib/controllers/auth.js +166 -166
- package/lib/controllers/functions.js +86 -86
- package/lib/controllers/history.js +97 -97
- package/lib/controllers/label.js +82 -0
- package/lib/controllers/log.js +268 -0
- package/lib/controllers/menu.js +101 -101
- package/lib/controllers/operationsAWS.js +228 -228
- package/lib/controllers/permission.js +90 -90
- package/lib/controllers/user.js +880 -848
- package/lib/middleware.js +146 -146
- package/lib/models/Business.js +14 -14
- package/lib/models/Functions.js +13 -13
- package/lib/models/History.js +15 -15
- package/lib/models/Label.js +13 -0
- package/lib/models/Log.js +11 -0
- package/lib/models/Menu.js +17 -17
- package/lib/models/Permission.js +16 -16
- package/lib/models/User.js +115 -115
- package/lib/models/UserProvisional.js +10 -10
- package/lib/router.js +104 -82
- package/lib/services/auth.js +956 -956
- package/lib/services/bigQuery.js +87 -87
- package/lib/services/s3.js +71 -71
- package/lib/services/ses.js +97 -97
- package/lib/services/sns.js +21 -21
- package/lib/services/user.js +99 -99
- package/lib/swagger.yaml +1231 -1231
- package/package.json +38 -38
|
@@ -1,97 +1,97 @@
|
|
|
1
|
-
const History = require("../models/History");
|
|
2
|
-
const self = module.exports;
|
|
3
|
-
|
|
4
|
-
self.create = async (data) => {
|
|
5
|
-
try {
|
|
6
|
-
const history = new History({
|
|
7
|
-
method: data.originalMethod,
|
|
8
|
-
path: data.route.path,
|
|
9
|
-
payload: data.body,
|
|
10
|
-
createdAt: Date.now(),
|
|
11
|
-
});
|
|
12
|
-
const newHistory = await history.save();
|
|
13
|
-
return newHistory;
|
|
14
|
-
} catch (error) {
|
|
15
|
-
return error;
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
self.response = async (_history, response, _createdBy, permission) => {
|
|
20
|
-
try {
|
|
21
|
-
if (_createdBy) {
|
|
22
|
-
await History.updateOne(
|
|
23
|
-
{ _id: _history },
|
|
24
|
-
{ response: response, _createdBy: _createdBy, permission: permission }
|
|
25
|
-
);
|
|
26
|
-
} else {
|
|
27
|
-
await History.updateOne(
|
|
28
|
-
{ _id: _history },
|
|
29
|
-
{ response: response, permission: permission }
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
return true;
|
|
33
|
-
} catch (error) {
|
|
34
|
-
return error;
|
|
35
|
-
}
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
self.retrieve = async (req, res) => {
|
|
39
|
-
try {
|
|
40
|
-
let query = { $and: [] };
|
|
41
|
-
const response = { items: [], count: 0 };
|
|
42
|
-
|
|
43
|
-
if (req.body?.filter?.method) {
|
|
44
|
-
query.$and.push({ method: req.body.filter.method });
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
if (req.body?.filter?.description) {
|
|
48
|
-
query.$and.push({
|
|
49
|
-
permission: { $regex: req.body.filter.description, $options: "i" },
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (req.body?.filter?._user) {
|
|
54
|
-
query.$and.push({ _createdBy: req.body.filter._user });
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
if (req.body.filter?.dateStart > 0 && req.body.filter?.dateEnd > 0) {
|
|
58
|
-
query.$and.push({
|
|
59
|
-
createdAt: {
|
|
60
|
-
$gte: req.body.filter.dateStart,
|
|
61
|
-
$lte: req.body.filter.dateEnd,
|
|
62
|
-
},
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
if (query.$and.length === 0) {
|
|
67
|
-
query = {};
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
response.count = await History.countDocuments(query);
|
|
71
|
-
response.items = await History.find(query)
|
|
72
|
-
.populate({ path: "_createdBy", select: { name: 1, lastName: 1 } })
|
|
73
|
-
.sort({ createdAt: -1 })
|
|
74
|
-
.skip((req.body.config.page - 1) * req.body.config.itemsPerPage)
|
|
75
|
-
.limit(req.body.config.itemsPerPage)
|
|
76
|
-
.lean();
|
|
77
|
-
|
|
78
|
-
res.status(200).send(response);
|
|
79
|
-
} catch (error) {
|
|
80
|
-
res.status(400).send(error);
|
|
81
|
-
}
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
self.detail = async (req, res) => {
|
|
85
|
-
try {
|
|
86
|
-
const history = await History.findOne({ _id: req.params.HISTORY_ID });
|
|
87
|
-
if (!history) {
|
|
88
|
-
return res.status(404).send({
|
|
89
|
-
error: "No se encontró el elemento",
|
|
90
|
-
suggestion: "Verifica que el id del registro sea correcto",
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
res.status(200).send(history);
|
|
94
|
-
} catch (error) {
|
|
95
|
-
res.status(400).send(error);
|
|
96
|
-
}
|
|
97
|
-
};
|
|
1
|
+
const History = require("../models/History");
|
|
2
|
+
const self = module.exports;
|
|
3
|
+
|
|
4
|
+
self.create = async (data) => {
|
|
5
|
+
try {
|
|
6
|
+
const history = new History({
|
|
7
|
+
method: data.originalMethod,
|
|
8
|
+
path: data.route.path,
|
|
9
|
+
payload: data.body,
|
|
10
|
+
createdAt: Date.now(),
|
|
11
|
+
});
|
|
12
|
+
const newHistory = await history.save();
|
|
13
|
+
return newHistory;
|
|
14
|
+
} catch (error) {
|
|
15
|
+
return error;
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
self.response = async (_history, response, _createdBy, permission) => {
|
|
20
|
+
try {
|
|
21
|
+
if (_createdBy) {
|
|
22
|
+
await History.updateOne(
|
|
23
|
+
{ _id: _history },
|
|
24
|
+
{ response: response, _createdBy: _createdBy, permission: permission }
|
|
25
|
+
);
|
|
26
|
+
} else {
|
|
27
|
+
await History.updateOne(
|
|
28
|
+
{ _id: _history },
|
|
29
|
+
{ response: response, permission: permission }
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
return true;
|
|
33
|
+
} catch (error) {
|
|
34
|
+
return error;
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
self.retrieve = async (req, res) => {
|
|
39
|
+
try {
|
|
40
|
+
let query = { $and: [] };
|
|
41
|
+
const response = { items: [], count: 0 };
|
|
42
|
+
|
|
43
|
+
if (req.body?.filter?.method) {
|
|
44
|
+
query.$and.push({ method: req.body.filter.method });
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (req.body?.filter?.description) {
|
|
48
|
+
query.$and.push({
|
|
49
|
+
permission: { $regex: req.body.filter.description, $options: "i" },
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (req.body?.filter?._user) {
|
|
54
|
+
query.$and.push({ _createdBy: req.body.filter._user });
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (req.body.filter?.dateStart > 0 && req.body.filter?.dateEnd > 0) {
|
|
58
|
+
query.$and.push({
|
|
59
|
+
createdAt: {
|
|
60
|
+
$gte: req.body.filter.dateStart,
|
|
61
|
+
$lte: req.body.filter.dateEnd,
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (query.$and.length === 0) {
|
|
67
|
+
query = {};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
response.count = await History.countDocuments(query);
|
|
71
|
+
response.items = await History.find(query)
|
|
72
|
+
.populate({ path: "_createdBy", select: { name: 1, lastName: 1 } })
|
|
73
|
+
.sort({ createdAt: -1 })
|
|
74
|
+
.skip((req.body.config.page - 1) * req.body.config.itemsPerPage)
|
|
75
|
+
.limit(req.body.config.itemsPerPage)
|
|
76
|
+
.lean();
|
|
77
|
+
|
|
78
|
+
res.status(200).send(response);
|
|
79
|
+
} catch (error) {
|
|
80
|
+
res.status(400).send(error);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
self.detail = async (req, res) => {
|
|
85
|
+
try {
|
|
86
|
+
const history = await History.findOne({ _id: req.params.HISTORY_ID });
|
|
87
|
+
if (!history) {
|
|
88
|
+
return res.status(404).send({
|
|
89
|
+
error: "No se encontró el elemento",
|
|
90
|
+
suggestion: "Verifica que el id del registro sea correcto",
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
res.status(200).send(history);
|
|
94
|
+
} catch (error) {
|
|
95
|
+
res.status(400).send(error);
|
|
96
|
+
}
|
|
97
|
+
};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
const Label = require("../models/Label");
|
|
2
|
+
const self = module.exports;
|
|
3
|
+
|
|
4
|
+
self.create = async (req, res) => {
|
|
5
|
+
try {
|
|
6
|
+
const label = new Label(req.body);
|
|
7
|
+
label.createdAt = new Date().getTime();
|
|
8
|
+
label.status = "Activo";
|
|
9
|
+
await label.save();
|
|
10
|
+
res.status(201).send(label);
|
|
11
|
+
} catch (error) {
|
|
12
|
+
res.status(400).send({ error: error.message });
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
self.update = async (req, resp) => {
|
|
17
|
+
try {
|
|
18
|
+
await new Label(req.body).validate();
|
|
19
|
+
const _id = req.params.LABEL_ID;
|
|
20
|
+
const count = await Label.findOne({ _id }).countDocuments();
|
|
21
|
+
if (!count) throw new Error("Upss! No se encontró el registro");
|
|
22
|
+
req.body.lastUpdate = new Date().getTime();
|
|
23
|
+
const result = await Label.updateOne({ _id }, req.body);
|
|
24
|
+
resp.status(200).send(req.body);
|
|
25
|
+
} catch (error) {
|
|
26
|
+
resp.status(400).send({ error: error.message });
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
self.status = async (req, resp) => {
|
|
30
|
+
try {
|
|
31
|
+
const _id = req.params.LABEL_ID;
|
|
32
|
+
const user = await Label.findOne({ _id });
|
|
33
|
+
if (!user) throw new Error("Upss! No se encontró el Elemento");
|
|
34
|
+
user.status = req.body.status;
|
|
35
|
+
user.lastUpdate = new Date().getTime();
|
|
36
|
+
const result = await user.save();
|
|
37
|
+
resp.status(200).send(result);
|
|
38
|
+
} catch (error) {
|
|
39
|
+
resp.status(400).send({ error: error.message });
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
self.retrieve = async (req, res) => {
|
|
43
|
+
try {
|
|
44
|
+
const consulta = await Label.find({}).sort({ index: 1 });
|
|
45
|
+
if (!consulta) res.status(404).send();
|
|
46
|
+
res.status(200).send(consulta);
|
|
47
|
+
} catch (error) {
|
|
48
|
+
res.status(400).send(error);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
self.get = async (req, res) => {
|
|
53
|
+
try {
|
|
54
|
+
const _id = req.params.LABEL_ID;
|
|
55
|
+
const label = await Label.findOne({ _id });
|
|
56
|
+
if (!label) res.status(404).send();
|
|
57
|
+
res.status(200).send(label);
|
|
58
|
+
} catch (error) {
|
|
59
|
+
res.status(400).send(error);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
self.delete = async (req, res) => {
|
|
64
|
+
try {
|
|
65
|
+
const _id = req.params.LABEL_ID;
|
|
66
|
+
const response = await Label.deleteOne({ _id });
|
|
67
|
+
if (!response.deletedCount)
|
|
68
|
+
res.status(404).send({ error: "El registro no existe" });
|
|
69
|
+
else res.status(200).send({});
|
|
70
|
+
} catch (error) {
|
|
71
|
+
res.status(400).send({ error: error.message });
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
self.count = async (req, res) => {
|
|
76
|
+
try {
|
|
77
|
+
let result = await Label.find({}).countDocuments();
|
|
78
|
+
res.status(200).send({ count: result });
|
|
79
|
+
} catch (error) {
|
|
80
|
+
res.status(400).send({ error: error.message });
|
|
81
|
+
}
|
|
82
|
+
};
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
const Log = require("../models/Log");
|
|
2
|
+
const Label = require("../models/Label");
|
|
3
|
+
const self = module.exports;
|
|
4
|
+
|
|
5
|
+
self.create = async (req, res) => {
|
|
6
|
+
try {
|
|
7
|
+
const log = new Log(req.body);
|
|
8
|
+
log.createdAt = new Date().getTime();
|
|
9
|
+
log._user = req.user._id;
|
|
10
|
+
const label = await Label.findOne(
|
|
11
|
+
{ label: req.body.label },
|
|
12
|
+
{ _id: 1 }
|
|
13
|
+
).lean();
|
|
14
|
+
if (label) {
|
|
15
|
+
log._label = label._id;
|
|
16
|
+
await log.save();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
res.status(201).send(log);
|
|
20
|
+
} catch (error) {
|
|
21
|
+
res.status(400).send({ error: error.message });
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
self.update = async (req, resp) => {
|
|
26
|
+
try {
|
|
27
|
+
await new Log(req.body).validate();
|
|
28
|
+
const _id = req.params.LOG_ID;
|
|
29
|
+
const count = await Log.findOne({ _id }).countDocuments();
|
|
30
|
+
if (!count) throw new Error("Upss! No se encontró el registro");
|
|
31
|
+
req.body.lastUpdate = new Date().getTime();
|
|
32
|
+
const result = await Log.updateOne({ _id }, req.body);
|
|
33
|
+
resp.status(200).send(req.body);
|
|
34
|
+
} catch (error) {
|
|
35
|
+
resp.status(400).send({ error: error.message });
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
self.status = async (req, resp) => {
|
|
39
|
+
try {
|
|
40
|
+
const _id = req.params.LOG_ID;
|
|
41
|
+
const user = await Log.findOne({ _id });
|
|
42
|
+
if (!user) throw new Error("Upss! No se encontró el Elemento");
|
|
43
|
+
user.status = req.body.status;
|
|
44
|
+
user.lastUpdate = new Date().getTime();
|
|
45
|
+
const result = await user.save();
|
|
46
|
+
resp.status(200).send(result);
|
|
47
|
+
} catch (error) {
|
|
48
|
+
resp.status(400).send({ error: error.message });
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
self.retrieve = async (req, res) => {
|
|
52
|
+
try {
|
|
53
|
+
let query = {};
|
|
54
|
+
|
|
55
|
+
if (req.body.users.length) {
|
|
56
|
+
query = {
|
|
57
|
+
_user: { $in: req.body.users },
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const consulta = await Log.find(query)
|
|
62
|
+
.populate([
|
|
63
|
+
{ path: "_label" },
|
|
64
|
+
{ path: "_user", select: { name: 1, lastName: 1 } },
|
|
65
|
+
])
|
|
66
|
+
.sort({ createdAt: 1 })
|
|
67
|
+
.lean();
|
|
68
|
+
|
|
69
|
+
const response = {
|
|
70
|
+
dataset0: { field: "Total de operaciones", count: consulta.length },
|
|
71
|
+
dataset1: consulta,
|
|
72
|
+
dataset2: processDataset2(consulta),
|
|
73
|
+
dataset3: processDataset3(consulta),
|
|
74
|
+
dataset4: processDataset4(consulta),
|
|
75
|
+
dataset5: processDataset5(consulta),
|
|
76
|
+
dataset6: processDataset6(consulta),
|
|
77
|
+
dataset7: processDataset7(consulta),
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
res.status(200).send(response);
|
|
81
|
+
} catch (error) {
|
|
82
|
+
console.error(error);
|
|
83
|
+
res.status(400).send(error);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
function formatDate(date) {
|
|
88
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
89
|
+
const monthNames = [
|
|
90
|
+
"Ene",
|
|
91
|
+
"Feb",
|
|
92
|
+
"Mar",
|
|
93
|
+
"Abr",
|
|
94
|
+
"May",
|
|
95
|
+
"Jun",
|
|
96
|
+
"Jul",
|
|
97
|
+
"Ago",
|
|
98
|
+
"Sep",
|
|
99
|
+
"Oct",
|
|
100
|
+
"Nov",
|
|
101
|
+
"Dic",
|
|
102
|
+
];
|
|
103
|
+
const month = monthNames[date.getMonth()];
|
|
104
|
+
const year = date.getFullYear();
|
|
105
|
+
return `${day} ${month} ${year}`;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function processDataset2(consulta) {
|
|
109
|
+
const labelCounts = consulta.reduce((acc, item) => {
|
|
110
|
+
const label = item._label.label;
|
|
111
|
+
acc[label] = (acc[label] || 0) + 1;
|
|
112
|
+
return acc;
|
|
113
|
+
}, {});
|
|
114
|
+
|
|
115
|
+
return {
|
|
116
|
+
field: "Distribución de acciones",
|
|
117
|
+
counts: Object.values(labelCounts),
|
|
118
|
+
operations: Object.keys(labelCounts),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function processDataset3(consulta) {
|
|
123
|
+
const labelCounts = consulta.reduce((acc, item) => {
|
|
124
|
+
const label = item._label.label;
|
|
125
|
+
acc[label] = (acc[label] || 0) + 1;
|
|
126
|
+
return acc;
|
|
127
|
+
}, {});
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
field: "Distribución de acciones",
|
|
131
|
+
items: Object.keys(labelCounts).map((label) => ({
|
|
132
|
+
addGroup: label,
|
|
133
|
+
totalResponse: labelCounts[label],
|
|
134
|
+
})),
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function processDataset4(consulta) {
|
|
139
|
+
const dateCounts = consulta.reduce((acc, item) => {
|
|
140
|
+
const date = formatDate(new Date(item.createdAt));
|
|
141
|
+
acc[date] = (acc[date] || 0) + 1;
|
|
142
|
+
return acc;
|
|
143
|
+
}, {});
|
|
144
|
+
|
|
145
|
+
return {
|
|
146
|
+
field: "Actividad en la plataforma",
|
|
147
|
+
counts: Object.values(dateCounts),
|
|
148
|
+
actionsName: Object.keys(dateCounts),
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function processDataset5(consulta) {
|
|
153
|
+
const labelCountsByDate = {};
|
|
154
|
+
const categories = new Set();
|
|
155
|
+
|
|
156
|
+
consulta.forEach((item) => {
|
|
157
|
+
const date = formatDate(new Date(item.createdAt));
|
|
158
|
+
const label = item._label.label;
|
|
159
|
+
categories.add(date);
|
|
160
|
+
|
|
161
|
+
if (!labelCountsByDate[date]) {
|
|
162
|
+
labelCountsByDate[date] = {};
|
|
163
|
+
}
|
|
164
|
+
labelCountsByDate[date][label] = (labelCountsByDate[date][label] || 0) + 1;
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
const uniqueLabels = new Set(
|
|
168
|
+
Object.values(labelCountsByDate).flatMap(Object.keys)
|
|
169
|
+
);
|
|
170
|
+
const series = Array.from(uniqueLabels).map((label) => ({
|
|
171
|
+
name: label,
|
|
172
|
+
data: Array.from(categories).map(
|
|
173
|
+
(date) => labelCountsByDate[date]?.[label] || 0
|
|
174
|
+
),
|
|
175
|
+
}));
|
|
176
|
+
|
|
177
|
+
return {
|
|
178
|
+
field: "Actividad en la plataforma por operación",
|
|
179
|
+
categories: Array.from(categories),
|
|
180
|
+
series: series,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function processDataset6(data) {
|
|
185
|
+
const userActivity = {};
|
|
186
|
+
|
|
187
|
+
// Count activity per user. Assuming data contains _user with name and lastName
|
|
188
|
+
data.forEach((item) => {
|
|
189
|
+
const fullName = `${item._user.name} ${item._user.lastName}`;
|
|
190
|
+
userActivity[fullName] = (userActivity[fullName] || 0) + 1;
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
// Sort users by activity count in descending order
|
|
194
|
+
const sortedUsers = Object.entries(userActivity).sort(
|
|
195
|
+
([, countA], [, countB]) => countB - countA
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
// Extract top 10 users
|
|
199
|
+
const topUsers = sortedUsers.slice(0, 10);
|
|
200
|
+
|
|
201
|
+
// Build the result object
|
|
202
|
+
const result = {
|
|
203
|
+
counts: topUsers.map(([, count]) => count),
|
|
204
|
+
actionsName: topUsers.map(([fullName]) => fullName.split(" ")),
|
|
205
|
+
field: "Usuarios con mas actividad en la plataforma",
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
return result;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function processDataset7(data) {
|
|
212
|
+
const userActivity = {};
|
|
213
|
+
|
|
214
|
+
// Count activity per user. Assuming data contains _user with name and lastName
|
|
215
|
+
data.forEach((item) => {
|
|
216
|
+
const fullName = `${item._user.name} ${item._user.lastName}`;
|
|
217
|
+
userActivity[fullName] = (userActivity[fullName] || 0) + 1;
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
// Sort users by activity count in ascending order
|
|
221
|
+
const sortedUsers = Object.entries(userActivity).sort(
|
|
222
|
+
([, countA], [, countB]) => countA - countB
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
// Extract top 10 least active users
|
|
226
|
+
const leastActiveUsers = sortedUsers.slice(0, 10);
|
|
227
|
+
|
|
228
|
+
// Build the result object
|
|
229
|
+
const result = {
|
|
230
|
+
counts: leastActiveUsers.map(([, count]) => count),
|
|
231
|
+
actionsName: leastActiveUsers.map(([fullName]) => fullName.split(" ")),
|
|
232
|
+
field: "Usuarios con menos actividad en la plataforma",
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
return result;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
self.get = async (req, res) => {
|
|
239
|
+
try {
|
|
240
|
+
const _id = req.params.LOG_ID;
|
|
241
|
+
const log = await Log.findOne({ _id });
|
|
242
|
+
if (!log) res.status(404).send();
|
|
243
|
+
res.status(200).send(log);
|
|
244
|
+
} catch (error) {
|
|
245
|
+
res.status(400).send(error);
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
self.delete = async (req, res) => {
|
|
250
|
+
try {
|
|
251
|
+
const _id = req.params.LOG_ID;
|
|
252
|
+
const response = await Log.deleteOne({ _id });
|
|
253
|
+
if (!response.deletedCount)
|
|
254
|
+
res.status(404).send({ error: "El registro no existe" });
|
|
255
|
+
else res.status(200).send({});
|
|
256
|
+
} catch (error) {
|
|
257
|
+
res.status(400).send({ error: error.message });
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
self.count = async (req, res) => {
|
|
262
|
+
try {
|
|
263
|
+
let result = await Log.find({}).countDocuments();
|
|
264
|
+
res.status(200).send({ count: result });
|
|
265
|
+
} catch (error) {
|
|
266
|
+
res.status(400).send({ error: error.message });
|
|
267
|
+
}
|
|
268
|
+
};
|