feat: add range param to daily-activity and comparison-activity endpoints
Both endpoints now accept ?range=7|30|90 (default 7). comparison-activity result now follows SQL ORDER BY instead of being remapped through villages array.
This commit is contained in:
@@ -117,50 +117,32 @@ const MonitoringServer = new Elysia({ prefix: "/api/monitoring" })
|
|||||||
)
|
)
|
||||||
.get("/daily-activity", async ({ query, set }) => {
|
.get("/daily-activity", async ({ query, set }) => {
|
||||||
try {
|
try {
|
||||||
// const data = await prisma.userLog.findMany({
|
const VALID_RANGES = [7, 30, 90];
|
||||||
// where: {
|
const range = VALID_RANGES.includes(Number(query.range)) ? Number(query.range) : 7;
|
||||||
// User: {
|
|
||||||
// Village: {
|
|
||||||
// isDummy: false
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// createdAt: {
|
|
||||||
// gte: moment().subtract(7, 'days').toDate(),
|
|
||||||
// lte: moment().toDate(),
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// select: {
|
|
||||||
// createdAt: true,
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
|
|
||||||
const data = await prisma.$queryRaw`
|
const data = await prisma.$queryRaw`
|
||||||
SELECT
|
SELECT
|
||||||
DATE(ul."createdAt") AS tanggal,
|
DATE(ul."createdAt") AS tanggal,
|
||||||
COUNT(*) AS total
|
COUNT(*) AS total
|
||||||
FROM "UserLog" ul
|
FROM "UserLog" ul
|
||||||
JOIN "User" u ON ul."idUser" = u."id"
|
JOIN "User" u ON ul."idUser" = u."id"
|
||||||
JOIN "Village" v ON u."idVillage" = v."id"
|
JOIN "Village" v ON u."idVillage" = v."id"
|
||||||
WHERE v."isDummy" = false
|
WHERE v."isDummy" = false
|
||||||
AND ul."createdAt" >= NOW() - INTERVAL '7 days'
|
AND ul."createdAt" >= NOW() - (${range} * INTERVAL '1 day')
|
||||||
GROUP BY tanggal
|
GROUP BY tanggal
|
||||||
ORDER BY tanggal;` as any[];
|
ORDER BY tanggal;` as any[];
|
||||||
|
|
||||||
const result = [];
|
const result = [];
|
||||||
|
|
||||||
// ubah data ke map biar gampang lookup
|
|
||||||
const map = data.reduce((acc: any, item: any) => {
|
const map = data.reduce((acc: any, item: any) => {
|
||||||
const key = moment(item.tanggal).format('YYYY-MM-DD');
|
const key = moment(item.tanggal).format('YYYY-MM-DD');
|
||||||
acc[key] = Number(item.total);
|
acc[key] = Number(item.total);
|
||||||
return acc;
|
return acc;
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
// generate 7 hari terakhir
|
for (let i = range - 1; i >= 0; i--) {
|
||||||
for (let i = 6; i >= 0; i--) {
|
|
||||||
const date = moment().subtract(i, 'days');
|
const date = moment().subtract(i, 'days');
|
||||||
|
|
||||||
const key = date.format('YYYY-MM-DD');
|
const key = date.format('YYYY-MM-DD');
|
||||||
|
|
||||||
result.push({
|
result.push({
|
||||||
date: date.format('DD MMM'),
|
date: date.format('DD MMM'),
|
||||||
logs: map[key] || 0
|
logs: map[key] || 0
|
||||||
@@ -183,45 +165,39 @@ const MonitoringServer = new Elysia({ prefix: "/api/monitoring" })
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
query: t.Object({
|
||||||
|
range: t.Optional(t.String({ description: "Rentang hari: 7, 30, atau 90 (default: 7)" })),
|
||||||
|
}),
|
||||||
detail: {
|
detail: {
|
||||||
summary: "Daily Activity",
|
summary: "Daily Activity",
|
||||||
description: "Menu Overview - Mendapatkan data grafik aktivitas harian semua desa.",
|
description: "Menu Overview - Mendapatkan data grafik aktivitas harian semua desa. Gunakan ?range=30 atau ?range=90 untuk rentang lebih panjang.",
|
||||||
tags: ["overview"],
|
tags: ["overview"],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.get("/comparison-activity", async ({ query, set }) => {
|
.get("/comparison-activity", async ({ query, set }) => {
|
||||||
try {
|
try {
|
||||||
const villages = await prisma.village.findMany({
|
const VALID_RANGES = [7, 30, 90];
|
||||||
where: { isDummy: false },
|
const range = VALID_RANGES.includes(Number(query.range)) ? Number(query.range) : 7;
|
||||||
select: { name: true },
|
|
||||||
});
|
|
||||||
|
|
||||||
const data = await prisma.$queryRaw`
|
const data = await prisma.$queryRaw`
|
||||||
SELECT
|
SELECT
|
||||||
v."name",
|
v."name",
|
||||||
COUNT(ul."id") AS total_logs
|
COUNT(ul."id") AS total_logs
|
||||||
FROM "UserLog" ul
|
FROM "UserLog" ul
|
||||||
JOIN "User" u ON ul."idUser" = u."id"
|
JOIN "User" u ON ul."idUser" = u."id"
|
||||||
JOIN "Village" v ON u."idVillage" = v."id"
|
JOIN "Village" v ON u."idVillage" = v."id"
|
||||||
WHERE v."isDummy" = false
|
WHERE v."isDummy" = false
|
||||||
AND ul."createdAt" >= NOW() - INTERVAL '7 days'
|
AND ul."createdAt" >= NOW() - (${range} * INTERVAL '1 day')
|
||||||
GROUP BY v."id", v."name"
|
GROUP BY v."id", v."name"
|
||||||
ORDER BY total_logs DESC;
|
ORDER BY total_logs DESC;
|
||||||
` as any[];
|
` as any[];
|
||||||
|
|
||||||
const logMap: Record<string, number> = {};
|
const result = data.map((item: any) => ({
|
||||||
|
village: item.name,
|
||||||
data.forEach((item) => {
|
activity: Number(item.total_logs),
|
||||||
logMap[item.name] = Number(item.total_logs);
|
|
||||||
});
|
|
||||||
|
|
||||||
const result = villages.map((v) => ({
|
|
||||||
village: v.name,
|
|
||||||
activity: logMap[v.name] || 0,
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
message: "Berhasil mendapatkan data",
|
message: "Berhasil mendapatkan data",
|
||||||
@@ -238,9 +214,12 @@ const MonitoringServer = new Elysia({ prefix: "/api/monitoring" })
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
query: t.Object({
|
||||||
|
range: t.Optional(t.String({ description: "Rentang hari: 7, 30, atau 90 (default: 7)" })),
|
||||||
|
}),
|
||||||
detail: {
|
detail: {
|
||||||
summary: "Comparison Activity",
|
summary: "Comparison Activity",
|
||||||
description: "Menu Overview - Mendapatkan data grafik perbandingan aktivitas desa selama 7 hari terakhir.",
|
description: "Menu Overview - Mendapatkan data grafik perbandingan aktivitas desa. Gunakan ?range=30 atau ?range=90 untuk rentang lebih panjang.",
|
||||||
tags: ["overview"],
|
tags: ["overview"],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user