import { Types } from "mongoose"; import { PrivilegeModel } from "@/models/privilege.model"; import { validateEmptyFields } from "@/utils/validate-empty-fields"; import { convertPrivilegesToMap, validatePrivilege } from "./helpers"; import type { FastifyReply } from "fastify"; import type { GetServicePrivilegesRequest, RegisterPrivilegeRequest, GetPrivilegeRequest, RegisterPrivilegesRequest, RemovePrivilegeRequest, } from "./types"; export const registerPrivileges = async (request: RegisterPrivilegesRequest, reply: FastifyReply) => { const [requestBody, errorEmpty] = validateEmptyFields(request.body ?? {}, ["privileges"]); if (errorEmpty) { void reply.status(400); return errorEmpty; } if (!requestBody.privileges.length) { void reply.status(400); return new Error("empty privilege array"); } for (const rawPrivilege of requestBody.privileges) { const errorInvalid = validatePrivilege(rawPrivilege); if (errorInvalid) { void reply.status(400); return errorInvalid; } } const updatePrivilegeRequests = requestBody.privileges.map(async (privilege) => { await PrivilegeModel.updateOne( { privilegeId: privilege.privilegeId }, { $set: { name: privilege.name, privilegeId: privilege.privilegeId, serviceKey: privilege.serviceKey, description: privilege.description, type: privilege.type, value: privilege.value, price: privilege.price, isDeleted: false, createdAt: new Date(), }, }, { upsert: true } ).lean(); return privilege; }); return Promise.all(updatePrivilegeRequests); }; export const registerPrivilege = async (request: RegisterPrivilegeRequest, reply: FastifyReply) => { const [requestBody, errorEmpty] = validateEmptyFields( request.body ?? {}, ["name", "privilegeId", "serviceKey", "type", "description", "value"], false ); if (errorEmpty) { void reply.status(400); return errorEmpty; } const errorInvalid = validatePrivilege(requestBody); if (errorInvalid) { void reply.status(400); return errorInvalid; } const privilege = await PrivilegeModel.findOne({ privilegeId: requestBody.privilegeId }).lean(); if (privilege) { void reply.status(409); return new Error("privilege already exist"); } const newPrivilege = new PrivilegeModel({ name: requestBody.name, privilegeId: requestBody.privilegeId, serviceKey: requestBody.serviceKey, description: requestBody.description, type: requestBody.type, value: requestBody.value, price: requestBody.price, }); return newPrivilege.save(); }; export const getAllPrivileges = async () => PrivilegeModel.find({ isDeleted: false }).lean(); export const getAllPrivilegesMap = async () => { const privileges = await PrivilegeModel.find({ isDeleted: false }).lean(); if (!privileges.length) { return {}; } return convertPrivilegesToMap(privileges); }; export const getServicePrivileges = async (request: GetServicePrivilegesRequest, reply: FastifyReply) => { const [requestParams, error] = validateEmptyFields(request.params ?? {}, ["serviceKey"]); if (error) { void reply.status(400); return error; } return PrivilegeModel.find({ serviceKey: requestParams.serviceKey, isDeleted: false }).lean(); }; export const getPrivilege = async (request: GetPrivilegeRequest, reply: FastifyReply) => { const [requestParams, error] = validateEmptyFields(request.params ?? {}, ["privilegeId"]); if (error) { void reply.status(400); return error; } if (!Types.ObjectId.isValid(requestParams.privilegeId)) { void reply.status(400); return new Error("invalid id"); } const privilege = await PrivilegeModel.findOne({ privilegeId: requestParams.privilegeId, isDeleted: false }).lean(); if (!privilege) { void reply.status(404); return new Error("privilege not found"); } return privilege; }; export const replacePrivilege = async (request: RegisterPrivilegeRequest, reply: FastifyReply) => { const [requestBody, errorEmpty] = validateEmptyFields( request.body ?? {}, ["name", "privilegeId", "serviceKey", "type", "description", "value"], false ); if (errorEmpty) { void reply.status(400); return errorEmpty; } const errorInvalid = validatePrivilege(requestBody); if (errorInvalid) { void reply.status(400); return errorInvalid; } const privilege = await PrivilegeModel.findOne({ privilegeId: requestBody.privilegeId }); if (!privilege) { void reply.status(404); return new Error("privilege not found"); } await privilege.replaceOne({ name: requestBody.name, privilegeId: requestBody.privilegeId, serviceKey: requestBody.serviceKey, description: requestBody.description, type: requestBody.type, value: requestBody.value, price: requestBody.price, updatedAt: new Date(), }); return privilege; }; export const removePrivilege = async (request: RemovePrivilegeRequest, reply: FastifyReply) => { const [{ privilegeId }, error] = validateEmptyFields(request.body ?? {}, ["privilegeId"]); if (error) { void reply.status(400); return error; } if (!Types.ObjectId.isValid(privilegeId)) { void reply.status(400); return new Error("invalid id"); } const privilege = await PrivilegeModel.findOneAndUpdate( { privilegeId }, { $set: { isDeleted: true, deletedAt: new Date() } } ); if (!privilege) { void reply.status(404); return new Error("privilege not found"); } return privilege; }; export const replacePrivileges = async (request: RegisterPrivilegesRequest, reply: FastifyReply) => { const [requestBody, errorEmpty] = validateEmptyFields(request.body ?? {}, ["privileges"]); if (errorEmpty) { void reply.status(400); return errorEmpty; } if (!requestBody.privileges.length) { void reply.status(400); return new Error("empty privilege array"); } for (const rawPrivilege of requestBody.privileges) { const errorInvalid = validatePrivilege(rawPrivilege); if (errorInvalid) { void reply.status(400); return errorInvalid; } } const replacePrivilegeRequests = requestBody.privileges.map(async (privilege) => { await PrivilegeModel.replaceOne( { privilegeId: privilege.privilegeId }, { name: privilege.name, privilegeId: privilege.privilegeId, serviceKey: privilege.serviceKey, description: privilege.description, type: privilege.type, value: privilege.value, price: privilege.price, updatedAt: new Date(), isDeleted: false, } ).lean(); return privilege; }); return Promise.all(replacePrivilegeRequests); }; export const restorePrivilege = async (request: RemovePrivilegeRequest, reply: FastifyReply) => { const [{ privilegeId }, error] = validateEmptyFields(request.body ?? {}, ["privilegeId"]); if (error) { void reply.status(400); return error; } if (!Types.ObjectId.isValid(privilegeId)) { void reply.status(400); return new Error("invalid id"); } const privilege = await PrivilegeModel.findOneAndUpdate({ privilegeId }, { $set: { isDeleted: false } }); if (!privilege) { void reply.status(404); return new Error("privilege not found"); } return privilege; };