feat: tambah endpoint export-logs dan export-users untuk CSV download
This commit is contained in:
@@ -1736,6 +1736,141 @@ const MonitoringServer = new Elysia({ prefix: "/api/monitoring" })
|
||||
}
|
||||
)
|
||||
|
||||
// ─── CSV EXPORT ──────────────────────────────────────────────────────────
|
||||
|
||||
.get("/export-logs", async ({ query, set }) => {
|
||||
const { search, action, idVillage, dateFrom, dateTo } = query;
|
||||
|
||||
const whereClause = {
|
||||
...(action && { action: action.toUpperCase() }),
|
||||
...(idVillage && { User: { idVillage } }),
|
||||
...((dateFrom || dateTo) && {
|
||||
createdAt: {
|
||||
...(dateFrom && { gte: new Date(dateFrom) }),
|
||||
...(dateTo && { lte: new Date(new Date(dateTo).setHours(23, 59, 59, 999)) }),
|
||||
},
|
||||
}),
|
||||
...(search && {
|
||||
OR: [
|
||||
{ User: { name: { contains: search, mode: "insensitive" as const } } },
|
||||
{ User: { Village: { name: { contains: search, mode: "insensitive" as const } } } },
|
||||
],
|
||||
}),
|
||||
};
|
||||
|
||||
try {
|
||||
const data = await prisma.userLog.findMany({
|
||||
where: whereClause,
|
||||
select: {
|
||||
createdAt: true,
|
||||
action: true,
|
||||
desc: true,
|
||||
User: {
|
||||
select: {
|
||||
name: true,
|
||||
Village: { select: { name: true } },
|
||||
},
|
||||
},
|
||||
},
|
||||
orderBy: { createdAt: "desc" },
|
||||
});
|
||||
|
||||
const result = data.map((item) => ({
|
||||
timestamp: moment(item.createdAt).format('DD MMM YYYY HH:mm'),
|
||||
username: item.User.name,
|
||||
village: item.User.Village.name,
|
||||
action: item.action,
|
||||
desc: item.desc,
|
||||
}));
|
||||
|
||||
return { success: true, data: result };
|
||||
} catch (error) {
|
||||
console.error("[export-logs] error:", error);
|
||||
set.status = 500;
|
||||
return { success: false, message: "Terjadi kesalahan pada server", data: null };
|
||||
}
|
||||
}, {
|
||||
query: t.Object({
|
||||
search: t.Optional(t.String()),
|
||||
action: t.Optional(t.String()),
|
||||
idVillage: t.Optional(t.String()),
|
||||
dateFrom: t.Optional(t.String()),
|
||||
dateTo: t.Optional(t.String()),
|
||||
}),
|
||||
detail: { summary: "Export Logs CSV", tags: ["log-activity"] },
|
||||
})
|
||||
|
||||
.get("/export-users", async ({ query, set }) => {
|
||||
const { search, isActive, idUserRole, idVillage } = query;
|
||||
|
||||
const whereClause = {
|
||||
...(isActive !== undefined && { isActive: isActive === 'true' }),
|
||||
...(idUserRole && { idUserRole }),
|
||||
...(idVillage && { idVillage }),
|
||||
...(search && {
|
||||
OR: [
|
||||
{ name: { contains: search, mode: "insensitive" as const } },
|
||||
{ phone: { contains: search, mode: "insensitive" as const } },
|
||||
{ email: { contains: search, mode: "insensitive" as const } },
|
||||
{ nik: { contains: search, mode: "insensitive" as const } },
|
||||
{ Village: { name: { contains: search, mode: "insensitive" as const } } },
|
||||
],
|
||||
}),
|
||||
};
|
||||
|
||||
try {
|
||||
const data = await prisma.user.findMany({
|
||||
where: whereClause,
|
||||
select: {
|
||||
name: true,
|
||||
nik: true,
|
||||
phone: true,
|
||||
email: true,
|
||||
gender: true,
|
||||
isActive: true,
|
||||
UserRole: { select: { name: true } },
|
||||
Village: { select: { name: true } },
|
||||
Group: { select: { name: true } },
|
||||
Position: { select: { name: true } },
|
||||
UserLog: {
|
||||
orderBy: { createdAt: 'desc' },
|
||||
take: 1,
|
||||
select: { createdAt: true },
|
||||
},
|
||||
},
|
||||
orderBy: { name: 'asc' },
|
||||
});
|
||||
|
||||
const result = data.map((item) => ({
|
||||
name: item.name,
|
||||
nik: item.nik,
|
||||
email: item.email,
|
||||
phone: item.phone,
|
||||
gender: item.gender === 'M' ? 'Male' : item.gender === 'F' ? 'Female' : item.gender,
|
||||
role: item.UserRole?.name ?? '',
|
||||
village: item.Village?.name ?? '',
|
||||
group: item.Group?.name ?? '',
|
||||
position: item.Position?.name ?? '',
|
||||
status: item.isActive ? 'Active' : 'Inactive',
|
||||
lastActivity: item.UserLog[0]?.createdAt ? moment(item.UserLog[0].createdAt).format('DD MMM YYYY HH:mm') : '',
|
||||
}));
|
||||
|
||||
return { success: true, data: result };
|
||||
} catch (error) {
|
||||
console.error("[export-users] error:", error);
|
||||
set.status = 500;
|
||||
return { success: false, message: "Terjadi kesalahan pada server", data: null };
|
||||
}
|
||||
}, {
|
||||
query: t.Object({
|
||||
search: t.Optional(t.String()),
|
||||
isActive: t.Optional(t.String()),
|
||||
idUserRole: t.Optional(t.String()),
|
||||
idVillage: t.Optional(t.String()),
|
||||
}),
|
||||
detail: { summary: "Export Users CSV", tags: ["user"] },
|
||||
})
|
||||
|
||||
// ─── API KEY MANAGEMENT ──────────────────────────────────────────────────
|
||||
|
||||
.get("/api-keys", async ({ set }) => {
|
||||
|
||||
Reference in New Issue
Block a user