From d369a71eb6afc3ddfeacf2dc2bea3cb2b6f728d7 Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Fri, 22 May 2026 11:17:42 +0800 Subject: [PATCH] feat: add filter and orderBy support on /user monitoring endpoint --- src/app/api/monitoring/[[...slug]]/route.ts | 121 ++++++-------------- 1 file changed, 32 insertions(+), 89 deletions(-) diff --git a/src/app/api/monitoring/[[...slug]]/route.ts b/src/app/api/monitoring/[[...slug]]/route.ts index d606510..b65f1af 100644 --- a/src/app/api/monitoring/[[...slug]]/route.ts +++ b/src/app/api/monitoring/[[...slug]]/route.ts @@ -1186,54 +1186,35 @@ const MonitoringServer = new Elysia({ prefix: "/api/monitoring" }) } ) .get("/user", async ({ query, set }) => { - const { page = 1, search } = query; + const { page = 1, search, isActive, idUserRole, idVillage, orderBy = 'createdAt', orderDir = 'desc' } = query; const pageNum = Number(page) || 1; const take = 15; const skip = (pageNum - 1) * take; + const SORTABLE_FIELDS = ['name', 'email', 'isActive', 'idUserRole', 'createdAt'] as const; + type SortableField = typeof SORTABLE_FIELDS[number]; + const safeOrderBy: SortableField = SORTABLE_FIELDS.includes(orderBy as SortableField) ? (orderBy as SortableField) : 'createdAt'; + const safeOrderDir = orderDir === 'asc' ? 'asc' : 'desc'; + + 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 } } }, + { idUserRole: search }, + ], + }), + }; + try { const data = await prisma.user.findMany({ - where: { - ...(search && { - OR: [ - { - name: { - contains: search, - mode: "insensitive", - }, - }, - { - phone: { - contains: search, - mode: "insensitive", - }, - }, - { - email: { - contains: search, - mode: "insensitive", - }, - }, - { - nik: { - contains: search, - mode: "insensitive", - }, - }, - { - Village: { - name: { - contains: search, - mode: "insensitive", - }, - }, - }, - { - idUserRole: search, - }, - ], - }), - }, + where: whereClause, select: { id: true, name: true, @@ -1270,55 +1251,13 @@ const MonitoringServer = new Elysia({ prefix: "/api/monitoring" }) }, }, orderBy: { - createdAt: "desc", + [safeOrderBy]: safeOrderDir, }, skip, take, }); - const total = await prisma.user.count({ - where: { - ...(search && { - OR: [ - { - name: { - contains: search, - mode: "insensitive", - }, - }, - { - phone: { - contains: search, - mode: "insensitive", - }, - }, - { - email: { - contains: search, - mode: "insensitive", - }, - }, - { - nik: { - contains: search, - mode: "insensitive", - }, - }, - { - Village: { - name: { - contains: search, - mode: "insensitive", - }, - }, - }, - { - idUserRole: search, - }, - ], - }), - }, - }); + const total = await prisma.user.count({ where: whereClause }); const result = data.map((item) => ({ id: item.id, @@ -1363,12 +1302,16 @@ const MonitoringServer = new Elysia({ prefix: "/api/monitoring" }) { query: t.Object({ page: t.Optional(t.String({ description: "Halaman" })), - search: t.Optional(t.String({ description: "Pencarian" })), + search: t.Optional(t.String({ description: "Pencarian nama/NIK/email/telepon" })), + isActive: t.Optional(t.String({ description: "Filter status: 'true' atau 'false'" })), + idUserRole: t.Optional(t.String({ description: "Filter berdasarkan ID role" })), + idVillage: t.Optional(t.String({ description: "Filter berdasarkan ID desa" })), + orderBy: t.Optional(t.String({ description: "Kolom urutan: name | email | isActive | idUserRole | createdAt (default: createdAt)" })), + orderDir: t.Optional(t.String({ description: "Arah urutan: asc | desc (default: desc)" })), }), detail: { summary: "User", - description: - "Mendapatkan data user berdasarkan halaman dan pencarian", + description: "Mendapatkan data user dengan filter status, role, desa, pencarian, dan pengurutan", tags: ["user"], }, }