Pull Request branch dev-clone to main #1

Merged
gitea merged 429 commits from dev-clone into main 2024-12-23 09:31:34 +00:00
4 changed files with 190 additions and 3 deletions
Showing only changes of commit e7a425aa0b - Show all commits

View File

@ -47,6 +47,15 @@ const permissionsData = [
{ {
code: "questions.restore", code: "questions.restore",
}, },
{
code :"assessmentRequestManagement.readAll",
},
{
code: "assessmentRequestManagement.update",
},
{
code :"assessmentRequestManagement.read",
},
{ {
code: "managementAspect.readAll", code: "managementAspect.readAll",
}, },

View File

@ -4,7 +4,7 @@ import { relations } from "drizzle-orm";
import { respondents } from "./respondents"; import { respondents } from "./respondents";
import { users } from "./users"; import { users } from "./users";
const statusEnum = pgEnum("status", ["menunggu konfirmasi", "disetujui", "ditolak", "selesai"]); const statusEnum = pgEnum("status", ["menunggu konfirmasi", "diterima", "ditolak", "selesai"]);
export const assessments = pgTable("assessments", { export const assessments = pgTable("assessments", {
id: varchar("id", { length: 50 }) id: varchar("id", { length: 50 })
@ -17,6 +17,8 @@ export const assessments = pgTable("assessments", {
validatedBy: varchar("validatedBy"), validatedBy: varchar("validatedBy"),
validatedAt: timestamp("validatedAt", { mode: "date" }), validatedAt: timestamp("validatedAt", { mode: "date" }),
createdAt: timestamp("createdAt", { mode: "date" }).defaultNow(), createdAt: timestamp("createdAt", { mode: "date" }).defaultNow(),
}); });
// Query Tools in PosgreSQL // Query Tools in PosgreSQL
// CREATE TYPE status AS ENUM ('menunggu konfirmasi', 'disetujui', 'ditolak', 'selesai'); // CREATE TYPE status AS ENUM ('menunggu konfirmasi', 'diterima', 'ditolak', 'selesai');

View File

@ -22,6 +22,7 @@ import assessmentResultRoute from "./routes/assessmentResult/route";
import assessmentRequestRoute from "./routes/assessmentRequest/route"; import assessmentRequestRoute from "./routes/assessmentRequest/route";
import forgotPasswordRoutes from "./routes/forgotPassword/route"; import forgotPasswordRoutes from "./routes/forgotPassword/route";
import assessmentsRoute from "./routes/assessments/route"; import assessmentsRoute from "./routes/assessments/route";
import assessmentsRequestManagementRoutes from "./routes/assessmentRequestManagement/route";
configDotenv(); configDotenv();
@ -92,11 +93,13 @@ const routes = app
.route("/assessmentRequest", assessmentRequestRoute) .route("/assessmentRequest", assessmentRequestRoute)
.route("/forgot-password", forgotPasswordRoutes) .route("/forgot-password", forgotPasswordRoutes)
.route("/assessments", assessmentsRoute) .route("/assessments", assessmentsRoute)
.route("/assessmentRequestManagement",assessmentsRequestManagementRoutes)
.onError((err, c) => { .onError((err, c) => {
if (err instanceof DashboardError) { if (err instanceof DashboardError) {
return c.json( return c.json(
{ {
message: err.message, message: err.message,
errorCode: err.errorCode, errorCode: err.errorCode,
formErrors: err.formErrors, formErrors: err.formErrors,
}, },

View File

@ -0,0 +1,173 @@
import { and, eq, ilike, or, sql } from "drizzle-orm";
import { Hono } from "hono";
import checkPermission from "../../middlewares/checkPermission";
import { z } from "zod";
import { HTTPException } from "hono/http-exception";
import db from "../../drizzle";
import { assessments } from "../../drizzle/schema/assessments";
import { respondents } from "../../drizzle/schema/respondents";
import { users } from "../../drizzle/schema/users";
import HonoEnv from "../../types/HonoEnv";
import requestValidator from "../../utils/requestValidator";
import authInfo from "../../middlewares/authInfo";
export const assessmentFormSchema = z.object({
respondentId: z.string().min(1),
status: z.enum(["menunggu konfirmasi", "diterima", "ditolak", "selesai"]),
reviewedBy: z.string().min(1),
validatedBy: z.string().min(1),
validatedAt: z.string().optional(),
});
export const assessmentUpdateSchema = assessmentFormSchema.extend({
validatedAt: z.string().optional().or(z.literal("")),
});
const assessmentsRequestManagementRoutes = new Hono<HonoEnv>()
.use(authInfo)
/**
* Get All Assessments (With Metadata)
*
* Query params:
* - withMetadata: boolean
*/
.get(
"/",
checkPermission("assessmentRequestManagement.readAll"),
requestValidator(
"query",
z.object({
withMetadata: z
.string()
.optional()
.transform((v) => v?.toLowerCase() === "true"),
page: z.coerce.number().int().min(0).default(0),
limit: z.coerce.number().int().min(1).max(1000).default(10),
q: z.string().default(""),
})
),
async (c) => {
const { page, limit, q } = c.req.valid("query");
const totalCountQuery = sql<number>`(SELECT count(*) FROM ${assessments})`;
const result = await db
.select({
idPermohonan: assessments.id,
namaResponden: users.name,
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)
.limit(limit);
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(
(Number(result[0]?.fullCount) ?? 0) / limit
),
totalItems: Number(result[0]?.fullCount) ?? 0,
perPage: limit,
},
});
}
)
// Get assessment by id
.get(
"/:id",
checkPermission("assessmentRequestManagement.read"),
async (c) => {
const assessmentId = c.req.param("id");
const queryResult = await db
.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"]),
})
),
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;