update: changes to backend endpoints in orderBy and search query usage

This commit is contained in:
falendikategar 2024-10-09 16:09:36 +07:00
parent 251d74d659
commit dfa3cd9f03

View File

@ -1,173 +1,191 @@
import { and, eq, ilike, or, sql } from "drizzle-orm"; import { and, eq, ilike, or, sql, desc } from "drizzle-orm";
import { Hono } from "hono"; import { Hono } from "hono";
import checkPermission from "../../middlewares/checkPermission"; import checkPermission from "../../middlewares/checkPermission";
import { z } from "zod"; import { z } from "zod";
import { HTTPException } from "hono/http-exception"; import { HTTPException } from "hono/http-exception";
import db from "../../drizzle"; import db from "../../drizzle";
import { assessments } from "../../drizzle/schema/assessments"; import { assessments } from "../../drizzle/schema/assessments";
import { respondents } from "../../drizzle/schema/respondents"; import { respondents } from "../../drizzle/schema/respondents";
import { users } from "../../drizzle/schema/users"; import { users } from "../../drizzle/schema/users";
import HonoEnv from "../../types/HonoEnv"; import HonoEnv from "../../types/HonoEnv";
import requestValidator from "../../utils/requestValidator"; import requestValidator from "../../utils/requestValidator";
import authInfo from "../../middlewares/authInfo"; import authInfo from "../../middlewares/authInfo";
export const assessmentFormSchema = z.object({ export const assessmentFormSchema = z.object({
respondentId: z.string().min(1), respondentId: z.string().min(1),
status: z.enum(["menunggu konfirmasi", "diterima", "ditolak", "selesai"]), status: z.enum(["menunggu konfirmasi", "diterima", "ditolak", "selesai"]),
reviewedBy: z.string().min(1), reviewedBy: z.string().min(1),
validatedBy: z.string().min(1), validatedBy: z.string().min(1),
validatedAt: z.string().optional(), validatedAt: z.string().optional(),
}); });
export const assessmentUpdateSchema = assessmentFormSchema.extend({ export const assessmentUpdateSchema = assessmentFormSchema.extend({
validatedAt: z.string().optional().or(z.literal("")), validatedAt: z.string().optional().or(z.literal("")),
}); });
const assessmentsRequestManagementRoutes = new Hono<HonoEnv>() const assessmentsRequestManagementRoutes = new Hono<HonoEnv>()
.use(authInfo) .use(authInfo)
/** /**
* Get All Assessments (With Metadata) * Get All Assessments (With Metadata)
* *
* Query params: * Query params:
* - withMetadata: boolean * - withMetadata: boolean
*/ */
.get( .get(
"/", "/",
checkPermission("assessmentRequestManagement.readAll"), checkPermission("assessmentRequestManagement.readAll"),
requestValidator( requestValidator(
"query", "query",
z.object({ z.object({
withMetadata: z withMetadata: z
.string() .string()
.optional() .optional()
.transform((v) => v?.toLowerCase() === "true"), .transform((v) => v?.toLowerCase() === "true"),
page: z.coerce.number().int().min(0).default(0), page: z.coerce.number().int().min(0).default(0),
limit: z.coerce.number().int().min(1).max(1000).default(10), limit: z.coerce.number().int().min(1).max(1000).default(10),
q: z.string().default(""), q: z.string().default(""),
})
),
async (c) => {
const { page, limit, q } = c.req.valid("query");
// Query untuk menghitung total jumlah item (totalCountQuery)
const assessmentCountQuery = await db
.select({
count: sql<number>`count(*)`,
}) })
), .from(assessments)
async (c) => { .leftJoin(respondents, eq(assessments.respondentId, respondents.id))
const { page, limit, q } = c.req.valid("query"); .leftJoin(users, eq(respondents.userId, users.id))
.where(
const totalCountQuery = sql<number>`(SELECT count(*) FROM ${assessments})`; q
? or(
const result = await db ilike(users.name, `%${q}%`),
.select({ ilike(respondents.companyName, `%${q}%`),
idPermohonan: assessments.id, sql`CAST(${assessments.status} AS TEXT) ILIKE ${'%' + q + '%'}`,
namaResponden: users.name, eq(assessments.id, q)
namaPerusahaan: respondents.companyName,
status: assessments.status,
tanggal: assessments.createdAt,
fullCount: totalCountQuery,
})
.from(assessments)
.leftJoin(respondents, eq(assessments.respondentId, respondents.id))
.leftJoin(users, eq(respondents.userId, users.id))
.where(
q
? or(
ilike(users.name, `%${q}%`),
ilike(respondents.companyName, `%${q}%`),
eq(assessments.id, q)
)
: undefined
) )
.offset(page * limit) : undefined
.limit(limit); );
return c.json({ const totalItems = Number(assessmentCountQuery[0]?.count) || 0;
data: result.map((d) => ({
idPermohonan: d.idPermohonan,
namaResponden: d.namaResponden,
namaPerusahaan: d.namaPerusahaan,
status: d.status,
tanggal: d.tanggal,
})),
_metadata: {
currentPage: page,
totalPages: Math.ceil(
(Number(result[0]?.fullCount) ?? 0) / limit
),
totalItems: Number(result[0]?.fullCount) ?? 0,
perPage: limit,
},
});
}
)
// Get assessment by id // Query utama untuk mendapatkan data permohonan assessment
.get( const result = await db
"/:id", .select({
checkPermission("assessmentRequestManagement.read"), idPermohonan: assessments.id,
async (c) => { namaResponden: users.name,
const assessmentId = c.req.param("id"); namaPerusahaan: respondents.companyName,
status: assessments.status,
const queryResult = await db tanggal: assessments.createdAt,
.select({
// id: assessments.id,
tanggal: assessments.createdAt,
nama: users.name,
posisi: respondents.position,
pengalamanKerja: respondents.workExperience,
email: users.email,
namaPerusahaan: respondents.companyName,
alamat: respondents.address,
nomorTelepon: respondents.phoneNumber,
username: users.username,
status: assessments.status,
})
.from(assessments)
.leftJoin(respondents, eq(assessments.respondentId, respondents.id))
.leftJoin(users, eq(respondents.userId, users.id))
.where(eq(assessments.id, assessmentId));
if (!queryResult.length)
throw new HTTPException(404, {
message: "The assessment does not exist",
});
const assessmentData = queryResult[0];
return c.json(assessmentData);
}
)
.patch(
"/:id",
checkPermission("assessmentRequestManagement.update"),
requestValidator(
"json",
z.object({
status: z.enum(["menunggu konfirmasi", "diterima", "ditolak", "selesai"]),
}) })
), .from(assessments)
async (c) => { .leftJoin(respondents, eq(assessments.respondentId, respondents.id))
const assessmentId = c.req.param("id"); .leftJoin(users, eq(respondents.userId, users.id))
const { status } = c.req.valid("json"); .where(
q
const assessment = await db ? or(
.select() ilike(users.name, `%${q}%`),
.from(assessments) ilike(respondents.companyName, `%${q}%`),
.where(and(eq(assessments.id, assessmentId),)); sql`CAST(${assessments.status} AS TEXT) ILIKE ${'%' + q + '%'}`,
eq(assessments.id, q)
if (!assessment[0]) throw new HTTPException(404, { )
message: "Assessment tidak ditemukan.", : undefined
}); )
.orderBy(desc(assessments.createdAt))
await db .offset(page * limit)
.update(assessments) .limit(limit);
.set({
status,
})
.where(eq(assessments.id, assessmentId));
return c.json({
message: "Status assessment berhasil diperbarui.",
});
}
)
return c.json({
data: result.map((d) => ({
idPermohonan: d.idPermohonan,
namaResponden: d.namaResponden,
namaPerusahaan: d.namaPerusahaan,
status: d.status,
tanggal: d.tanggal,
})),
_metadata: {
currentPage: page,
totalPages: Math.ceil(totalItems / limit),
totalItems,
perPage: limit,
},
});
}
)
// Get assessment by id
.get(
"/:id",
checkPermission("assessmentRequestManagement.read"),
async (c) => {
const assessmentId = c.req.param("id");
const queryResult = await db
.select({
tanggal: assessments.createdAt,
nama: users.name,
posisi: respondents.position,
pengalamanKerja: respondents.workExperience,
email: users.email,
namaPerusahaan: respondents.companyName,
alamat: respondents.address,
nomorTelepon: respondents.phoneNumber,
username: users.username,
status: assessments.status,
})
.from(assessments)
.leftJoin(respondents, eq(assessments.respondentId, respondents.id))
.leftJoin(users, eq(respondents.userId, users.id))
.where(eq(assessments.id, assessmentId));
if (!queryResult.length)
throw new HTTPException(404, {
message: "The assessment does not exist",
});
const assessmentData = queryResult[0];
return c.json(assessmentData);
}
)
.patch(
"/:id",
checkPermission("assessmentRequestManagement.update"),
requestValidator(
"json",
z.object({
status: z.enum(["menunggu konfirmasi", "diterima", "ditolak", "selesai"]),
})
),
async (c) => {
const assessmentId = c.req.param("id");
const { status } = c.req.valid("json");
const assessment = await db
.select()
.from(assessments)
.where(and(eq(assessments.id, assessmentId),));
if (!assessment[0]) throw new HTTPException(404, {
message: "Assessment tidak ditemukan.",
});
await db
.update(assessments)
.set({
status,
})
.where(eq(assessments.id, assessmentId));
return c.json({
message: "Status assessment berhasil diperbarui.",
});
}
)
export default assessmentsRequestManagementRoutes;
export default assessmentsRequestManagementRoutes;