From 8e0de97b78c93e86439285ec12d6967899297e21 Mon Sep 17 00:00:00 2001 From: "DESKTOP-1R2VSQH\\Lenovo ThinkPad E490" Date: Thu, 22 Aug 2024 14:23:50 +0700 Subject: [PATCH] log --- src/controllers/KpiCapacityController.ts | 31 ++-- src/controllers/KpiEvaluationController.ts | 8 +- src/controllers/KpiGroupController.ts | 29 ++-- src/controllers/KpiLinkController.ts | 24 ++- src/controllers/KpiPeriodController.ts | 54 +++--- src/controllers/KpiPlanController.ts | 35 ++-- src/controllers/KpiReasonController.ts | 108 +++++++++--- src/controllers/KpiRoleController.ts | 39 +++-- src/controllers/KpiSpecialController.ts | 24 ++- src/controllers/KpiUserCapacityController.ts | 17 +- .../KpiUserDevelopmentController.ts | 31 +++- .../KpiUserEvaluationController.ts | 158 +++++++++++------- src/controllers/KpiUserPlannedController.ts | 16 +- src/controllers/KpiUserRoleController.ts | 18 +- src/controllers/KpiUserSpecialController.ts | 25 ++- src/database/data-source.ts | 48 +++++- src/interfaces/call-api.ts | 43 +++++ src/interfaces/utils.ts | 37 ++++ src/middlewares/auth.ts | 22 ++- src/middlewares/error.ts | 6 + src/middlewares/logs.ts | 74 ++++++++ 21 files changed, 637 insertions(+), 210 deletions(-) create mode 100644 src/interfaces/utils.ts create mode 100644 src/middlewares/logs.ts diff --git a/src/controllers/KpiCapacityController.ts b/src/controllers/KpiCapacityController.ts index dc4bbbc..26fc623 100644 --- a/src/controllers/KpiCapacityController.ts +++ b/src/controllers/KpiCapacityController.ts @@ -25,6 +25,8 @@ import { KpiCapacityDetail } from "../entities/kpiCapacityDetail"; import { Like, In } from "typeorm"; import permission from "../interfaces/permission"; import { RequestWithUser } from "../middlewares/user"; +import { addLogSequence, setLogDataDiff } from "../interfaces/utils"; + @Route("api/v1/kpi/capacity") @Tags("kpiCapacity") @Security("bearerAuth") @@ -69,17 +71,20 @@ export class kpiCapacityController extends Controller { }, @Request() request: RequestWithUser, ) { - await new permission().PermissionCreate(request,"SYS_EVA_COMPETENCY"); + await new permission().PermissionCreate(request, "SYS_EVA_COMPETENCY"); const kpiCapacity = Object.assign(new KpiCapacity(), { type: requestBody.type, name: requestBody.name, description: requestBody.description, }); + const before = null; + kpiCapacity.createdUserId = request.user.sub; kpiCapacity.createdFullName = request.user.name; kpiCapacity.lastUpdateUserId = request.user.sub; kpiCapacity.lastUpdateFullName = request.user.name; - await this.kpiCapacityRepository.save(kpiCapacity); + await this.kpiCapacityRepository.save(kpiCapacity, { data: request }); + setLogDataDiff(request, { before, after: kpiCapacity }); let idx: number = 0; for (const data of requestBody.capacityDetails) { @@ -95,7 +100,8 @@ export class kpiCapacityController extends Controller { kpiCapacityDetail.createdFullName = request.user.name; kpiCapacityDetail.lastUpdateUserId = request.user.sub; kpiCapacityDetail.lastUpdateFullName = request.user.name; - await this.kpiCapacityDetailRepository.save(kpiCapacityDetail); + await this.kpiCapacityDetailRepository.save(kpiCapacityDetail, { data: request }); + setLogDataDiff(request, { before, after: kpiCapacityDetail }); } return new HttpSuccess(kpiCapacity.id); @@ -134,7 +140,7 @@ export class kpiCapacityController extends Controller { }, @Request() request: RequestWithUser, ) { - await new permission().PermissionUpdate(request,"SYS_EVA_COMPETENCY"); + await new permission().PermissionUpdate(request, "SYS_EVA_COMPETENCY"); const kpiCapacity = await this.kpiCapacityRepository.findOne({ where: { id: id }, }); @@ -146,15 +152,17 @@ export class kpiCapacityController extends Controller { name: requestBody.name, description: requestBody.description, }); + const before = structuredClone(kpiCapacity); kpiCapacity.lastUpdateUserId = request.user.sub; kpiCapacity.lastUpdateFullName = request.user.name; this.kpiCapacityRepository.merge(kpiCapacity, _kpiCapacity); - await this.kpiCapacityRepository.save(kpiCapacity); + await this.kpiCapacityRepository.save(kpiCapacity, { data: request }); + setLogDataDiff(request, { before, after: kpiCapacity }); const _kpiCapacityDetailsOld = await this.kpiCapacityDetailRepository.find({ where: { kpiCapacityId: kpiCapacity.id }, }); - await this.kpiCapacityDetailRepository.remove(_kpiCapacityDetailsOld); + await this.kpiCapacityDetailRepository.remove(_kpiCapacityDetailsOld, { data: request }); let idx: number = 0; for (const data of requestBody.capacityDetails) { @@ -166,11 +174,14 @@ export class kpiCapacityController extends Controller { description: data.description, kpiCapacityId: kpiCapacity.id, }); + const beforeDetail = structuredClone(kpiCapacityDetail); + kpiCapacityDetail.createdUserId = request.user.sub; kpiCapacityDetail.createdFullName = request.user.name; kpiCapacityDetail.lastUpdateUserId = request.user.sub; kpiCapacityDetail.lastUpdateFullName = request.user.name; - await this.kpiCapacityDetailRepository.save(kpiCapacityDetail); + await this.kpiCapacityDetailRepository.save(kpiCapacityDetail, { data: request }); + setLogDataDiff(request, { before: beforeDetail, after: kpiCapacityDetail }); } return new HttpSuccess(kpiCapacity.id); @@ -360,7 +371,7 @@ export class kpiCapacityController extends Controller { */ @Delete("{id}") async deleteKpiCapacity(@Path() id: string, @Request() request: RequestWithUser) { - await new permission().PermissionDelete(request,"SYS_EVA_COMPETENCY"); + await new permission().PermissionDelete(request, "SYS_EVA_COMPETENCY"); const kpiCapacity = await this.kpiCapacityRepository.findOne({ where: { id: id }, }); @@ -371,9 +382,9 @@ export class kpiCapacityController extends Controller { where: { kpiCapacityId: id }, }); if (kpiCapacityDetails.length > 0) { - await this.kpiCapacityDetailRepository.remove(kpiCapacityDetails); + await this.kpiCapacityDetailRepository.remove(kpiCapacityDetails, { data: request }); } - await this.kpiCapacityRepository.remove(kpiCapacity); + await this.kpiCapacityRepository.remove(kpiCapacity, { data: request }); return new HttpSuccess(); } } diff --git a/src/controllers/KpiEvaluationController.ts b/src/controllers/KpiEvaluationController.ts index e2ad304..d259858 100644 --- a/src/controllers/KpiEvaluationController.ts +++ b/src/controllers/KpiEvaluationController.ts @@ -23,6 +23,8 @@ import HttpStatusCode from "../interfaces/http-status"; import { KpiEvaluation, updateKpiEvaluation } from "../entities/kpiEvaluation"; import permission from "../interfaces/permission"; import { RequestWithUser } from "../middlewares/user"; +import { addLogSequence, setLogDataDiff } from "../interfaces/utils"; + @Route("api/v1/kpi/evaluation") @Tags("kpiEvaluation") @Security("bearerAuth") @@ -43,7 +45,7 @@ export class kpiEvaluationController extends Controller { @Body() requestBody: updateKpiEvaluation[], @Request() request: RequestWithUser, ) { - await new permission().PermissionUpdate(request,"SYS_EVA_COMPETENCY"); + await new permission().PermissionUpdate(request, "SYS_EVA_COMPETENCY"); const updatedIds: string[] = []; for (const item of requestBody) { @@ -53,11 +55,13 @@ export class kpiEvaluationController extends Controller { if (!kpiEvaluation) { throw new HttpError(HttpStatusCode.NOT_FOUND, `ไม่พบข้อมูลเกณฑ์การประเมินนี้: ${item.id}`); } + const before = structuredClone(kpiEvaluation); this.kpiEvaluationRepository.merge(kpiEvaluation, item); kpiEvaluation.lastUpdateUserId = request.user.sub; kpiEvaluation.lastUpdateFullName = request.user.name; - await this.kpiEvaluationRepository.save(kpiEvaluation); + await this.kpiEvaluationRepository.save(kpiEvaluation, { data: request }); + setLogDataDiff(request, { before, after: kpiEvaluation }); updatedIds.push(item.id); } diff --git a/src/controllers/KpiGroupController.ts b/src/controllers/KpiGroupController.ts index 1e53f20..3cd5731 100644 --- a/src/controllers/KpiGroupController.ts +++ b/src/controllers/KpiGroupController.ts @@ -23,6 +23,8 @@ import HttpStatusCode from "../interfaces/http-status"; import { KpiGroup, createKpiGroup, updateKpiGroup } from "../entities/kpiGroup"; import permission from "../interfaces/permission"; import { RequestWithUser } from "../middlewares/user"; +import { addLogSequence, setLogDataDiff } from "../interfaces/utils"; + @Route("api/v1/kpi/group") @Tags("kpiGroup") @Security("bearerAuth") @@ -43,11 +45,8 @@ export class kpiGroupController extends Controller { @Example({ nameGroupKPI: "string", //ชื่อกลุ่มงาน }) - async createKpiGroup( - @Body() requestBody: createKpiGroup, - @Request() request: RequestWithUser, - ) { - await new permission().PermissionCreate(request,"SYS_EVA_COMPETENCY"); + async createKpiGroup(@Body() requestBody: createKpiGroup, @Request() request: RequestWithUser) { + await new permission().PermissionCreate(request, "SYS_EVA_COMPETENCY"); const kpiGroup = Object.assign(new KpiGroup(), requestBody); const chkkpinameGroup = await this.kpiGroupRepository.findOne({ where: { @@ -57,11 +56,15 @@ export class kpiGroupController extends Controller { if (chkkpinameGroup) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ชื่อกลุ่มงานนี้มีอยู่ในระบบแล้ว"); } + const before = null; + kpiGroup.createdUserId = request.user.sub; kpiGroup.createdFullName = request.user.name; kpiGroup.lastUpdateUserId = request.user.sub; kpiGroup.lastUpdateFullName = request.user.name; - await this.kpiGroupRepository.save(kpiGroup); + await this.kpiGroupRepository.save(kpiGroup, { data: request }); + setLogDataDiff(request, { before, after: kpiGroup }); + return new HttpSuccess(kpiGroup.id); } @@ -75,7 +78,7 @@ export class kpiGroupController extends Controller { @Body() requestBody: updateKpiGroup, @Request() request: RequestWithUser, ) { - await new permission().PermissionUpdate(request,"SYS_EVA_COMPETENCY"); + await new permission().PermissionUpdate(request, "SYS_EVA_COMPETENCY"); const kpiGroup = await this.kpiGroupRepository.findOne({ where: { id: id }, }); @@ -86,16 +89,20 @@ export class kpiGroupController extends Controller { const chkkpinameGroup = await this.kpiGroupRepository.findOne({ where: { nameGroupKPI: requestBody.nameGroupKPI, - id: Not(id) + id: Not(id), }, }); if (chkkpinameGroup) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ชื่อกลุ่มงานนี้มีอยู่ในระบบแล้ว"); } + const before = structuredClone(kpiGroup); + this.kpiGroupRepository.merge(kpiGroup, requestBody); kpiGroup.lastUpdateUserId = request.user.sub; kpiGroup.lastUpdateFullName = request.user.name; - await this.kpiGroupRepository.save(kpiGroup); + await this.kpiGroupRepository.save(kpiGroup, { data: request }); + setLogDataDiff(request, { before, after: kpiGroup }); + return new HttpSuccess(id); } @@ -124,7 +131,7 @@ export class kpiGroupController extends Controller { */ @Delete("{id}") async deleteKpiGroup(@Path() id: string, @Request() request: RequestWithUser) { - await new permission().PermissionDelete(request,"SYS_EVA_COMPETENCY"); + await new permission().PermissionDelete(request, "SYS_EVA_COMPETENCY"); const kpiGroup = await this.kpiGroupRepository.findOne({ where: { id: id }, }); @@ -132,7 +139,7 @@ export class kpiGroupController extends Controller { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลกลุ่มงานนี้"); } - await this.kpiGroupRepository.remove(kpiGroup); + await this.kpiGroupRepository.remove(kpiGroup, { data: request }); return new HttpSuccess(); } diff --git a/src/controllers/KpiLinkController.ts b/src/controllers/KpiLinkController.ts index 187addb..92d71c2 100644 --- a/src/controllers/KpiLinkController.ts +++ b/src/controllers/KpiLinkController.ts @@ -26,6 +26,8 @@ import { KpiCapacity } from "../entities/kpiCapacity"; import { Position } from "../entities/position"; import permission from "../interfaces/permission"; import { RequestWithUser } from "../middlewares/user"; +import { addLogSequence, setLogDataDiff } from "../interfaces/utils"; + @Route("api/v1/kpi/link") @Tags("kpiLink") @Security("bearerAuth") @@ -57,6 +59,7 @@ export class kpiLinkController extends Controller { if (!chkkpiGroup) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลการเชื่อมโยง"); } + const before = null; const kpiLink = Object.assign(new KpiLink(), requestBody, { createdUserId: request.user.sub, @@ -65,7 +68,8 @@ export class kpiLinkController extends Controller { lastUpdateFullName: request.user.name, kpiGroup: chkkpiGroup, }); - await this.kpiLinkRepository.save(kpiLink); + await this.kpiLinkRepository.save(kpiLink, { data: request }); + setLogDataDiff(request, { before, after: kpiLink }); if (requestBody.positions != null) { await Promise.all( @@ -77,7 +81,8 @@ export class kpiLinkController extends Controller { position.createdFullName = request.user.name; position.lastUpdateUserId = request.user.sub; position.lastUpdateFullName = request.user.name; - await this.positionRepository.save(position); + await this.positionRepository.save(position, { data: request }); + setLogDataDiff(request, { before, after: position }); }), ); } @@ -92,7 +97,8 @@ export class kpiLinkController extends Controller { } kpiLink.kpiCapacitys = chkCapacity; - await this.kpiLinkRepository.save(kpiLink); + await this.kpiLinkRepository.save(kpiLink, { data: request }); + setLogDataDiff(request, { before, after: kpiLink }); return new HttpSuccess(kpiLink.id); } @@ -120,8 +126,9 @@ export class kpiLinkController extends Controller { if (!chkKpiLink) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลการเชื่อมโยง"); } + const before = structuredClone(chkKpiLink); - await this.positionRepository.remove(chkKpiLink.positions); + await this.positionRepository.remove(chkKpiLink.positions, { data: request }); Object.assign(chkKpiLink, { ...requestBody, kpiCapacitys: [], @@ -140,7 +147,8 @@ export class kpiLinkController extends Controller { position.createdFullName = request.user.name; position.lastUpdateUserId = request.user.sub; position.lastUpdateFullName = request.user.name; - await this.positionRepository.save(position); + await this.positionRepository.save(position, { data: request }); + setLogDataDiff(request, { before: null, after: position }); }), ); } @@ -155,7 +163,8 @@ export class kpiLinkController extends Controller { } chkKpiLink.kpiCapacitys = chkCapacity; - await this.kpiLinkRepository.save(chkKpiLink); + await this.kpiLinkRepository.save(chkKpiLink, { data: request }); + setLogDataDiff(request, { before, after: chkKpiLink }); return new HttpSuccess(chkKpiLink.id); } @@ -208,8 +217,9 @@ export class kpiLinkController extends Controller { if (!kpiLink) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลการเชื่อมโยง"); } + kpiLink.kpiCapacitys = []; - await this.kpiLinkRepository.save(kpiLink); + await this.kpiLinkRepository.save(kpiLink, { data: request }); await this.positionRepository.delete({ kpiLinkId: id }); await this.kpiLinkRepository.delete({ id: id }); diff --git a/src/controllers/KpiPeriodController.ts b/src/controllers/KpiPeriodController.ts index 58ebd8f..2dff088 100644 --- a/src/controllers/KpiPeriodController.ts +++ b/src/controllers/KpiPeriodController.ts @@ -30,6 +30,7 @@ import { KpiUserCapacity } from "../entities/kpiUserCapacity"; import { KpiUserSpecial } from "../entities/kpiUserSpecial"; import { RequestWithUser } from "../middlewares/user"; import permission from "../interfaces/permission"; +import { addLogSequence, setLogDataDiff } from "../interfaces/utils"; @Route("api/v1/kpi/period") @Tags("kpiPeriod") @@ -59,10 +60,7 @@ export class kpiPeriodController extends Controller { startDate: "datetime", //วันเริ่มต้น endDate: "datetime", //วันสิ้นสุด }) - async createKpi( - @Body() requestBody: createKpiPeriod, - @Request() request: RequestWithUser, - ) { + async createKpi(@Body() requestBody: createKpiPeriod, @Request() request: RequestWithUser) { await new permission().PermissionCreate(request, "SYS_KPI_ROUND"); const chkkpiPeriod = await this.kpiPeriodRepository.findOne({ where: { @@ -73,13 +71,16 @@ export class kpiPeriodController extends Controller { if (chkkpiPeriod) { throw new HttpError(HttpStatusCode.NOT_FOUND, "รอบการประเมินผลนี้มีอยู่ในระบบแล้ว"); } + const before = null; const kpiPeriod = Object.assign(new KpiPeriod(), requestBody); kpiPeriod.durationKPI = requestBody.durationKPI.trim().toUpperCase(); kpiPeriod.createdUserId = request.user.sub; kpiPeriod.createdFullName = request.user.name; kpiPeriod.lastUpdateUserId = request.user.sub; kpiPeriod.lastUpdateFullName = request.user.name; - await this.kpiPeriodRepository.save(kpiPeriod); + await this.kpiPeriodRepository.save(kpiPeriod, { data: request }); + setLogDataDiff(request, { before, after: kpiPeriod }); + return new HttpSuccess(kpiPeriod.id); } @@ -115,6 +116,7 @@ export class kpiPeriodController extends Controller { if (chkkpiPeriod) { throw new HttpError(HttpStatusCode.NOT_FOUND, "รอบการประเมินผลนี้มีอยู่ในระบบแล้ว"); } + const before = structuredClone(kpiPeriod); requestBody.durationKPI = requestBody.durationKPI.trim().toUpperCase(); this.kpiPeriodRepository.merge(kpiPeriod, requestBody); @@ -122,7 +124,9 @@ export class kpiPeriodController extends Controller { kpiPeriod.createdFullName = request.user.name; kpiPeriod.lastUpdateUserId = request.user.sub; kpiPeriod.lastUpdateFullName = request.user.name; - await this.kpiPeriodRepository.save(kpiPeriod); + await this.kpiPeriodRepository.save(kpiPeriod, { data: request }); + setLogDataDiff(request, { before, after: kpiPeriod }); + return new HttpSuccess(id); } @@ -136,7 +140,7 @@ export class kpiPeriodController extends Controller { startDate: "datetime", //วันเริ่มต้น endDate: "datetime", //วันสิ้นสุด }) - async CloseKpiPeriodById(@Path() id: string) { + async CloseKpiPeriodById(@Path() id: string, @Request() request: RequestWithUser) { const kpiPeriod = await this.kpiPeriodRepository.findOne({ where: { id: id }, }); @@ -146,8 +150,12 @@ export class kpiPeriodController extends Controller { "ไม่พบข้อมูลรอบการประเมินผลการปฏิบัติหน้าที่ราชการนี้", ); } + const before = structuredClone(kpiPeriod); + kpiPeriod.isActive = false; - await this.kpiPeriodRepository.save(kpiPeriod); + await this.kpiPeriodRepository.save(kpiPeriod, { data: request }); + setLogDataDiff(request, { before, after: kpiPeriod }); + return new HttpSuccess(kpiPeriod); } @@ -161,7 +169,7 @@ export class kpiPeriodController extends Controller { startDate: "datetime", //วันเริ่มต้น endDate: "datetime", //วันสิ้นสุด }) - async OpenKpiPeriodById(@Path() id: string) { + async OpenKpiPeriodById(@Path() id: string, @Request() request: RequestWithUser) { const kpiPeriod = await this.kpiPeriodRepository.findOne({ where: { id: id }, }); @@ -171,8 +179,12 @@ export class kpiPeriodController extends Controller { "ไม่พบข้อมูลรอบการประเมินผลการปฏิบัติหน้าที่ราชการนี้", ); } + const before = structuredClone(kpiPeriod); + kpiPeriod.isActive = true; - await this.kpiPeriodRepository.save(kpiPeriod); + await this.kpiPeriodRepository.save(kpiPeriod, { data: request }); + setLogDataDiff(request, { before, after: kpiPeriod }); + return new HttpSuccess(kpiPeriod); } @@ -220,7 +232,7 @@ export class kpiPeriodController extends Controller { { year: year }, ) .orderBy("kpiPeriod.startDate", "ASC") - .addOrderBy("kpiPeriod.year", "ASC") + .addOrderBy("kpiPeriod.year", "ASC") .skip((page - 1) * pageSize) .take(pageSize) .getManyAndCount(); @@ -275,18 +287,18 @@ export class kpiPeriodController extends Controller { where: { kpiUserEvaluationId: In(kpiPlan.map((x) => x.id)) }, }); - await this.kpiUserRoleRepository.remove(kpiUserRole); - await this.kpiUserPlannedRepository.remove(kpiUserPlanned); + await this.kpiUserRoleRepository.remove(kpiUserRole, { data: request }); + await this.kpiUserPlannedRepository.remove(kpiUserPlanned, { data: request }); - await this.kpiUserRoleRepository.remove(_kpiUserRole); - await this.kpiUserPlannedRepository.remove(_kpiUserPlanned); - await this.kpiUserCapacityRepository.remove(_kpiUserCapacity); - await this.kpiUserSpecialRepository.remove(_kpiUserSpecial); + await this.kpiUserRoleRepository.remove(_kpiUserRole, { data: request }); + await this.kpiUserPlannedRepository.remove(_kpiUserPlanned, { data: request }); + await this.kpiUserCapacityRepository.remove(_kpiUserCapacity, { data: request }); + await this.kpiUserSpecialRepository.remove(_kpiUserSpecial, { data: request }); - await this.kpiRoleRepository.remove(kpiRole); - await this.kpiPlanRepository.remove(kpiPlan); - await this.kpiUserEvaluationRepository.remove(kpiUserEvaluation); - await this.kpiPeriodRepository.remove(kpiPeriod); + await this.kpiRoleRepository.remove(kpiRole, { data: request }); + await this.kpiPlanRepository.remove(kpiPlan, { data: request }); + await this.kpiUserEvaluationRepository.remove(kpiUserEvaluation, { data: request }); + await this.kpiPeriodRepository.remove(kpiPeriod, { data: request }); return new HttpSuccess(); } } diff --git a/src/controllers/KpiPlanController.ts b/src/controllers/KpiPlanController.ts index 32d16ca..585014c 100644 --- a/src/controllers/KpiPlanController.ts +++ b/src/controllers/KpiPlanController.ts @@ -28,6 +28,8 @@ import { KpiSpecial } from "../entities/kpiSpecial"; import { KpiRole } from "../entities/kpiRole"; import permission from "../interfaces/permission"; import { RequestWithUser } from "../middlewares/user"; +import { addLogSequence, setLogDataDiff } from "../interfaces/utils"; + @Route("api/v1/kpi/plan") @Tags("kpiPlan") @Security("bearerAuth") @@ -48,11 +50,8 @@ export class kpiPlanController extends Controller { * @param request */ @Post() - async createKpiPlan( - @Body() requestBody: createKpiPlan, - @Request() request: RequestWithUser, - ) { - await new permission().PermissionCreate(request,"SYS_EVA_INDICATOR"); + async createKpiPlan(@Body() requestBody: createKpiPlan, @Request() request: RequestWithUser) { + await new permission().PermissionCreate(request, "SYS_EVA_INDICATOR"); const kpiPlan = Object.assign(new KpiPlan(), requestBody); if (requestBody.year != null && requestBody.period != null) { const kpiPeriod = await this.kpiPeriodRepository @@ -182,12 +181,15 @@ export class kpiPlanController extends Controller { }) .getRawOne(); } + const before = null; + kpiPlan.including = maxIncludingPlan.maxIncluding + 1; kpiPlan.createdUserId = request.user.sub; kpiPlan.createdFullName = request.user.name; kpiPlan.lastUpdateUserId = request.user.sub; kpiPlan.lastUpdateFullName = request.user.name; - await this.kpiPlanRepository.save(kpiPlan); + await this.kpiPlanRepository.save(kpiPlan, { data: request }); + setLogDataDiff(request, { before, after: kpiPlan }); const history = new KpiPlanHistory(); history.kpiPlanId = kpiPlan.id; @@ -195,7 +197,8 @@ export class kpiPlanController extends Controller { history.createdFullName = request.user.name; history.lastUpdateUserId = request.user.sub; history.lastUpdateFullName = request.user.name; - await this.kpiPlanHistoryRepository.save(history); + await this.kpiPlanHistoryRepository.save(history, { data: request }); + setLogDataDiff(request, { before: null, after: history }); return new HttpSuccess(kpiPlan.id); } @@ -212,7 +215,7 @@ export class kpiPlanController extends Controller { @Body() requestBody: updateKpiPlan, @Request() request: RequestWithUser, ) { - await new permission().PermissionUpdate(request,"SYS_EVA_INDICATOR"); + await new permission().PermissionUpdate(request, "SYS_EVA_INDICATOR"); const kpiPlan = await this.kpiPlanRepository.findOne({ where: { id: id }, }); @@ -272,19 +275,25 @@ export class kpiPlanController extends Controller { kpiPlan.strategyChild5Id = requestBody.strategy <= 4 ? null : x.strategyChild5Id; }) .catch((x) => {}); + + const before = structuredClone(kpiPlan); + kpiPlan.createdUserId = request.user.sub; kpiPlan.createdFullName = request.user.name; kpiPlan.lastUpdateUserId = request.user.sub; kpiPlan.lastUpdateFullName = request.user.name; - await this.kpiPlanRepository.save(kpiPlan); + await this.kpiPlanRepository.save(kpiPlan, { data: request }); + setLogDataDiff(request, { before, after: kpiPlan }); const history = new KpiPlanHistory(); + history.kpiPlanId = kpiPlan.id; history.createdUserId = request.user.sub; history.createdFullName = request.user.name; history.lastUpdateUserId = request.user.sub; history.lastUpdateFullName = request.user.name; - await this.kpiPlanHistoryRepository.save(history); + await this.kpiPlanHistoryRepository.save(history, { data: request }); + setLogDataDiff(request, { before: null, after: history }); return new HttpSuccess(id); } @@ -506,7 +515,7 @@ export class kpiPlanController extends Controller { */ @Delete("{id}") async deleteKpiPlan(@Path() id: string, @Request() request: RequestWithUser) { - await new permission().PermissionDelete(request,"SYS_EVA_INDICATOR"); + await new permission().PermissionDelete(request, "SYS_EVA_INDICATOR"); const kpiPlan = await this.kpiPlanRepository.findOne({ where: { id: id }, }); @@ -524,7 +533,7 @@ export class kpiPlanController extends Controller { type = 4; } await this.kpiPlanHistoryRepository.delete({ kpiPlanId: id }); - await this.kpiPlanRepository.remove(kpiPlan); + await this.kpiPlanRepository.remove(kpiPlan, { data: request }); if (kpiPlan) { let remainingKpiPlans: any; @@ -581,7 +590,7 @@ export class kpiPlanController extends Controller { remainingKpiPlans.forEach((kpiPlan: any, index: any) => { kpiPlan.including = index + 1; }); - await this.kpiPlanRepository.save(remainingKpiPlans); + await this.kpiPlanRepository.save(remainingKpiPlans, { data: request }); } return new HttpSuccess(); diff --git a/src/controllers/KpiReasonController.ts b/src/controllers/KpiReasonController.ts index bcd717e..11c7059 100644 --- a/src/controllers/KpiReasonController.ts +++ b/src/controllers/KpiReasonController.ts @@ -30,6 +30,8 @@ import { KpiUserSpecial } from "../entities/kpiUserSpecial"; import { KpiUserCapacity } from "../entities/kpiUserCapacity"; import { KpiUserDevelopment } from "../entities/kpiUserDevelopment"; import { KpiUserPlanned } from "../entities/kpiUserPlanned"; +import { RequestWithUser } from "../middlewares/user"; +import { addLogSequence, setLogDataDiff } from "../interfaces/utils"; @Route("api/v1/kpi/reason") @Tags("kpiReason") @@ -70,7 +72,7 @@ export class kpiReasonController extends Controller { @Path() user: string, @Path() id: string, @Body() requestBody: updateKpiUserReasonEvaluation, - @Request() request: { user: Record }, + @Request() request: RequestWithUser, ) { if (user.trim().toUpperCase() == "USER") { const kpiUserEvaluation = await this.kpiUserPlan.findOne({ @@ -113,12 +115,16 @@ export class kpiReasonController extends Controller { ? "DONE" : "EVALUATOR"; } + const before = structuredClone(kpiUserEvaluationReason); + kpiUserEvaluationReason.kpiUserPlannedId = id; kpiUserEvaluationReason.createdUserId = request.user.sub; kpiUserEvaluationReason.createdFullName = request.user.name; kpiUserEvaluationReason.lastUpdateUserId = request.user.sub; kpiUserEvaluationReason.lastUpdateFullName = request.user.name; - await this.kpiUserEvaluationReasonPlan.save(kpiUserEvaluationReason); + await this.kpiUserEvaluationReasonPlan.save(kpiUserEvaluationReason, { data: request }); + setLogDataDiff(request, { before, after: kpiUserEvaluationReason }); + return new HttpSuccess(kpiUserEvaluationReason.id); } else { const kpiReason = await this.kpiUserEvaluationReasonPlan.findOne({ @@ -150,9 +156,13 @@ export class kpiReasonController extends Controller { kpiReason.reasonCommanderHigh = requestBody.reason == null ? "" : requestBody.reason; kpiReason.status = "DONE"; } + const before = structuredClone(kpiReason); + kpiReason.lastUpdateUserId = request.user.sub; kpiReason.lastUpdateFullName = request.user.name; - await this.kpiUserEvaluationReasonPlan.save(kpiReason); + await this.kpiUserEvaluationReasonPlan.save(kpiReason, { data: request }); + setLogDataDiff(request, { before, after: kpiReason }); + return new HttpSuccess(kpiReason.id); } } @@ -168,7 +178,7 @@ export class kpiReasonController extends Controller { async sendKpiPlanReason( @Path() id: string, @Body() requestBody: updateKpiUserReasonEvaluation, - @Request() request: { user: Record }, + @Request() request: RequestWithUser, ) { const kpiReason = await this.kpiUserEvaluationReasonPlan.findOne({ where: { id: id }, @@ -180,6 +190,7 @@ export class kpiReasonController extends Controller { "ไม่พบข้อมูลรายการประเมินผลการปฏิบัติราชการระดับบุคคลนี้", ); } + const before = structuredClone(kpiReason); kpiReason.status = kpiReason.kpiUserPlanned.kpiUserEvaluation.evaluatorId == null || @@ -189,7 +200,9 @@ export class kpiReasonController extends Controller { kpiReason.reason = requestBody.reason == null ? "" : requestBody.reason; kpiReason.lastUpdateUserId = request.user.sub; kpiReason.lastUpdateFullName = request.user.name; - await this.kpiUserEvaluationReasonPlan.save(kpiReason); + await this.kpiUserEvaluationReasonPlan.save(kpiReason, { data: request }); + setLogDataDiff(request, { before, after: kpiReason }); + return new HttpSuccess(kpiReason.id); } @@ -286,7 +299,7 @@ export class kpiReasonController extends Controller { @Path() user: string, @Path() id: string, @Body() requestBody: updateKpiUserReasonEvaluation, - @Request() request: { user: Record }, + @Request() request: RequestWithUser, ) { if (user.trim().toUpperCase() == "USER") { const kpiUserEvaluation = await this.kpiUserRole.findOne({ @@ -329,13 +342,16 @@ export class kpiReasonController extends Controller { ? "DONE" : "EVALUATOR"; } + const before = structuredClone(kpiUserEvaluationReason); kpiUserEvaluationReason.kpiUserRoleId = id; kpiUserEvaluationReason.createdUserId = request.user.sub; kpiUserEvaluationReason.createdFullName = request.user.name; kpiUserEvaluationReason.lastUpdateUserId = request.user.sub; kpiUserEvaluationReason.lastUpdateFullName = request.user.name; - await this.kpiUserEvaluationReasonRole.save(kpiUserEvaluationReason); + await this.kpiUserEvaluationReasonRole.save(kpiUserEvaluationReason, { data: request }); + setLogDataDiff(request, { before, after: kpiUserEvaluationReason }); + return new HttpSuccess(kpiUserEvaluationReason.id); } else { const kpiReason = await this.kpiUserEvaluationReasonRole.findOne({ @@ -367,9 +383,13 @@ export class kpiReasonController extends Controller { kpiReason.reasonCommanderHigh = requestBody.reason == null ? "" : requestBody.reason; kpiReason.status = "DONE"; } + const before = structuredClone(kpiReason); + kpiReason.lastUpdateUserId = request.user.sub; kpiReason.lastUpdateFullName = request.user.name; - await this.kpiUserEvaluationReasonRole.save(kpiReason); + await this.kpiUserEvaluationReasonRole.save(kpiReason, { data: request }); + setLogDataDiff(request, { before, after: kpiReason }); + return new HttpSuccess(kpiReason.id); } } @@ -385,7 +405,7 @@ export class kpiReasonController extends Controller { async sendKpiRoleReason( @Path() id: string, @Body() requestBody: updateKpiUserReasonEvaluation, - @Request() request: { user: Record }, + @Request() request: RequestWithUser, ) { const kpiReason = await this.kpiUserEvaluationReasonRole.findOne({ where: { id: id }, @@ -397,6 +417,7 @@ export class kpiReasonController extends Controller { "ไม่พบข้อมูลรายการประเมินผลการปฏิบัติราชการระดับบุคคลนี้", ); } + const before = structuredClone(kpiReason); kpiReason.status = kpiReason.kpiUserRole.kpiUserEvaluation.evaluatorId == null || @@ -406,7 +427,9 @@ export class kpiReasonController extends Controller { kpiReason.reason = requestBody.reason == null ? "" : requestBody.reason; kpiReason.lastUpdateUserId = request.user.sub; kpiReason.lastUpdateFullName = request.user.name; - await this.kpiUserEvaluationReasonRole.save(kpiReason); + await this.kpiUserEvaluationReasonRole.save(kpiReason, { data: request }); + setLogDataDiff(request, { before, after: kpiReason }); + return new HttpSuccess(kpiReason.id); } @@ -503,7 +526,7 @@ export class kpiReasonController extends Controller { @Path() user: string, @Path() id: string, @Body() requestBody: updateKpiUserReasonEvaluation, - @Request() request: { user: Record }, + @Request() request: RequestWithUser, ) { if (user.trim().toUpperCase() == "USER") { const kpiUserEvaluation = await this.kpiUserSpecial.findOne({ @@ -549,12 +572,16 @@ export class kpiReasonController extends Controller { ? "DONE" : "EVALUATOR"; } + const before = structuredClone(kpiUserEvaluationReason); + kpiUserEvaluationReason.kpiUserSpecialId = id; kpiUserEvaluationReason.createdUserId = request.user.sub; kpiUserEvaluationReason.createdFullName = request.user.name; kpiUserEvaluationReason.lastUpdateUserId = request.user.sub; kpiUserEvaluationReason.lastUpdateFullName = request.user.name; - await this.kpiUserEvaluationReasonSpecial.save(kpiUserEvaluationReason); + await this.kpiUserEvaluationReasonSpecial.save(kpiUserEvaluationReason, { data: request }); + setLogDataDiff(request, { before, after: kpiUserEvaluationReason }); + return new HttpSuccess(kpiUserEvaluationReason.id); } else { const kpiReason = await this.kpiUserEvaluationReasonSpecial.findOne({ @@ -586,9 +613,13 @@ export class kpiReasonController extends Controller { kpiReason.reasonCommanderHigh = requestBody.reason == null ? "" : requestBody.reason; kpiReason.status = "DONE"; } + const before = structuredClone(kpiReason); + kpiReason.lastUpdateUserId = request.user.sub; kpiReason.lastUpdateFullName = request.user.name; - await this.kpiUserEvaluationReasonSpecial.save(kpiReason); + await this.kpiUserEvaluationReasonSpecial.save(kpiReason, { data: request }); + setLogDataDiff(request, { before, after: kpiReason }); + return new HttpSuccess(kpiReason.id); } } @@ -604,7 +635,7 @@ export class kpiReasonController extends Controller { async sendKpiSpecialReason( @Path() id: string, @Body() requestBody: updateKpiUserReasonEvaluation, - @Request() request: { user: Record }, + @Request() request: RequestWithUser, ) { const kpiReason = await this.kpiUserEvaluationReasonSpecial.findOne({ where: { id: id }, @@ -616,6 +647,7 @@ export class kpiReasonController extends Controller { "ไม่พบข้อมูลรายการประเมินผลการปฏิบัติราชการระดับบุคคลนี้", ); } + const before = structuredClone(kpiReason); kpiReason.status = kpiReason.kpiUserSpecial.kpiUserEvaluation.evaluatorId == null || @@ -625,7 +657,9 @@ export class kpiReasonController extends Controller { kpiReason.reason = requestBody.reason == null ? "" : requestBody.reason; kpiReason.lastUpdateUserId = request.user.sub; kpiReason.lastUpdateFullName = request.user.name; - await this.kpiUserEvaluationReasonSpecial.save(kpiReason); + await this.kpiUserEvaluationReasonSpecial.save(kpiReason, { data: request }); + setLogDataDiff(request, { before, after: kpiReason }); + return new HttpSuccess(kpiReason.id); } @@ -722,7 +756,7 @@ export class kpiReasonController extends Controller { @Path() user: string, @Path() id: string, @Body() requestBody: updateKpiUserReasonEvaluation, - @Request() request: { user: Record }, + @Request() request: RequestWithUser, ) { if (user.trim().toUpperCase() == "USER") { const kpiUserEvaluation = await this.kpiUserDevelopment.findOne({ @@ -764,12 +798,18 @@ export class kpiReasonController extends Controller { } kpiUserEvaluationReason.status = "DONE"; } + const before = structuredClone(kpiUserEvaluationReason); + kpiUserEvaluationReason.kpiUserDevelopmentId = id; kpiUserEvaluationReason.createdUserId = request.user.sub; kpiUserEvaluationReason.createdFullName = request.user.name; kpiUserEvaluationReason.lastUpdateUserId = request.user.sub; kpiUserEvaluationReason.lastUpdateFullName = request.user.name; - await this.kpiUserEvaluationReasonDevelopment.save(kpiUserEvaluationReason); + await this.kpiUserEvaluationReasonDevelopment.save(kpiUserEvaluationReason, { + data: request, + }); + setLogDataDiff(request, { before, after: kpiUserEvaluationReason }); + return new HttpSuccess(kpiUserEvaluationReason.id); } else { const kpiReason = await this.kpiUserEvaluationReasonDevelopment.findOne({ @@ -801,9 +841,13 @@ export class kpiReasonController extends Controller { kpiReason.reasonCommanderHigh = requestBody.reason == null ? "" : requestBody.reason; kpiReason.status = "DONE"; } + const before = structuredClone(kpiReason); + kpiReason.lastUpdateUserId = request.user.sub; kpiReason.lastUpdateFullName = request.user.name; - await this.kpiUserEvaluationReasonDevelopment.save(kpiReason); + await this.kpiUserEvaluationReasonDevelopment.save(kpiReason, { data: request }); + setLogDataDiff(request, { before, after: kpiReason }); + return new HttpSuccess(kpiReason.id); } } @@ -819,7 +863,7 @@ export class kpiReasonController extends Controller { async sendKpiDevelopmentReason( @Path() id: string, @Body() requestBody: updateKpiUserReasonEvaluation, - @Request() request: { user: Record }, + @Request() request: RequestWithUser, ) { const kpiReason = await this.kpiUserEvaluationReasonDevelopment.findOne({ where: { id: id }, @@ -831,6 +875,7 @@ export class kpiReasonController extends Controller { "ไม่พบข้อมูลรายการประเมินผลการปฏิบัติราชการระดับบุคคลนี้", ); } + const before = structuredClone(kpiReason); kpiReason.status = kpiReason.kpiUserDevelopment.kpiUserEvaluation.evaluatorId == null || @@ -840,7 +885,9 @@ export class kpiReasonController extends Controller { kpiReason.reason = requestBody.reason == null ? "" : requestBody.reason; kpiReason.lastUpdateUserId = request.user.sub; kpiReason.lastUpdateFullName = request.user.name; - await this.kpiUserEvaluationReasonDevelopment.save(kpiReason); + await this.kpiUserEvaluationReasonDevelopment.save(kpiReason, { data: request }); + setLogDataDiff(request, { before, after: kpiReason }); + return new HttpSuccess(kpiReason.id); } @@ -941,7 +988,7 @@ export class kpiReasonController extends Controller { @Path() user: string, @Path() id: string, @Body() requestBody: updateKpiUserReasonEvaluation, - @Request() request: { user: Record }, + @Request() request: RequestWithUser, ) { if (user.trim().toUpperCase() == "USER") { const kpiUserEvaluation = await this.kpiUserCapacity.findOne({ @@ -983,12 +1030,16 @@ export class kpiReasonController extends Controller { } kpiUserEvaluationReason.status = "DONE"; } + const before = structuredClone(kpiUserEvaluationReason); + kpiUserEvaluationReason.kpiUserCapacityId = id; kpiUserEvaluationReason.createdUserId = request.user.sub; kpiUserEvaluationReason.createdFullName = request.user.name; kpiUserEvaluationReason.lastUpdateUserId = request.user.sub; kpiUserEvaluationReason.lastUpdateFullName = request.user.name; - await this.kpiUserEvaluationReasonCapacity.save(kpiUserEvaluationReason); + await this.kpiUserEvaluationReasonCapacity.save(kpiUserEvaluationReason, { data: request }); + setLogDataDiff(request, { before, after: kpiUserEvaluationReason }); + return new HttpSuccess(kpiUserEvaluationReason.id); } else { const kpiReason = await this.kpiUserEvaluationReasonCapacity.findOne({ @@ -1020,9 +1071,13 @@ export class kpiReasonController extends Controller { kpiReason.reasonCommanderHigh = requestBody.reason == null ? "" : requestBody.reason; kpiReason.status = "DONE"; } + const before = structuredClone(kpiReason); + kpiReason.lastUpdateUserId = request.user.sub; kpiReason.lastUpdateFullName = request.user.name; - await this.kpiUserEvaluationReasonCapacity.save(kpiReason); + await this.kpiUserEvaluationReasonCapacity.save(kpiReason, { data: request }); + setLogDataDiff(request, { before, after: kpiReason }); + return new HttpSuccess(kpiReason.id); } } @@ -1038,7 +1093,7 @@ export class kpiReasonController extends Controller { async sendKpiCapacityReason( @Path() id: string, @Body() requestBody: updateKpiUserReasonEvaluation, - @Request() request: { user: Record }, + @Request() request: RequestWithUser, ) { const kpiReason = await this.kpiUserEvaluationReasonCapacity.findOne({ where: { id: id }, @@ -1050,6 +1105,7 @@ export class kpiReasonController extends Controller { "ไม่พบข้อมูลรายการประเมินผลการปฏิบัติราชการระดับบุคคลนี้", ); } + const before = structuredClone(kpiReason); kpiReason.status = kpiReason.kpiUserCapacity.kpiUserEvaluation.evaluatorId == null || @@ -1059,7 +1115,9 @@ export class kpiReasonController extends Controller { kpiReason.reason = requestBody.reason == null ? "" : requestBody.reason; kpiReason.lastUpdateUserId = request.user.sub; kpiReason.lastUpdateFullName = request.user.name; - await this.kpiUserEvaluationReasonCapacity.save(kpiReason); + await this.kpiUserEvaluationReasonCapacity.save(kpiReason, { data: request }); + setLogDataDiff(request, { before, after: kpiReason }); + return new HttpSuccess(kpiReason.id); } diff --git a/src/controllers/KpiRoleController.ts b/src/controllers/KpiRoleController.ts index c1a583d..f54e2cb 100644 --- a/src/controllers/KpiRoleController.ts +++ b/src/controllers/KpiRoleController.ts @@ -26,6 +26,9 @@ import { Brackets, IsNull, Like } from "typeorm"; import { KpiRoleHistory } from "../entities/kpiRoleHistory"; import permission from "../interfaces/permission"; import { RequestWithUser } from "../middlewares/user"; + +import { addLogSequence, setLogDataDiff } from "../interfaces/utils"; + @Route("api/v1/kpi/role") @Tags("kpiRole") @Security("bearerAuth") @@ -44,11 +47,8 @@ export class kpiRoleController extends Controller { * @param request */ @Post() - async createKpiRole( - @Body() requestBody: createKpiRole, - @Request() request: RequestWithUser, - ) { - await new permission().PermissionCreate(request,"SYS_EVA_INDICATOR"); + async createKpiRole(@Body() requestBody: createKpiRole, @Request() request: RequestWithUser) { + await new permission().PermissionCreate(request, "SYS_EVA_INDICATOR"); const kpiRole = Object.assign(new KpiRole(), requestBody); if (requestBody.year != null && requestBody.period != null) { const kpiPeriod = await this.kpiPeriodRepository @@ -175,12 +175,16 @@ export class kpiRoleController extends Controller { }) .getRawOne(); } + + const before = null; + kpiRole.including = maxIncludingRole.maxIncluding + 1; kpiRole.createdUserId = request.user.sub; kpiRole.createdFullName = request.user.name; kpiRole.lastUpdateUserId = request.user.sub; kpiRole.lastUpdateFullName = request.user.name; - await this.kpiRoleRepository.save(kpiRole); + await this.kpiRoleRepository.save(kpiRole, { data: request }); + setLogDataDiff(request, { before, after: kpiRole }); const history = new KpiRoleHistory(); history.kpiRoleId = kpiRole.id; @@ -188,7 +192,8 @@ export class kpiRoleController extends Controller { history.createdFullName = request.user.name; history.lastUpdateUserId = request.user.sub; history.lastUpdateFullName = request.user.name; - await this.kpiRoleHistoryRepository.save(history); + await this.kpiRoleHistoryRepository.save(history, { data: request }); + setLogDataDiff(request, { before, after: kpiRole }); return new HttpSuccess(kpiRole.id); } @@ -205,7 +210,7 @@ export class kpiRoleController extends Controller { @Body() requestBody: updateKpiRole, @Request() request: RequestWithUser, ) { - await new permission().PermissionUpdate(request,"SYS_EVA_INDICATOR"); + await new permission().PermissionUpdate(request, "SYS_EVA_INDICATOR"); const kpiRole = await this.kpiRoleRepository.findOne({ where: { id: id }, }); @@ -247,19 +252,25 @@ export class kpiRoleController extends Controller { kpiRole.child4ShortName = requestBody.node <= 3 ? null : x.child4ShortName; }) .catch((x) => {}); + let before = null; + before = structuredClone(kpiRole); + kpiRole.createdUserId = request.user.sub; kpiRole.createdFullName = request.user.name; kpiRole.lastUpdateUserId = request.user.sub; kpiRole.lastUpdateFullName = request.user.name; - await this.kpiRoleRepository.save(kpiRole); + await this.kpiRoleRepository.save(kpiRole, { data: request }); + setLogDataDiff(request, { before, after: kpiRole }); + before = null; const history = new KpiRoleHistory(); history.kpiRoleId = kpiRole.id; history.createdUserId = request.user.sub; history.createdFullName = request.user.name; history.lastUpdateUserId = request.user.sub; history.lastUpdateFullName = request.user.name; - await this.kpiRoleHistoryRepository.save(history); + await this.kpiRoleHistoryRepository.save(history, { data: request }); + setLogDataDiff(request, { before, after: kpiRole }); return new HttpSuccess(id); } @@ -468,8 +479,8 @@ export class kpiRoleController extends Controller { * @param id */ @Delete("{id}") - async deleteKpiRole(@Path() id: string,@Request() request: RequestWithUser) { - await new permission().PermissionDelete(request,"SYS_EVA_INDICATOR"); + async deleteKpiRole(@Path() id: string, @Request() request: RequestWithUser) { + await new permission().PermissionDelete(request, "SYS_EVA_INDICATOR"); const kpiRole = await this.kpiRoleRepository.findOne({ where: { id: id }, }); @@ -487,7 +498,7 @@ export class kpiRoleController extends Controller { type = 4; } await this.kpiRoleHistoryRepository.delete({ kpiRoleId: id }); - await this.kpiRoleRepository.remove(kpiRole); + await this.kpiRoleRepository.remove(kpiRole, { data: request }); if (kpiRole) { let remainingKpiRoles: any; @@ -549,7 +560,7 @@ export class kpiRoleController extends Controller { remainingKpiRoles.forEach((kpiRole: any, index: any) => { kpiRole.including = index + 1; }); - await this.kpiRoleRepository.save(remainingKpiRoles); + await this.kpiRoleRepository.save(remainingKpiRoles, { data: request }); } return new HttpSuccess(); } diff --git a/src/controllers/KpiSpecialController.ts b/src/controllers/KpiSpecialController.ts index 6885301..5976e39 100644 --- a/src/controllers/KpiSpecialController.ts +++ b/src/controllers/KpiSpecialController.ts @@ -24,6 +24,8 @@ import CallAPI from "../interfaces/call-api"; import { Brackets, IsNull, Like, Not } from "typeorm"; import permission from "../interfaces/permission"; import { RequestWithUser } from "../middlewares/user"; +import { addLogSequence, setLogDataDiff } from "../interfaces/utils"; + @Route("api/v1/kpi/special") @Tags("kpiSpecial") @Security("bearerAuth") @@ -45,7 +47,7 @@ export class kpiSpecialController extends Controller { @Body() requestBody: CreateKpiSpecial, @Request() request: RequestWithUser, ) { - await new permission().PermissionCreate(request,"SYS_EVA_INDICATOR"); + await new permission().PermissionCreate(request, "SYS_EVA_INDICATOR"); const chk_kpiSpecial = await this.kpiSpecialRepository.findOne({ where: { including: String(requestBody.including), @@ -62,11 +64,15 @@ export class kpiSpecialController extends Controller { if (!kpiSpecial) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล"); } + const before = null; + kpiSpecial.createdUserId = request.user.sub; kpiSpecial.createdFullName = request.user.name; kpiSpecial.lastUpdateUserId = request.user.sub; kpiSpecial.lastUpdateFullName = request.user.name; - await this.kpiSpecialRepository.save(kpiSpecial); + await this.kpiSpecialRepository.save(kpiSpecial, { data: request }); + setLogDataDiff(request, { before, after: kpiSpecial }); + return new HttpSuccess(kpiSpecial.id); } @@ -82,7 +88,7 @@ export class kpiSpecialController extends Controller { @Body() requestBody: UpdateKpiSpecial, @Request() request: RequestWithUser, ) { - await new permission().PermissionUpdate(request,"SYS_EVA_INDICATOR"); + await new permission().PermissionUpdate(request, "SYS_EVA_INDICATOR"); const kpiSpecial = await this.kpiSpecialRepository.findOne({ where: { id: id }, }); @@ -103,10 +109,14 @@ export class kpiSpecialController extends Controller { "ไม่สามารถเพิ่มข้อมูลได้เนื่องจากข้อมูลตัวชี้วัดซ้ำ", ); } + const before = structuredClone(kpiSpecial); + kpiSpecial.lastUpdateUserId = request.user.sub; kpiSpecial.lastUpdateFullName = request.user.name; Object.assign(kpiSpecial, requestBody); - await this.kpiSpecialRepository.save(kpiSpecial); + await this.kpiSpecialRepository.save(kpiSpecial, { data: request }); + setLogDataDiff(request, { before, after: kpiSpecial }); + return new HttpSuccess(id); } @@ -216,15 +226,15 @@ export class kpiSpecialController extends Controller { * @param id */ @Delete("{id}") - async deleteKpiSpecial(@Path() id: string, @Request() request: RequestWithUser,) { - await new permission().PermissionDelete(request,"SYS_EVA_INDICATOR"); + async deleteKpiSpecial(@Path() id: string, @Request() request: RequestWithUser) { + await new permission().PermissionDelete(request, "SYS_EVA_INDICATOR"); const kpiSpecial = await this.kpiSpecialRepository.findOne({ where: { id: id }, }); if (!kpiSpecial) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลตัวชี้วัด Specialนี้"); } - await this.kpiSpecialRepository.remove(kpiSpecial); + await this.kpiSpecialRepository.remove(kpiSpecial, { data: request }); return new HttpSuccess(); } } diff --git a/src/controllers/KpiUserCapacityController.ts b/src/controllers/KpiUserCapacityController.ts index c603464..3e0d090 100644 --- a/src/controllers/KpiUserCapacityController.ts +++ b/src/controllers/KpiUserCapacityController.ts @@ -28,6 +28,7 @@ import { Double } from "typeorm/browser"; import { RequestWithUser } from "../middlewares/user"; import permission from "../interfaces/permission"; import { request } from "axios"; +import { addLogSequence, setLogDataDiff } from "../interfaces/utils"; @Route("api/v1/kpi/user/capacity") @Tags("kpiUserCapacity") @@ -88,12 +89,16 @@ export class KpiUserCapacityController extends Controller { "ไม่สามารถเพิ่มข้อมูลได้เนื่องจากรายการสมรรถนะซ้ำ", ); } + const before = null; + const kpiUserCapacity = Object.assign(new KpiUserCapacity(), requestBody); kpiUserCapacity.createdUserId = request.user.sub; kpiUserCapacity.createdFullName = request.user.name; kpiUserCapacity.lastUpdateUserId = request.user.sub; kpiUserCapacity.lastUpdateFullName = request.user.name; - await this.kpiUserCapacityRepository.save(kpiUserCapacity); + await this.kpiUserCapacityRepository.save(kpiUserCapacity, { data: request }); + setLogDataDiff(request, { before, after: kpiUserCapacity }); + return new HttpSuccess(kpiUserCapacity.id); } @@ -154,11 +159,14 @@ export class KpiUserCapacityController extends Controller { "ไม่สามารถแก้ไขข้อมูลได้เนื่องจากรายการสมรรถนะซ้ำ", ); } + const before = structuredClone(kpiUserCapacity); const _kpiUserCapacity = Object.assign(new KpiUserCapacity(), requestBody); kpiUserCapacity.lastUpdateUserId = request.user.sub; kpiUserCapacity.lastUpdateFullName = request.user.name; this.kpiUserCapacityRepository.merge(kpiUserCapacity, _kpiUserCapacity); - await this.kpiUserCapacityRepository.save(kpiUserCapacity); + await this.kpiUserCapacityRepository.save(kpiUserCapacity, { data: request }); + setLogDataDiff(request, { before, after: kpiUserCapacity }); + return new HttpSuccess(kpiUserCapacity.id); } @@ -272,10 +280,13 @@ export class KpiUserCapacityController extends Controller { `ไม่พบข้อมูลพฤติกรรมการปฎิบัติราชการ (สมรรถนะ): ${item.id}`, ); } + const before = structuredClone(kpiUserCapacity); + this.kpiUserCapacityRepository.merge(kpiUserCapacity, item); kpiUserCapacity.lastUpdateUserId = request.user.sub; kpiUserCapacity.lastUpdateFullName = request.user.name; - await this.kpiUserCapacityRepository.save(kpiUserCapacity); + await this.kpiUserCapacityRepository.save(kpiUserCapacity, { data: request }); + setLogDataDiff(request, { before, after: kpiUserCapacity }); } return new HttpSuccess(); } diff --git a/src/controllers/KpiUserDevelopmentController.ts b/src/controllers/KpiUserDevelopmentController.ts index fca466a..9e5561f 100644 --- a/src/controllers/KpiUserDevelopmentController.ts +++ b/src/controllers/KpiUserDevelopmentController.ts @@ -29,6 +29,7 @@ import { Not, Like, Brackets } from "typeorm"; import { DevelopmentProject } from "../entities/developmentProject"; import { RequestWithUser } from "../middlewares/user"; import permission from "../interfaces/permission"; +import { addLogSequence, setLogDataDiff } from "../interfaces/utils"; @Route("api/v1/kpi/user/achievement/development") @Tags("KpiUserDevelopment") @@ -89,12 +90,13 @@ export class KpiUserDevelopmentController extends Controller { // "ไม่สามารถเพิ่มข้อมูลได้เนื่องจากข้อมูลตัวชี้วัดซ้ำ", // ); // } - + let before = null; kpiUserDevelopment.createdUserId = request.user.sub; kpiUserDevelopment.createdFullName = request.user.name; kpiUserDevelopment.lastUpdateUserId = request.user.sub; kpiUserDevelopment.lastUpdateFullName = request.user.name; - await this.kpiUserDevelopmentRepository.save(kpiUserDevelopment); + await this.kpiUserDevelopmentRepository.save(kpiUserDevelopment, { data: request }); + setLogDataDiff(request, { before, after: kpiUserDevelopment }); if (requestBody.developmentProjects != null) { await Promise.all( @@ -106,7 +108,8 @@ export class KpiUserDevelopmentController extends Controller { data.lastUpdateUserId = request.user.sub; data.lastUpdateFullName = request.user.name; data.kpiUserDevelopmentId = kpiUserDevelopment.id; - await this.developmentProjectRepository.save(data); + await this.developmentProjectRepository.save(data, { data: request }); + setLogDataDiff(request, { before, after: data }); }), ); } @@ -169,12 +172,17 @@ export class KpiUserDevelopmentController extends Controller { // "ไม่สามารถเพิ่มข้อมูลได้เนื่องจากข้อมูลตัวชี้วัดซ้ำ", // ); // } - await this.developmentProjectRepository.remove(kpiUserDevelopment.developmentProjects); + await this.developmentProjectRepository.remove(kpiUserDevelopment.developmentProjects, { + data: request, + }); + const before = structuredClone(kpiUserDevelopment); kpiUserDevelopment.lastUpdateUserId = request.user.sub; kpiUserDevelopment.lastUpdateFullName = request.user.name; Object.assign(kpiUserDevelopment, requestBody); - await this.kpiUserDevelopmentRepository.save(kpiUserDevelopment); + await this.kpiUserDevelopmentRepository.save(kpiUserDevelopment, { data: request }); + setLogDataDiff(request, { before, after: kpiUserDevelopment }); + if (requestBody.developmentProjects != null) { await Promise.all( requestBody.developmentProjects.map(async (x) => { @@ -185,7 +193,8 @@ export class KpiUserDevelopmentController extends Controller { data.lastUpdateUserId = request.user.sub; data.lastUpdateFullName = request.user.name; data.kpiUserDevelopmentId = kpiUserDevelopment.id; - await this.developmentProjectRepository.save(data); + await this.developmentProjectRepository.save(data, { data: request }); + setLogDataDiff(request, { before: null, after: data }); }), ); } @@ -208,8 +217,10 @@ export class KpiUserDevelopmentController extends Controller { if (!delKpiUserDevelopment) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลพัฒนาตนเองนี้"); } - await this.developmentProjectRepository.remove(delKpiUserDevelopment.developmentProjects); - await this.kpiUserDevelopmentRepository.remove(delKpiUserDevelopment); + await this.developmentProjectRepository.remove(delKpiUserDevelopment.developmentProjects, { + data: request, + }); + await this.kpiUserDevelopmentRepository.remove(delKpiUserDevelopment, { data: request }); return new HttpSuccess(); } @@ -308,10 +319,12 @@ export class KpiUserDevelopmentController extends Controller { if (!kpiUserDevelopment) { throw new HttpError(HttpStatusCode.NOT_FOUND, `ไม่พบข้อมูลพัฒนาตนเองนี้: ${item.id}`); } + const before = null; this.kpiUserDevelopmentRepository.merge(kpiUserDevelopment, item); kpiUserDevelopment.lastUpdateUserId = request.user.sub; kpiUserDevelopment.lastUpdateFullName = request.user.name; - await this.kpiUserDevelopmentRepository.save(kpiUserDevelopment); + await this.kpiUserDevelopmentRepository.save(kpiUserDevelopment, { data: request }); + setLogDataDiff(request, { before, after: kpiUserDevelopment }); } return new HttpSuccess(); } diff --git a/src/controllers/KpiUserEvaluationController.ts b/src/controllers/KpiUserEvaluationController.ts index 2bc3adc..db33895 100644 --- a/src/controllers/KpiUserEvaluationController.ts +++ b/src/controllers/KpiUserEvaluationController.ts @@ -39,6 +39,7 @@ import { KpiLink } from "../entities/kpiLink"; import { KpiGroup } from "../entities/kpiGroup"; import { RequestWithUser } from "../middlewares/user"; import permission from "../interfaces/permission"; +import { addLogSequence, setLogDataDiff } from "../interfaces/utils"; @Route("api/v1/kpi/user/evaluation") @Tags("kpiUserEvaluation") @@ -249,27 +250,27 @@ export class KpiUserEvaluationController extends Controller { qb.orWhere("kpiUserEvaluation.prefix LIKE :keyword", { keyword: `%${requestBody.keyword}%`, }) - .orWhere("kpiUserEvaluation.firstName LIKE :keyword", { - keyword: `%${requestBody.keyword}%`, - }) - .orWhere("kpiUserEvaluation.lastName LIKE :keyword", { - keyword: `%${requestBody.keyword}%`, - }) - .orWhere("kpiUserEvaluation.org LIKE :keyword", { - keyword: `%${requestBody.keyword}%`, - }) - .orWhere("kpiUserEvaluation.position LIKE :keyword", { - keyword: `%${requestBody.keyword}%`, - }) - .orWhere("kpiUserEvaluation.posTypeName LIKE :keyword", { - keyword: `%${requestBody.keyword}%`, - }) - .orWhere("kpiUserEvaluation.posLevelName LIKE :keyword", { - keyword: `%${requestBody.keyword}%`, - }) - .orWhere(conditionFullName, { - keyword: `%${requestBody.keyword}%`, - }) + .orWhere("kpiUserEvaluation.firstName LIKE :keyword", { + keyword: `%${requestBody.keyword}%`, + }) + .orWhere("kpiUserEvaluation.lastName LIKE :keyword", { + keyword: `%${requestBody.keyword}%`, + }) + .orWhere("kpiUserEvaluation.org LIKE :keyword", { + keyword: `%${requestBody.keyword}%`, + }) + .orWhere("kpiUserEvaluation.position LIKE :keyword", { + keyword: `%${requestBody.keyword}%`, + }) + .orWhere("kpiUserEvaluation.posTypeName LIKE :keyword", { + keyword: `%${requestBody.keyword}%`, + }) + .orWhere("kpiUserEvaluation.posLevelName LIKE :keyword", { + keyword: `%${requestBody.keyword}%`, + }) + .orWhere(conditionFullName, { + keyword: `%${requestBody.keyword}%`, + }); }), ) .orderBy("kpiUserEvaluation.createdAt", "ASC") @@ -400,13 +401,15 @@ export class KpiUserEvaluationController extends Controller { kpiUserEvaluation.posTypeNameEvaluator = x.posTypeName; kpiUserEvaluation.orgEvaluator = x.root; }); + const before = null; kpiUserEvaluation.evaluationStatus = "NEW"; kpiUserEvaluation.evaluationResults = "PENDING"; kpiUserEvaluation.createdUserId = request.user.sub; kpiUserEvaluation.createdFullName = request.user.name; kpiUserEvaluation.lastUpdateUserId = request.user.sub; kpiUserEvaluation.lastUpdateFullName = request.user.name; - await this.kpiUserEvalutionRepository.save(kpiUserEvaluation); + await this.kpiUserEvalutionRepository.save(kpiUserEvaluation, { data: request }); + setLogDataDiff(request, { before, after: kpiUserEvaluation }); enum CapacityType { HEAD = "HEAD", @@ -532,7 +535,9 @@ export class KpiUserEvaluationController extends Controller { kpiUserEvaluation.weightPoint1 = 50; kpiUserEvaluation.weightPoint2 = 50; } - await this.kpiUserEvalutionRepository.save(kpiUserEvaluation); + + await this.kpiUserEvalutionRepository.save(kpiUserEvaluation, { data: request }); + setLogDataDiff(request, { before, after: kpiUserEvaluation }); return new HttpSuccess(kpiUserEvaluation.id); } @@ -548,7 +553,7 @@ export class KpiUserEvaluationController extends Controller { async updateKpiUserCheckEvaluation( @Path() id: string, @Body() requestBody: updateKpiUserCheckEvaluation, - @Request() request: { user: Record }, + @Request() request: RequestWithUser, ) { const kpiUserEvaluation = await this.kpiUserEvalutionRepository.findOne({ where: { id: id }, @@ -559,10 +564,14 @@ export class KpiUserEvaluationController extends Controller { "ไม่พบข้อมูลรายการประเมินผลการปฏิบัติราชการระดับบุคคลนี้", ); } + const before = structuredClone(kpiUserEvaluation); + kpiUserEvaluation.lastUpdateUserId = request.user.sub; kpiUserEvaluation.lastUpdateFullName = request.user.name; Object.assign(kpiUserEvaluation, requestBody); - await this.kpiUserEvalutionRepository.save(kpiUserEvaluation); + await this.kpiUserEvalutionRepository.save(kpiUserEvaluation, { data: request }); + setLogDataDiff(request, { before, after: kpiUserEvaluation }); + return new HttpSuccess(kpiUserEvaluation.id); } @@ -577,7 +586,7 @@ export class KpiUserEvaluationController extends Controller { async updateKpiUserPointEvaluation( @Path() id: string, @Body() requestBody: updateKpiUserPointEvaluation, - @Request() request: { user: Record }, + @Request() request: RequestWithUser, ) { const kpiUserEvaluation = await this.kpiUserEvalutionRepository.findOne({ where: { id: id }, @@ -604,10 +613,12 @@ export class KpiUserEvaluationController extends Controller { } else { kpiUserEvaluation.evaluationResults = "IMPROVEMENT"; } + const before = structuredClone(kpiUserEvaluation); kpiUserEvaluation.lastUpdateUserId = request.user.sub; kpiUserEvaluation.lastUpdateFullName = request.user.name; Object.assign(kpiUserEvaluation, requestBody); - await this.kpiUserEvalutionRepository.save(kpiUserEvaluation); + await this.kpiUserEvalutionRepository.save(kpiUserEvaluation, { data: request }); + setLogDataDiff(request, { before, after: kpiUserEvaluation }); return new HttpSuccess(kpiUserEvaluation.id); } @@ -622,7 +633,7 @@ export class KpiUserEvaluationController extends Controller { async updateKpiUserEvaluation( @Path() id: string, @Body() requestBody: updateKpiUserEvaluation, - @Request() request: { user: Record }, + @Request() request: RequestWithUser, ) { const kpiUserEvaluation = await this.kpiUserEvalutionRepository.findOne({ where: { id: id }, @@ -643,11 +654,12 @@ export class KpiUserEvaluationController extends Controller { "ไม่พบข้อมูลรอบการประเมินผลการปฏิบัติหน้าที่ราชการนี้", ); } - + const before = structuredClone(kpiUserEvaluation); kpiUserEvaluation.lastUpdateUserId = request.user.sub; kpiUserEvaluation.lastUpdateFullName = request.user.name; Object.assign(kpiUserEvaluation, requestBody); - await this.kpiUserEvalutionRepository.save(kpiUserEvaluation); + await this.kpiUserEvalutionRepository.save(kpiUserEvaluation, { data: request }); + setLogDataDiff(request, { before, after: kpiUserEvaluation }); return new HttpSuccess(kpiUserEvaluation.id); } @@ -662,7 +674,7 @@ export class KpiUserEvaluationController extends Controller { async updateKpiUserReqEditEvaluation( @Path() id: string, @Body() requestBody: updateKpiUserReqEditEvaluation, - @Request() request: { user: Record }, + @Request() request: RequestWithUser, ) { const kpiUserEvaluation = await this.kpiUserEvalutionRepository.findOne({ where: { id: id }, @@ -673,10 +685,12 @@ export class KpiUserEvaluationController extends Controller { "ไม่พบข้อมูลรายการประเมินผลการปฏิบัติราชการระดับบุคคลนี้", ); } + const before = structuredClone(kpiUserEvaluation); kpiUserEvaluation.evaluationReqEdit = requestBody.status.trim().toUpperCase(); kpiUserEvaluation.lastUpdateUserId = request.user.sub; kpiUserEvaluation.lastUpdateFullName = request.user.name; - await this.kpiUserEvalutionRepository.save(kpiUserEvaluation); + await this.kpiUserEvalutionRepository.save(kpiUserEvaluation, { data: request }); + setLogDataDiff(request, { before, after: kpiUserEvaluation }); return new HttpSuccess(kpiUserEvaluation.id); } @@ -691,7 +705,7 @@ export class KpiUserEvaluationController extends Controller { async updateKpiUserResultEvaluation( @Path() id: string, @Body() requestBody: updateKpiUserResultEvaluation, - @Request() request: { user: Record }, + @Request() request: RequestWithUser, ) { const kpiUserEvaluation = await this.kpiUserEvalutionRepository.findOne({ where: { id: id }, @@ -702,10 +716,12 @@ export class KpiUserEvaluationController extends Controller { "ไม่พบข้อมูลรายการประเมินผลการปฏิบัติราชการระดับบุคคลนี้", ); } + const before = structuredClone(kpiUserEvaluation); kpiUserEvaluation.evaluationResults = requestBody.status.trim().toUpperCase(); kpiUserEvaluation.lastUpdateUserId = request.user.sub; kpiUserEvaluation.lastUpdateFullName = request.user.name; - await this.kpiUserEvalutionRepository.save(kpiUserEvaluation); + await this.kpiUserEvalutionRepository.save(kpiUserEvaluation, { data: request }); + setLogDataDiff(request, { before, after: kpiUserEvaluation }); return new HttpSuccess(kpiUserEvaluation.id); } @@ -720,7 +736,7 @@ export class KpiUserEvaluationController extends Controller { async updateKpiUserStatusEvaluation( @Path() id: string, @Body() requestBody: updateKpiUserStatusEvaluation, - @Request() request: { user: Record }, + @Request() request: RequestWithUser, ) { const kpiUserEvaluation = await this.kpiUserEvalutionRepository.findOne({ where: { id: id }, @@ -758,10 +774,12 @@ export class KpiUserEvaluationController extends Controller { .then((x) => {}) .catch((x) => {}); } + const before = structuredClone(kpiUserEvaluation); kpiUserEvaluation.evaluationStatus = requestBody.status.trim().toUpperCase(); kpiUserEvaluation.lastUpdateUserId = request.user.sub; kpiUserEvaluation.lastUpdateFullName = request.user.name; - await this.kpiUserEvalutionRepository.save(kpiUserEvaluation); + await this.kpiUserEvalutionRepository.save(kpiUserEvaluation, { data: request }); + setLogDataDiff(request, { before, after: kpiUserEvaluation }); return new HttpSuccess(kpiUserEvaluation.id); } @@ -893,7 +911,7 @@ export class KpiUserEvaluationController extends Controller { * @param {string} id Guid, *Id รายการประเมินผลการปฏิบัติราชการระดับบุคคล (USER) */ @Delete("{id}") - async deleteKpiUserEvaluation(@Path() id: string) { + async deleteKpiUserEvaluation(@Path() id: string, @Request() request: RequestWithUser) { const kpiUserEvaluation = await this.kpiUserEvalutionRepository.findOne({ where: { id: id }, }); @@ -903,7 +921,7 @@ export class KpiUserEvaluationController extends Controller { "ไม่พบข้อมูลการประเมินผลการปฏิบัติราชการระดับบุคคลนี้", ); } - await this.kpiUserEvalutionRepository.remove(kpiUserEvaluation); + await this.kpiUserEvalutionRepository.remove(kpiUserEvaluation, { data: request }); return new HttpSuccess(); } @@ -916,7 +934,7 @@ export class KpiUserEvaluationController extends Controller { */ @Post("admin/change-status") async ChangeStatus( - @Request() request: { user: Record }, + @Request() request: RequestWithUser, @Body() requestBody: { status: string; @@ -1000,9 +1018,11 @@ export class KpiUserEvaluationController extends Controller { } else { item.evaluationStatus = requestBody.status.trim().toUpperCase(); } + const before = null; item.lastUpdateUserId = request.user.sub; item.lastUpdateFullName = request.user.name; - await this.kpiUserEvalutionRepository.save(item); + await this.kpiUserEvalutionRepository.save(item, { data: request }); + setLogDataDiff(request, { before, after: item }); }), ); return new HttpSuccess(); @@ -1017,7 +1037,7 @@ export class KpiUserEvaluationController extends Controller { */ @Post("admin/req-edit") async RequestEdit( - @Request() request: { user: Record }, + @Request() request: RequestWithUser, @Body() requestBody: { status: string; @@ -1081,9 +1101,11 @@ export class KpiUserEvaluationController extends Controller { item.evaluationReqEdit = requestBody.status.trim().toUpperCase(); } + const before = null; item.lastUpdateUserId = request.user.sub; item.lastUpdateFullName = request.user.name; - await this.kpiUserEvalutionRepository.save(item); + await this.kpiUserEvalutionRepository.save(item, { data: request }); + setLogDataDiff(request, { before, after: item }); }); return new HttpSuccess(); @@ -1098,7 +1120,7 @@ export class KpiUserEvaluationController extends Controller { */ @Post("admin/result-status") async ResultStatus( - @Request() request: { user: Record }, + @Request() request: RequestWithUser, @Body() requestBody: { status: string; @@ -1159,9 +1181,11 @@ export class KpiUserEvaluationController extends Controller { // } else { // // item.evaluationStatus = requestBody.status.trim().toUpperCase(); // } + const before = null; item.lastUpdateUserId = request.user.sub; item.lastUpdateFullName = request.user.name; - await this.kpiUserEvalutionRepository.save(item); + await this.kpiUserEvalutionRepository.save(item, { data: request }); + setLogDataDiff(request, { before, after: item }); }); return new HttpSuccess(); @@ -1173,10 +1197,7 @@ export class KpiUserEvaluationController extends Controller { * @param {string} id Guid, *Id คนประเมิน (USER) */ @Get("open/{id}") - async openKpiUserEvaluation( - @Path() id: string, - @Request() request: { user: Record }, - ) { + async openKpiUserEvaluation(@Path() id: string, @Request() request: RequestWithUser) { const kpiUserEvaluation = await this.kpiUserEvalutionRepository.findOne({ where: { id: id }, }); @@ -1186,11 +1207,13 @@ export class KpiUserEvaluationController extends Controller { "ไม่พบข้อมูลรายการประเมินผลการปฏิบัติราชการระดับบุคคลนี้", ); } + const before = structuredClone(kpiUserEvaluation); kpiUserEvaluation.isOpen = true; kpiUserEvaluation.openDate = new Date(); kpiUserEvaluation.lastUpdateUserId = request.user.sub; kpiUserEvaluation.lastUpdateFullName = request.user.name; - await this.kpiUserEvalutionRepository.save(kpiUserEvaluation); + await this.kpiUserEvalutionRepository.save(kpiUserEvaluation, { data: request }); + setLogDataDiff(request, { before, after: kpiUserEvaluation }); return new HttpSuccess(kpiUserEvaluation.id); } @@ -1211,7 +1234,7 @@ export class KpiUserEvaluationController extends Controller { timeEvaluator?: string | null; reasonEvaluator?: string | null; }, - @Request() request: { user: Record }, + @Request() request: RequestWithUser, ) { const kpiUserEvaluation = await this.kpiUserEvalutionRepository.findOne({ where: { id: id }, @@ -1252,6 +1275,8 @@ export class KpiUserEvaluationController extends Controller { .catch((x) => {}); kpiUserEvaluation.evaluationStatus = "SUMMARY_COMMANDER"; } + const before = structuredClone(kpiUserEvaluation); + kpiUserEvaluation.topicEvaluator = requestBody.topicEvaluator == null ? _null : requestBody.topicEvaluator; kpiUserEvaluation.developEvaluator = @@ -1262,7 +1287,8 @@ export class KpiUserEvaluationController extends Controller { requestBody.reasonEvaluator == null ? _null : requestBody.reasonEvaluator; kpiUserEvaluation.lastUpdateUserId = request.user.sub; kpiUserEvaluation.lastUpdateFullName = request.user.name; - await this.kpiUserEvalutionRepository.save(kpiUserEvaluation); + await this.kpiUserEvalutionRepository.save(kpiUserEvaluation, { data: request }); + setLogDataDiff(request, { before, after: kpiUserEvaluation }); return new HttpSuccess(kpiUserEvaluation.id); } @@ -1281,7 +1307,7 @@ export class KpiUserEvaluationController extends Controller { isReason: boolean; reason?: string | null; }, - @Request() request: { user: Record }, + @Request() request: RequestWithUser, ) { const kpiUserEvaluation = await this.kpiUserEvalutionRepository.findOne({ where: { id: id }, @@ -1322,11 +1348,15 @@ export class KpiUserEvaluationController extends Controller { .catch((x) => {}); kpiUserEvaluation.evaluationStatus = "SUMMARY_COMMANDER_HIGH"; } + const before = structuredClone(kpiUserEvaluation); + kpiUserEvaluation.isReasonCommander = requestBody.isReason; kpiUserEvaluation.reasonCommander = requestBody.reason == null ? _null : requestBody.reason; kpiUserEvaluation.lastUpdateUserId = request.user.sub; kpiUserEvaluation.lastUpdateFullName = request.user.name; - await this.kpiUserEvalutionRepository.save(kpiUserEvaluation); + await this.kpiUserEvalutionRepository.save(kpiUserEvaluation, { data: request }); + setLogDataDiff(request, { before, after: kpiUserEvaluation }); + return new HttpSuccess(kpiUserEvaluation.id); } @@ -1345,7 +1375,7 @@ export class KpiUserEvaluationController extends Controller { isReason: boolean; reason?: string | null; }, - @Request() request: { user: Record }, + @Request() request: RequestWithUser, ) { const kpiUserEvaluation = await this.kpiUserEvalutionRepository.findOne({ where: { id: id }, @@ -1370,11 +1400,15 @@ export class KpiUserEvaluationController extends Controller { }) .then((x) => {}) .catch((x) => {}); + const before = structuredClone(kpiUserEvaluation); + kpiUserEvaluation.isReasonCommanderHigh = requestBody.isReason; kpiUserEvaluation.reasonCommanderHigh = requestBody.reason == null ? _null : requestBody.reason; kpiUserEvaluation.lastUpdateUserId = request.user.sub; kpiUserEvaluation.lastUpdateFullName = request.user.name; - await this.kpiUserEvalutionRepository.save(kpiUserEvaluation); + await this.kpiUserEvalutionRepository.save(kpiUserEvaluation, { data: request }); + setLogDataDiff(request, { before, after: kpiUserEvaluation }); + return new HttpSuccess(kpiUserEvaluation.id); } /** @@ -1425,9 +1459,11 @@ export class KpiUserEvaluationController extends Controller { }) .then((x) => {}) .catch((x) => {}); + const before = null; kpiUserEvaluation.lastUpdateUserId = request.user.sub; kpiUserEvaluation.lastUpdateFullName = request.user.name; - await this.kpiUserEvalutionRepository.save(kpiUserEvaluation); + await this.kpiUserEvalutionRepository.save(kpiUserEvaluation, { data: request }); + setLogDataDiff(request, { before, after: kpiUserEvaluation }); }), ); @@ -1494,10 +1530,7 @@ export class KpiUserEvaluationController extends Controller { * @param {string} id Guid, *Id คนประเมิน (USER) */ @Get("summary/{id}") - async getSummaryKpiEvaluation( - @Path() id: string, - @Request() request: { user: Record }, - ) { + async getSummaryKpiEvaluation(@Path() id: string, @Request() request: RequestWithUser) { const kpiUserEvaluation = await this.kpiUserEvalutionRepository.findOne({ where: { id: id }, select: ["id", "evaluationStatus", "lastUpdateUserId", "lastUpdateFullName"], @@ -1508,10 +1541,13 @@ export class KpiUserEvaluationController extends Controller { "ไม่พบข้อมูลรายการประเมินผลการปฏิบัติราชการระดับบุคคลนี้", ); } + const before = structuredClone(kpiUserEvaluation); kpiUserEvaluation.evaluationStatus = "SUMMARY"; kpiUserEvaluation.lastUpdateUserId = request.user.sub; kpiUserEvaluation.lastUpdateFullName = request.user.name; - await this.kpiUserEvalutionRepository.save(kpiUserEvaluation); + await this.kpiUserEvalutionRepository.save(kpiUserEvaluation, { data: request }); + setLogDataDiff(request, { before, after: kpiUserEvaluation }); + return new HttpSuccess(kpiUserEvaluation); } } diff --git a/src/controllers/KpiUserPlannedController.ts b/src/controllers/KpiUserPlannedController.ts index 14c6641..e6ea658 100644 --- a/src/controllers/KpiUserPlannedController.ts +++ b/src/controllers/KpiUserPlannedController.ts @@ -31,6 +31,7 @@ import { KpiUserEvaluation } from "../entities/kpiUserEvaluation"; import { KpiPlan } from "../entities/kpiPlan"; import { RequestWithUser } from "../middlewares/user"; import permission from "../interfaces/permission"; +import { addLogSequence, setLogDataDiff } from "../interfaces/utils"; @Route("api/v1/kpi/user/achievement/planned") @Tags("KpiUserPlanned") @@ -90,6 +91,7 @@ export class KpiUserPlannedController extends Controller { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล"); } + const before = null; kpiUserPlanned.startDate = requestBody.startDate == undefined ? null : requestBody.startDate; kpiUserPlanned.endDate = requestBody.endDate == undefined ? null : requestBody.endDate; kpiUserPlanned.createdUserId = request.user.sub; @@ -104,7 +106,8 @@ export class KpiUserPlannedController extends Controller { // kpiUserPlanned.achievement3 = request.user.achievement3; // kpiUserPlanned.achievement4 = request.user.achievement4; // kpiUserPlanned.achievement5 = request.user.achievement5; - await this.kpiUserPlannedRepository.save(kpiUserPlanned); + await this.kpiUserPlannedRepository.save(kpiUserPlanned, { data: request }); + setLogDataDiff(request, { before, after: kpiUserPlanned }); return new HttpSuccess(kpiUserPlanned.id); } @@ -140,7 +143,7 @@ export class KpiUserPlannedController extends Controller { "ไม่สามารถเพิ่มข้อมูลได้เนื่องจากข้อมูลตัวชี้วัดซ้ำ", ); } - + const before = structuredClone(kpiUserPlanned); kpiUserPlanned.lastUpdateUserId = request.user.sub; kpiUserPlanned.lastUpdateFullName = request.user.name; // kpiUserPlanned.documentInfoEvidence = request.user.documentInfoEvidence; @@ -155,7 +158,8 @@ export class KpiUserPlannedController extends Controller { Object.assign(kpiUserPlanned, requestBody); kpiUserPlanned.startDate = requestBody.startDate == undefined ? null : requestBody.startDate; kpiUserPlanned.endDate = requestBody.endDate == undefined ? null : requestBody.endDate; - await this.kpiUserPlannedRepository.save(kpiUserPlanned); + await this.kpiUserPlannedRepository.save(kpiUserPlanned, { data: request }); + setLogDataDiff(request, { before, after: kpiUserPlanned }); return new HttpSuccess(kpiUserPlanned.id); } @@ -173,7 +177,7 @@ export class KpiUserPlannedController extends Controller { if (!delKpiUserPlanned) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลงานตามแผนปฏิบัติราชการประจำปีนี้"); } - await this.kpiUserPlannedRepository.remove(delKpiUserPlanned); + await this.kpiUserPlannedRepository.remove(delKpiUserPlanned, { data: request }); return new HttpSuccess(); } @@ -292,10 +296,12 @@ export class KpiUserPlannedController extends Controller { `ไม่พบข้อมูลงานตามแผนปฏิบัติราชการประจำปีนี้: ${item.id}`, ); } + const before = structuredClone(kpiUserPlanned); this.kpiUserPlannedRepository.merge(kpiUserPlanned, item); kpiUserPlanned.lastUpdateUserId = request.user.sub; kpiUserPlanned.lastUpdateFullName = request.user.name; - await this.kpiUserPlannedRepository.save(kpiUserPlanned); + await this.kpiUserPlannedRepository.save(kpiUserPlanned, { data: request }); + setLogDataDiff(request, { before, after: kpiUserPlanned }); } return new HttpSuccess(); } diff --git a/src/controllers/KpiUserRoleController.ts b/src/controllers/KpiUserRoleController.ts index 0b70932..43a1904 100644 --- a/src/controllers/KpiUserRoleController.ts +++ b/src/controllers/KpiUserRoleController.ts @@ -31,6 +31,7 @@ import { KpiUserEvaluation } from "../entities/kpiUserEvaluation"; import { KpiRole } from "../entities/kpiRole"; import { RequestWithUser } from "../middlewares/user"; import permission from "../interfaces/permission"; +import { addLogSequence, setLogDataDiff } from "../interfaces/utils"; @Route("api/v1/kpi/user/achievement/role") @Tags("KpiUserRole") @@ -93,13 +94,16 @@ export class KpiUserRoleController extends Controller { ); } + const before = null; kpiUserRole.startDate = requestBody.startDate == undefined ? null : requestBody.startDate; kpiUserRole.endDate = requestBody.endDate == undefined ? null : requestBody.endDate; kpiUserRole.createdUserId = request.user.sub; kpiUserRole.createdFullName = request.user.name; kpiUserRole.lastUpdateUserId = request.user.sub; kpiUserRole.lastUpdateFullName = request.user.name; - await this.kpiUserRoleRepository.save(kpiUserRole); + await this.kpiUserRoleRepository.save(kpiUserRole, { data: request }); + setLogDataDiff(request, { before, after: kpiUserRole }); + return new HttpSuccess(kpiUserRole.id); } @@ -151,13 +155,15 @@ export class KpiUserRoleController extends Controller { "ไม่สามารถเพิ่มข้อมูลได้เนื่องจากข้อมูลตัวชี้วัดซ้ำ", ); } - + const before = structuredClone(kpiUserRole); kpiUserRole.lastUpdateUserId = request.user.sub; kpiUserRole.lastUpdateFullName = request.user.name; Object.assign(kpiUserRole, requestBody); kpiUserRole.startDate = requestBody.startDate == undefined ? null : requestBody.startDate; kpiUserRole.endDate = requestBody.endDate == undefined ? null : requestBody.endDate; - await this.kpiUserRoleRepository.save(kpiUserRole); + await this.kpiUserRoleRepository.save(kpiUserRole, { data: request }); + setLogDataDiff(request, { before, after: kpiUserRole }); + return new HttpSuccess(kpiUserRole.id); } @@ -175,7 +181,7 @@ export class KpiUserRoleController extends Controller { if (!delKpiUserRole) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลงานตามหน้าที่ความรับผิดชอบหลักนี้"); } - await this.kpiUserRoleRepository.remove(delKpiUserRole); + await this.kpiUserRoleRepository.remove(delKpiUserRole, { data: request }); return new HttpSuccess(); } @@ -295,10 +301,12 @@ export class KpiUserRoleController extends Controller { `ไม่พบข้อมูลงานตามหน้าที่ความรับผิดชอบหลักนี้: ${item.id}`, ); } + const before = null; this.kpiUserRoleRepository.merge(kpiUserRole, item); kpiUserRole.lastUpdateUserId = request.user.sub; kpiUserRole.lastUpdateFullName = request.user.name; - await this.kpiUserRoleRepository.save(kpiUserRole); + await this.kpiUserRoleRepository.save(kpiUserRole, { data: request }); + setLogDataDiff(request, { before, after: kpiUserRole }); } return new HttpSuccess(); } diff --git a/src/controllers/KpiUserSpecialController.ts b/src/controllers/KpiUserSpecialController.ts index d8f57b6..04dfd9d 100644 --- a/src/controllers/KpiUserSpecialController.ts +++ b/src/controllers/KpiUserSpecialController.ts @@ -29,6 +29,7 @@ import { KpiSpecial } from "../entities/kpiSpecial"; import { Not } from "typeorm"; import { RequestWithUser } from "../middlewares/user"; import permission from "../interfaces/permission"; +import { addLogSequence, setLogDataDiff } from "../interfaces/utils"; @Route("api/v1/kpi/user/achievement/special") @Tags("KpiUserSpecial") @@ -93,6 +94,7 @@ export class KpiUserSpecialController extends Controller { includingName: String(requestBody.includingName), }, }); + let before = null; if (!chk_kpiSpecial) { const kpiSpecial = Object.assign(new KpiSpecial(), requestBody); if (!kpiSpecial) { @@ -102,7 +104,8 @@ export class KpiUserSpecialController extends Controller { kpiSpecial.createdFullName = request.user.name; kpiSpecial.lastUpdateUserId = request.user.sub; kpiSpecial.lastUpdateFullName = request.user.name; - await this.kpiSpecialRepository.save(kpiSpecial); + await this.kpiSpecialRepository.save(kpiSpecial, { data: request }); + setLogDataDiff(request, { before, after: kpiSpecial }); } kpiUserSpecial.startDate = requestBody.startDate == undefined ? null : requestBody.startDate; kpiUserSpecial.endDate = requestBody.endDate == undefined ? null : requestBody.endDate; @@ -110,7 +113,9 @@ export class KpiUserSpecialController extends Controller { kpiUserSpecial.createdFullName = request.user.name; kpiUserSpecial.lastUpdateUserId = request.user.sub; kpiUserSpecial.lastUpdateFullName = request.user.name; - await this.kpiUserSpecialRepository.save(kpiUserSpecial); + await this.kpiUserSpecialRepository.save(kpiUserSpecial, { data: request }); + setLogDataDiff(request, { before, after: kpiUserSpecial }); + return new HttpSuccess(kpiUserSpecial.id); } @@ -165,23 +170,29 @@ export class KpiUserSpecialController extends Controller { includingName: String(requestBody.includingName), }, }); + let before = null; if (!chk_kpiSpecial) { const kpiSpecial = Object.assign(new KpiSpecial(), requestBody); if (!kpiSpecial) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล"); } + before = structuredClone(kpiSpecial); kpiSpecial.createdUserId = request.user.sub; kpiSpecial.createdFullName = request.user.name; kpiSpecial.lastUpdateUserId = request.user.sub; kpiSpecial.lastUpdateFullName = request.user.name; - await this.kpiSpecialRepository.save(kpiSpecial); + await this.kpiSpecialRepository.save(kpiSpecial, { data: request }); + setLogDataDiff(request, { before, after: kpiSpecial }); } + before = structuredClone(kpiUserSpecial); kpiUserSpecial.lastUpdateUserId = request.user.sub; kpiUserSpecial.lastUpdateFullName = request.user.name; Object.assign(kpiUserSpecial, requestBody); kpiUserSpecial.startDate = requestBody.startDate == undefined ? null : requestBody.startDate; kpiUserSpecial.endDate = requestBody.endDate == undefined ? null : requestBody.endDate; - await this.kpiUserSpecialRepository.save(kpiUserSpecial); + await this.kpiUserSpecialRepository.save(kpiUserSpecial, { data: request }); + setLogDataDiff(request, { before, after: kpiUserSpecial }); + return new HttpSuccess(kpiUserSpecial.id); } @@ -198,7 +209,7 @@ export class KpiUserSpecialController extends Controller { if (!delKpiUserSpecial) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลงานที่ได้รับมอบหมายพิเศษนี้"); } - await this.kpiUserSpecialRepository.remove(delKpiUserSpecial); + await this.kpiUserSpecialRepository.remove(delKpiUserSpecial, { data: request }); return new HttpSuccess(); } @@ -328,10 +339,12 @@ export class KpiUserSpecialController extends Controller { `ไม่พบข้อมูลงานที่ได้รับมอบหมายพิเศษนี้: ${item.id}`, ); } + const before = null; this.kpiUserSpecialRepository.merge(kpiUserSpecial, item); kpiUserSpecial.lastUpdateUserId = request.user.sub; kpiUserSpecial.lastUpdateFullName = request.user.name; - await this.kpiUserSpecialRepository.save(kpiUserSpecial); + await this.kpiUserSpecialRepository.save(kpiUserSpecial, { data: request }); + setLogDataDiff(request, { before, after: kpiUserSpecial }); } return new HttpSuccess(); } diff --git a/src/database/data-source.ts b/src/database/data-source.ts index 7c70f52..d713314 100644 --- a/src/database/data-source.ts +++ b/src/database/data-source.ts @@ -1,6 +1,46 @@ import "dotenv/config"; import "reflect-metadata"; -import { DataSource } from "typeorm"; +import { DataSource, LogLevel, LogMessage } from "typeorm"; +import { Logger } from "typeorm"; +import { QueryRunner } from "typeorm/browser"; +import { RequestWithUser } from "../middlewares/user"; +import { addLogSequence } from "../interfaces/utils"; + +export class MyCustomLogger implements Logger { + log(level: "log" | "info" | "warn", message: any, queryRunner?: QueryRunner) {} + + logQuery(query: string, parameters?: any[], queryRunner?: QueryRunner): void { + const req = queryRunner?.data as RequestWithUser; + if (req?.app?.locals.logData?.sequence) { + addLogSequence(req, { + action: "database", + status: "success", + description: "Query Data.", + query: [ + "Query: " + query + (parameters ? " - Parameters:" + JSON.stringify(parameters) : ""), + ], + }); + } + + // const req = queryRunner?.data as RequestWithUser | undefined; + // const logData = req?.app?.locals.logData?.sequence?.at(-1); + + // if (logData && !logData.query) logData.query = []; + // if (logData) logData.query.push( + // "Query: " + query + (parameters ? (" - Parameters:" + JSON.stringify(parameters)) : '') + // ); + } + + logMigration(message: string, queryRunner?: QueryRunner) {} + logQueryError( + error: string | Error, + query: string, + parameters?: any[], + queryRunner?: QueryRunner, + ) {} + logQuerySlow(time: number, query: string, parameters?: any[], queryRunner?: QueryRunner) {} + logSchemaBuild(message: string, queryRunner?: QueryRunner) {} +} export const AppDataSource = new DataSource({ type: "mysql", @@ -11,7 +51,7 @@ export const AppDataSource = new DataSource({ password: process.env.DB_PASSWORD, connectorPackage: "mysql2", synchronize: false, - logging: true, + logging: ["query", "error"], entities: process.env.NODE_ENV !== "production" ? ["src/entities/**/*.ts"] @@ -21,7 +61,5 @@ export const AppDataSource = new DataSource({ ? ["src/migration/**/*.ts"] : ["dist/migration/**/*{.ts,.js}"], subscribers: [], + logger: new MyCustomLogger(), }); -// console.log(AppDataSource); - -// export default database; diff --git a/src/interfaces/call-api.ts b/src/interfaces/call-api.ts index 69364e4..78f0f14 100644 --- a/src/interfaces/call-api.ts +++ b/src/interfaces/call-api.ts @@ -12,6 +12,7 @@ import { Path, } from "tsoa"; import axios from "axios"; +import { addLogSequence } from "./utils"; class CallAPI { //Get @@ -26,8 +27,28 @@ class CallAPI { api_key: process.env.API_KEY, }, }); + addLogSequence(request, { + action: "request", + status: "success", + description: "connected", + request: { + method: "GET", + url: url, + response: JSON.stringify(response.data.result), + }, + }); return response.data.result; } catch (error) { + addLogSequence(request, { + action: "request", + status: "error", + description: "unconnected", + request: { + method: "GET", + url: url, + response: JSON.stringify(error), + }, + }); throw error; } } @@ -43,8 +64,30 @@ class CallAPI { api_key: process.env.API_KEY, }, }); + addLogSequence(request, { + action: "request", + status: "success", + description: "connected", + request: { + method: "POST", + url: url, + payload: JSON.stringify(sendData), + response: JSON.stringify(response.data.result), + }, + }); return response.data.result; } catch (error) { + addLogSequence(request, { + action: "request", + status: "error", + description: "unconnected", + request: { + method: "POST", + url: url, + payload: JSON.stringify(sendData), + response: JSON.stringify(error), + }, + }); throw error; } } diff --git a/src/interfaces/utils.ts b/src/interfaces/utils.ts new file mode 100644 index 0000000..30035f0 --- /dev/null +++ b/src/interfaces/utils.ts @@ -0,0 +1,37 @@ +import { RequestWithUser } from "../middlewares/user"; + +export type DataDiff = { + before: any; + after: any; +}; + +export type LogSequence = { + action: string; + status: "success" | "error"; + description: string; + query?: any; + request?: { + method?: "GET" | "POST" | "PUT" | "DELETE" | "PATCH"; + url?: string; + payload?: string; + response?: string; + }; +}; + +export function setLogDataDiff(req: RequestWithUser, data: DataDiff) { + req.app.locals.logData.dataDiff = { + before: JSON.stringify(data.before), + after: JSON.stringify(data.after), + }; +} + +export function addLogSequence(req: RequestWithUser, data: LogSequence) { + if (!req?.app?.locals?.logData?.sequence) { + req.app.locals.logData.sequence = []; + } + req.app.locals.logData.sequence = req.app.locals.logData.sequence.concat(data); +} + +export function editLogSequence(req: RequestWithUser, index: number, data: LogSequence) { + req.app.locals.logData.sequence[index] = data; +} diff --git a/src/middlewares/auth.ts b/src/middlewares/auth.ts index e81aa15..de43a0c 100644 --- a/src/middlewares/auth.ts +++ b/src/middlewares/auth.ts @@ -3,15 +3,13 @@ import { createDecoder, createVerifier } from "fast-jwt"; import HttpError from "../interfaces/http-error"; import HttpStatus from "../interfaces/http-status"; +import { addLogSequence } from "../interfaces/utils"; +import { RequestWithUser } from "./user"; if (!process.env.AUTH_PUBLIC_KEY && !process.env.AUTH_REALM_URL) { throw new Error("Require keycloak AUTH_PUBLIC_KEY or AUTH_REALM_URL."); } -if ( - process.env.AUTH_PUBLIC_KEY && - process.env.AUTH_REALM_URL && - !process.env.AUTH_PREFERRED_MODE -) { +if (process.env.AUTH_PUBLIC_KEY && process.env.AUTH_REALM_URL && !process.env.AUTH_PREFERRED_MODE) { throw new Error( "AUTH_PREFFERRED must be specified if AUTH_PUBLIC_KEY and AUTH_REALM_URL is provided.", ); @@ -26,7 +24,7 @@ const jwtVerify = createVerifier({ const jwtDecode = createDecoder(); export async function expressAuthentication( - request: express.Request, + request: RequestWithUser, securityName: string, _scopes?: string[], ) { @@ -56,6 +54,18 @@ export async function expressAuthentication( if (process.env.AUTH_PUBLIC_KEY) payload = await verifyOffline(token); break; } + if (!request.app.locals.logData) { + request.app.locals.logData = {}; + } + + // addLogSequence(request, { + // action: "database", + // status: "success", + // description: "Query Data.", + // }); + request.app.locals.logData.userId = payload.sub; + request.app.locals.logData.userName = payload.name; + request.app.locals.logData.user = payload.preferred_username; return payload; } diff --git a/src/middlewares/error.ts b/src/middlewares/error.ts index b010f0a..f8d0b56 100644 --- a/src/middlewares/error.ts +++ b/src/middlewares/error.ts @@ -4,6 +4,12 @@ import HttpStatus from "../interfaces/http-status"; import { ValidateError } from "tsoa"; function error(error: Error, _req: Request, res: Response, _next: NextFunction) { + const logData = _req.app.locals.logData.sequence?.at(-1); + if (logData) { + logData.status = "error"; + logData.description = error.message; + } + if (error instanceof HttpError) { return res.status(error.status).json({ status: error.status, diff --git a/src/middlewares/logs.ts b/src/middlewares/logs.ts new file mode 100644 index 0000000..cd4cdfa --- /dev/null +++ b/src/middlewares/logs.ts @@ -0,0 +1,74 @@ +import { NextFunction, Request, Response } from "express"; +import { Client } from "@elastic/elasticsearch"; + +if (!process.env.ELASTICSEARCH_INDEX) { + throw new Error("Require ELASTICSEARCH_INDEX to store log."); +} + +const ELASTICSEARCH_INDEX = process.env.ELASTICSEARCH_INDEX; + +const LOG_LEVEL_MAP: Record = { + debug: 4, + info: 3, + warning: 2, + error: 1, + none: 0, +}; + +const elasticsearch = new Client({ + node: `${process.env.ELASTICSEARCH_PROTOCOL}://${process.env.ELASTICSEARCH_HOST}:${process.env.ELASTICSEARCH_PORT}`, +}); + +async function logMiddleware(req: Request, res: Response, next: NextFunction) { + if (!req.url.startsWith("/api/")) return next(); + + let data: any; + + const originalJson = res.json; + + res.json = function (v: any) { + data = v; + return originalJson.call(this, v); + }; + + const timestamp = new Date().toISOString(); + const start = performance.now(); + + req.app.locals.logData = {}; + + res.on("finish", () => { + if (!req.url.startsWith("/api/")) return; + + const level = LOG_LEVEL_MAP[process.env.LOG_LEVEL ?? "debug"] || 4; + + if (level === 1 && res.statusCode < 500) return; + if (level === 2 && res.statusCode < 400) return; + if (level === 3 && res.statusCode < 200) return; + + const obj = { + logType: res.statusCode >= 500 ? "error" : res.statusCode >= 400 ? "warning" : "info", + ip: req.ip, + systemName: "KPI", + startTimeStamp: timestamp, + endTimeStamp: new Date().toISOString(), + processTime: performance.now() - start, + host: req.hostname, + method: req.method, + endpoint: req.url, + responseCode: String(res.statusCode === 304 ? 200 : res.statusCode), + responseDescription: data?.message, + input: (level === 4 && JSON.stringify(req.body, null, 2)) || undefined, + output: (level === 4 && JSON.stringify(data, null, 2)) || undefined, + ...req.app.locals.logData, + }; + + elasticsearch.index({ + index: ELASTICSEARCH_INDEX, + document: obj, + }); + }); + + return next(); +} + +export default logMiddleware;