diff --git a/src/handlers/privilege/helpers.ts b/src/handlers/privilege/helpers.ts index b5d95d3..2a8fa1f 100644 --- a/src/handlers/privilege/helpers.ts +++ b/src/handlers/privilege/helpers.ts @@ -5,7 +5,7 @@ export const validatePrivilege = (privilege: RawPrivilege): Error | null => { const typeValues: typeof privilege.type[] = ["count", "day", "full"]; if (!typeValues.includes(privilege.type)) { - return new Error("invalid 'type' value"); + return new Error("invalid value"); } if (isNaN(Number(privilege.price))) { diff --git a/src/handlers/privilege/index.ts b/src/handlers/privilege/index.ts index 2193a59..b9e816b 100644 --- a/src/handlers/privilege/index.ts +++ b/src/handlers/privilege/index.ts @@ -11,8 +11,56 @@ import type { GetServicePrivilegiesRequest, RegisterPrivilegeRequest, GetPrivilegeRequest, + RegisterPrivilegiesRequest, } from "./types"; +export const registerPrivilegies = async (request: RegisterPrivilegiesRequest, reply: FastifyReply) => { + const [requestBody, errorEmpty] = validateEmptyFields(request.body || {}, ["privilegies"]); + + if (errorEmpty) { + reply.status(400); + return errorEmpty; + } + + if (!requestBody.privilegies.length) { + reply.status(400); + return new Error("empty privilege array"); + } + + for (const rawPrivilege of requestBody.privilegies) { + const errorInvalid = validatePrivilege(rawPrivilege); + + if (errorInvalid) { + reply.status(400); + return errorInvalid; + } + } + + const updatePrivilegeRequests = requestBody.privilegies.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 || {}, @@ -141,7 +189,80 @@ export const replacePrivilege = async (request: RegisterPrivilegeRequest, reply: type: requestBody.type, value: requestBody.value, price: requestBody.price, + updatedAt: new Date(), }); return privilege; }; + +export const replacePrivilegies = async (request: RegisterPrivilegiesRequest, reply: FastifyReply) => { + const [requestBody, errorEmpty] = validateEmptyFields(request.body || {}, ["privilegies"]); + + if (errorEmpty) { + reply.status(400); + return errorEmpty; + } + + if (!requestBody.privilegies.length) { + reply.status(400); + return new Error("empty privilege array"); + } + + for (const rawPrivilege of requestBody.privilegies) { + const errorInvalid = validatePrivilege(rawPrivilege); + + if (errorInvalid) { + reply.status(400); + return errorInvalid; + } + } + + const replacePrivilegeRequests = requestBody.privilegies.map(async (privilege) => { + await PrivilegeModel.replaceOne( + { 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, + updatedAt: new Date(), + isDeleted: false, + }, + } + ).lean(); + + return privilege; + }); + + return Promise.all(replacePrivilegeRequests); +}; + +export const removePrivilege = async (request: GetPrivilegeRequest, reply: FastifyReply) => { + const [requestParams, error] = validateEmptyFields(request.params || {}, ["id"]); + + if (error) { + reply.status(400); + return error; + } + + if (!Types.ObjectId.isValid(requestParams.id)) { + reply.status(400); + return new Error("invalid id"); + } + + const privilege = await PrivilegeModel.findOneAndUpdate( + { privilegeId: requestParams.id }, + { $set: { isDeleted: true, deletedAt: new Date() } } + ); + + if (!privilege) { + reply.status(404); + return new Error("privilege not found"); + } + + return privilege; +}; diff --git a/src/handlers/privilege/types.ts b/src/handlers/privilege/types.ts index 76e78c2..97edaf0 100644 --- a/src/handlers/privilege/types.ts +++ b/src/handlers/privilege/types.ts @@ -22,6 +22,12 @@ export type RegisterPrivilegeRequest = FastifyRequest<{ Body?: RawPrivilege; }>; +export type RegisterPrivilegiesRequest = FastifyRequest<{ + Body?: { + privilegies?: RawPrivilege[]; + }; +}>; + export type GetServicePrivilegiesRequest = FastifyRequest<{ Params?: { serviceKey?: string; diff --git a/src/routes/privilege.routes.ts b/src/routes/privilege.routes.ts index 2726088..e9fb140 100644 --- a/src/routes/privilege.routes.ts +++ b/src/routes/privilege.routes.ts @@ -6,6 +6,9 @@ import { getPrivilege, getServicePrivilegies, replacePrivilege, + registerPrivilegies, + removePrivilege, + replacePrivilegies, } from "@/handlers/privilege"; import { @@ -13,7 +16,10 @@ import { getPrivilegeSchema, getServicePrivilegiesSchema, registerPrivilegeSchema, + registerPrivilegiesSchema, replacePrivilegeSchema, + replacePrivilegiesSchema, + removePrivilegeSchema, } from "@/swagger/privilege"; export const setPrivilegeRoutes = (router: Router): void => { @@ -21,5 +27,8 @@ export const setPrivilegeRoutes = (router: Router): void => { router.get("/:id", getPrivilege, { schema: getPrivilegeSchema }); router.get("/service/:serviceKey", getServicePrivilegies, { schema: getServicePrivilegiesSchema }); router.post("/", registerPrivilege, { schema: registerPrivilegeSchema }); + router.post("/many", registerPrivilegies, { schema: registerPrivilegiesSchema }); router.put("/", replacePrivilege, { schema: replacePrivilegeSchema }); + router.put("/many", replacePrivilegies, { schema: replacePrivilegiesSchema }); + router.delete("/", removePrivilege, { schema: removePrivilegeSchema }); }; diff --git a/src/server/router.ts b/src/server/router.ts index fdb238b..6ddb5a0 100644 --- a/src/server/router.ts +++ b/src/server/router.ts @@ -46,7 +46,7 @@ export class Router { public post = ( path: string, handler: HandlerMethod, - options: RouteShorthandOptions + options: RouteShorthandOptions = {} ) => { this.fastifyInstance.post(path, options, handler); }; @@ -54,7 +54,7 @@ export class Router { public put = ( path: string, handler: HandlerMethod, - options: RouteShorthandOptions + options: RouteShorthandOptions = {} ) => { this.fastifyInstance.put(path, options, handler); }; @@ -62,7 +62,7 @@ export class Router { public patch = ( path: string, handler: HandlerMethod, - options: RouteShorthandOptions + options: RouteShorthandOptions = {} ) => { this.fastifyInstance.patch(path, options, handler); }; @@ -70,7 +70,7 @@ export class Router { public delete = ( path: string, handler: HandlerMethod, - options: RouteShorthandOptions + options: RouteShorthandOptions = {} ) => { this.fastifyInstance.delete(path, options, handler); }; diff --git a/src/swagger/privilege/index.ts b/src/swagger/privilege/index.ts index 77cdc3e..bc84698 100644 --- a/src/swagger/privilege/index.ts +++ b/src/swagger/privilege/index.ts @@ -1,10 +1,19 @@ -import { privilegeBody, getPrivilegeParams, getServicePrivilegiesParams, getPrivilegiesQuery } from "./inputs"; +import { + privilegeBody, + privilegiesBody, + getPrivilegeParams, + getServicePrivilegiesParams, + getPrivilegiesQuery, +} from "./inputs"; import { getPrivilegeReponse, getPrivilegiesReponse, getAllPrivilegiesReponse, registerPrivilegeResponse, replacePrivilegeResponse, + registerPrivilegiesResponse, + replacePrivilegiesResponse, + removePrivilegeResponse, } from "./responses"; import type { SwaggerSchema } from "@/types/swagger.type"; @@ -38,9 +47,30 @@ export const registerPrivilegeSchema: SwaggerSchema = { response: registerPrivilegeResponse, }; +export const registerPrivilegiesSchema: SwaggerSchema = { + summary: "Регистрация привелегий сервиса", + tags: ["privilege"], + body: privilegiesBody, + response: registerPrivilegiesResponse, +}; + export const replacePrivilegeSchema: SwaggerSchema = { summary: "Замена привилегии сервиса", tags: ["privilege"], body: privilegeBody, response: replacePrivilegeResponse, }; + +export const replacePrivilegiesSchema: SwaggerSchema = { + summary: "Замена привилегий сервиса", + tags: ["privilege"], + body: privilegiesBody, + response: replacePrivilegiesResponse, +}; + +export const removePrivilegeSchema: SwaggerSchema = { + summary: "Удаление привелегии", + tags: ["privilege"], + body: getPrivilegeParams, + response: removePrivilegeResponse, +}; diff --git a/src/swagger/privilege/inputs.ts b/src/swagger/privilege/inputs.ts index 3212f0e..7268306 100644 --- a/src/swagger/privilege/inputs.ts +++ b/src/swagger/privilege/inputs.ts @@ -25,6 +25,11 @@ export const privilegeBody: SwaggerMessage = { ], }; +export const privilegiesBody: SwaggerMessage = { + type: "array", + items: privilegeBody, +}; + export const getPrivilegeParams: SwaggerMessage = { type: "object", required: ["id"], diff --git a/src/swagger/privilege/responses.ts b/src/swagger/privilege/responses.ts index 2e9195d..880baa3 100644 --- a/src/swagger/privilege/responses.ts +++ b/src/swagger/privilege/responses.ts @@ -28,8 +28,30 @@ export const registerPrivilegeResponse: Record = { 409: swaggerError(409, "privilege already exist"), }; +export const registerPrivilegiesResponse: Record = { + 200: { + type: "array", + items: privilege, + }, + 400: swaggerError(400, "price must be a number"), +}; + export const replacePrivilegeResponse: Record = { 200: privilege, 400: swaggerError(400, "invalid 'type' value"), 404: swaggerError(404, "privilege not found"), }; + +export const replacePrivilegiesResponse: Record = { + 200: { + type: "array", + items: privilege, + }, + 400: swaggerError(400, "invalid 'type' value"), +}; + +export const removePrivilegeResponse: Record = { + 200: privilege, + 400: swaggerError(400, "invalid id"), + 404: swaggerError(404, "privilege not found"), +};