From 0e1d5f0bf8916f1e127798c635a6ce9b3336e60a Mon Sep 17 00:00:00 2001 From: Methapon2001 <61303214+Methapon2001@users.noreply.github.com> Date: Mon, 11 Mar 2024 10:49:02 +0700 Subject: [PATCH 01/12] refactor(utils): merge 2 statement of same conditions --- src/interfaces/utils.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/interfaces/utils.ts b/src/interfaces/utils.ts index ef23c9b1..d9edd9d9 100644 --- a/src/interfaces/utils.ts +++ b/src/interfaces/utils.ts @@ -5,8 +5,10 @@ export function calculateAge(start: Date, end = new Date()) { let month = end.getMonth() - start.getMonth(); let day = end.getDate() - start.getDate(); - if (month < 0) year -= 1; - if (month < 0) month += 12; + if (month < 0) { + month += 12; + year -= 1; + } if (day < 0) { month -= 1; day = From f47601a356fa5a3ceafb65aa05211055ccf6a8ab Mon Sep 17 00:00:00 2001 From: Methapon2001 <61303214+Methapon2001@users.noreply.github.com> Date: Mon, 11 Mar 2024 12:04:25 +0700 Subject: [PATCH 02/12] refactor(middlewares): add type to function parameter auth role --- src/middlewares/role.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/middlewares/role.ts b/src/middlewares/role.ts index fef95919..681dc99b 100644 --- a/src/middlewares/role.ts +++ b/src/middlewares/role.ts @@ -5,7 +5,7 @@ import { RequestWithUser } from "./user"; export function authRole( role: string | string[], - errorMessage = "คุณไม่มีสิทธิในการเข้าถึงทรัพยากรดังกล่าว", + errorMessage: string = "คุณไม่มีสิทธิในการเข้าถึงทรัพยากรดังกล่าว", ) { return (req: RequestWithUser, _res: express.Response, next: express.NextFunction) => { if ((Array.isArray(role) && role.includes("*")) || role === "*") return next(); From 339ee19c3d763ec04a4f4fdb7136641970f8fc3b Mon Sep 17 00:00:00 2001 From: Methapon2001 <61303214+Methapon2001@users.noreply.github.com> Date: Tue, 12 Mar 2024 10:18:08 +0700 Subject: [PATCH 03/12] chore(tsoa-setting): update to recursive path --- tsoa.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsoa.json b/tsoa.json index 588162ec..87fa35f9 100644 --- a/tsoa.json +++ b/tsoa.json @@ -1,7 +1,7 @@ { "entryFile": "src/app.ts", "noImplicitAdditionalProperties": "throw-on-extras", - "controllerPathGlobs": ["src/controllers/*Controller.ts"], + "controllerPathGlobs": ["src/controllers/**/*Controller.ts"], "spec": { "outputDirectory": "src", "specVersion": 3, From 86e4208310ae33f97eff04debcef2d213b8b046a Mon Sep 17 00:00:00 2001 From: Methapon2001 <61303214+Methapon2001@users.noreply.github.com> Date: Tue, 12 Mar 2024 16:48:15 +0700 Subject: [PATCH 04/12] feat: profile certificate endpoints --- .../ProfileCertificateController.ts | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 src/controllers/ProfileCertificateController.ts diff --git a/src/controllers/ProfileCertificateController.ts b/src/controllers/ProfileCertificateController.ts new file mode 100644 index 00000000..b4e17a21 --- /dev/null +++ b/src/controllers/ProfileCertificateController.ts @@ -0,0 +1,116 @@ +import { + Body, + Controller, + Delete, + Get, + Patch, + Path, + Post, + Request, + Route, + Security, + Tags, +} from "tsoa"; +import { AppDataSource } from "../database/data-source"; +import { + CreateProfileCertificate, + ProfileCertificate, + UpdateProfileCertificate, +} from "../entities/ProfileCertificate"; +import HttpSuccess from "../interfaces/http-success"; +import HttpStatus from "../interfaces/http-status"; +import HttpError from "../interfaces/http-error"; +import { ProfileCertificateHistory } from "../entities/ProfileCertificateHistory"; +import { RequestWithUser } from "../middlewares/user"; + +@Route("api/v1/org/profile/certificate") +@Tags("ProfileCertificate") +@Security("bearerAuth") +export class ProfileCertificateController extends Controller { + private certificateRepo = AppDataSource.getRepository(ProfileCertificate); + private certificateHistoryRepo = AppDataSource.getRepository(ProfileCertificateHistory); + + @Get("{profileId}") + public async getCertificate(@Path() profileId: string) { + const record = await this.certificateRepo.findBy({ profileId }); + return new HttpSuccess(record); + } + + @Get("history/{certificateId}") + public async certificateHistory(@Path() certificateId: string) { + const record = await this.certificateHistoryRepo.findBy({ + profileCertificateId: certificateId, + }); + return record; + } + + @Post() + public async newCertificate( + @Request() req: RequestWithUser, + @Body() body: CreateProfileCertificate, + ) { + const data = new ProfileCertificate(); + const history = new ProfileCertificateHistory(); + + const meta = { + createdUserId: req.user.sub, + createdFullName: req.user.name, + lastUpdateUserId: req.user.sub, + lastUpdateFullName: req.user.name, + }; + + Object.assign(data, { ...body, ...meta }); + Object.assign(history, { ...body, ...meta }); + + const result = await this.certificateRepo.save(data); + + history.profileCertificateId = result.id; + + await this.certificateHistoryRepo.save(history); + + return new HttpSuccess(); + } + + @Patch("{certificateId}") + public async editCertificate( + @Request() req: RequestWithUser, + @Body() body: UpdateProfileCertificate, + @Path() certificateId: string, + ) { + const record = await this.certificateRepo.findOneBy({ id: certificateId }); + + if (!record) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + + const history = new ProfileCertificateHistory(); + + Object.assign(record, body); + Object.assign(history, { ...body, id: undefined }); + history.profileCertificateId = certificateId; + record.lastUpdateFullName = req.user.name; + history.lastUpdateFullName = req.user.name; + + await Promise.all([ + this.certificateRepo.save(record), + this.certificateHistoryRepo.save(history), + ]); + + return new HttpSuccess(); + } + + @Delete("{certificateId}") + public async deleteCertificate(@Path() certificateId: string) { + await this.certificateHistoryRepo.delete({ + profileCertificateId: certificateId, + }); + + const certificateResult = await this.certificateRepo.delete({ + id: certificateId, + }); + + if (certificateResult.affected && certificateResult.affected <= 0) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + + return new HttpSuccess(); + } +} From 0e81e22ae3631ccd3a65b9f438c965d31c0b2814 Mon Sep 17 00:00:00 2001 From: Methapon2001 <61303214+Methapon2001@users.noreply.github.com> Date: Tue, 12 Mar 2024 16:48:33 +0700 Subject: [PATCH 05/12] feat: profile honor endpoints --- src/controllers/ProfileHonorController.ts | 104 ++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 src/controllers/ProfileHonorController.ts diff --git a/src/controllers/ProfileHonorController.ts b/src/controllers/ProfileHonorController.ts new file mode 100644 index 00000000..f5e34158 --- /dev/null +++ b/src/controllers/ProfileHonorController.ts @@ -0,0 +1,104 @@ +import { + Body, + Controller, + Delete, + Get, + Patch, + Path, + Post, + Request, + Route, + Security, + Tags, +} from "tsoa"; +import { AppDataSource } from "../database/data-source"; +import { CreateProfileHonor, ProfileHonor, UpdateProfileHonor } from "../entities/ProfileHonor"; +import HttpSuccess from "../interfaces/http-success"; +import HttpStatus from "../interfaces/http-status"; +import HttpError from "../interfaces/http-error"; +import { ProfileHonorHistory } from "../entities/ProfileHonorHistory"; +import { RequestWithUser } from "../middlewares/user"; + +@Route("api/v1/org/profile/honor") +@Tags("ProfileHonor") +@Security("bearerAuth") +export class ProfileHonorController extends Controller { + private honorRepo = AppDataSource.getRepository(ProfileHonor); + private honorHistoryRepo = AppDataSource.getRepository(ProfileHonorHistory); + + @Get("{profileId}") + public async getHonor(@Path() profileId: string) { + const record = await this.honorRepo.findBy({ profileId }); + return new HttpSuccess(record); + } + + @Get("history/{honorId}") + public async honorHistory(@Path() honorId: string) { + const record = await this.honorHistoryRepo.findBy({ + profileHonorId: honorId, + }); + return record; + } + + @Post() + public async newHonor(@Request() req: RequestWithUser, @Body() body: CreateProfileHonor) { + const data = new ProfileHonor(); + const history = new ProfileHonorHistory(); + + const meta = { + createdUserId: req.user.sub, + createdFullName: req.user.name, + lastUpdateUserId: req.user.sub, + lastUpdateFullName: req.user.name, + }; + + Object.assign(data, { ...body, ...meta }); + Object.assign(history, { ...body, ...meta }); + + const result = await this.honorRepo.save(data); + + history.profileHonorId = result.id; + + await this.honorHistoryRepo.save(history); + + return new HttpSuccess(); + } + + @Patch("{honorId}") + public async editHonor( + @Request() req: RequestWithUser, + @Body() body: UpdateProfileHonor, + @Path() honorId: string, + ) { + const record = await this.honorRepo.findOneBy({ id: honorId }); + + if (!record) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + + const history = new ProfileHonorHistory(); + + Object.assign(record, body); + Object.assign(history, { ...body, id: undefined }); + history.profileHonorId = honorId; + record.lastUpdateFullName = req.user.name; + history.lastUpdateFullName = req.user.name; + + await Promise.all([this.honorRepo.save(record), this.honorHistoryRepo.save(history)]); + + return new HttpSuccess(); + } + + @Delete("{honorId}") + public async deleteTraning(@Path() honorId: string) { + await this.honorHistoryRepo.delete({ + profileHonorId: honorId, + }); + + const result = await this.honorRepo.delete({ id: honorId }); + + if (result.affected && result.affected <= 0) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + + return new HttpSuccess(); + } +} From 8ac8339a6baa96631817b894d69338c1fbe6fa58 Mon Sep 17 00:00:00 2001 From: Methapon2001 <61303214+Methapon2001@users.noreply.github.com> Date: Tue, 12 Mar 2024 16:48:44 +0700 Subject: [PATCH 06/12] feat: profile insignia endpoints --- src/controllers/ProfileInsigniaController.ts | 108 +++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 src/controllers/ProfileInsigniaController.ts diff --git a/src/controllers/ProfileInsigniaController.ts b/src/controllers/ProfileInsigniaController.ts new file mode 100644 index 00000000..a24c6730 --- /dev/null +++ b/src/controllers/ProfileInsigniaController.ts @@ -0,0 +1,108 @@ +import { + Body, + Controller, + Delete, + Get, + Patch, + Path, + Post, + Request, + Route, + Security, + Tags, +} from "tsoa"; +import { AppDataSource } from "../database/data-source"; +import { + CreateProfileInsignia, + ProfileInsignia, + UpdateProfileInsignia, +} from "../entities/ProfileInsignia"; +import HttpSuccess from "../interfaces/http-success"; +import HttpStatus from "../interfaces/http-status"; +import HttpError from "../interfaces/http-error"; +import { ProfileInsigniaHistory } from "../entities/ProfileInsigniaHistory"; +import { RequestWithUser } from "../middlewares/user"; + +@Route("api/v1/org/profile/insignia") +@Tags("ProfileInsignia") +@Security("bearerAuth") +export class ProfileInsigniaController extends Controller { + private insigniaRepo = AppDataSource.getRepository(ProfileInsignia); + private insigniaHistoryRepo = AppDataSource.getRepository(ProfileInsigniaHistory); + + @Get("{profileId}") + public async getInsignia(@Path() profileId: string) { + const record = await this.insigniaRepo.findBy({ profileId }); + return new HttpSuccess(record); + } + + @Get("history/{InsigniaId}") + public async getInsigniaHistory(@Path() InsigniaId: string) { + const record = await this.insigniaHistoryRepo.findBy({ + profileInsigniaId: InsigniaId, + }); + return record; + } + + @Post() + public async newInsignia(@Request() req: RequestWithUser, @Body() body: CreateProfileInsignia) { + const data = new ProfileInsignia(); + const history = new ProfileInsigniaHistory(); + + const meta = { + createdUserId: req.user.sub, + createdFullName: req.user.name, + lastUpdateUserId: req.user.sub, + lastUpdateFullName: req.user.name, + }; + + Object.assign(data, { ...body, ...meta }); + Object.assign(history, { ...body, ...meta }); + + const result = await this.insigniaRepo.save(data); + + history.profileInsigniaId = result.id; + + await this.insigniaHistoryRepo.save(data); + + return new HttpSuccess(); + } + + @Patch("{insigniaId}") + public async editInsignia( + @Request() req: RequestWithUser, + @Body() body: UpdateProfileInsignia, + @Path() insigniaId: string, + ) { + const record = await this.insigniaRepo.findOneBy({ id: insigniaId }); + + if (!record) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + + const history = new ProfileInsigniaHistory(); + + Object.assign(record, body); + Object.assign(history, { ...body, id: undefined }); + history.profileInsigniaId = insigniaId; + record.lastUpdateFullName = req.user.name; + history.lastUpdateFullName = req.user.name; + + await Promise.all([this.insigniaRepo.save(record), this.insigniaHistoryRepo.save(history)]); + + return new HttpSuccess(); + } + + @Delete("{insigniaId}") + public async deleteInsignia(@Path() insigniaId: string) { + await this.insigniaHistoryRepo.delete({ + profileInsigniaId: insigniaId, + }); + + const result = await this.insigniaRepo.delete({ id: insigniaId }); + + if (result.affected && result.affected <= 0) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + + return new HttpSuccess(); + } +} From 294411a1147c07f880175c2293309cf04ee5f0c5 Mon Sep 17 00:00:00 2001 From: Methapon2001 <61303214+Methapon2001@users.noreply.github.com> Date: Tue, 12 Mar 2024 16:48:54 +0700 Subject: [PATCH 07/12] feat: profile training endpoints --- src/controllers/ProfileTrainingController.ts | 108 +++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 src/controllers/ProfileTrainingController.ts diff --git a/src/controllers/ProfileTrainingController.ts b/src/controllers/ProfileTrainingController.ts new file mode 100644 index 00000000..e5a02183 --- /dev/null +++ b/src/controllers/ProfileTrainingController.ts @@ -0,0 +1,108 @@ +import { + Body, + Controller, + Delete, + Get, + Patch, + Path, + Post, + Request, + Route, + Security, + Tags, +} from "tsoa"; +import { AppDataSource } from "../database/data-source"; +import { + CreateProfileTraining, + ProfileTraining, + UpdateProfileTraining, +} from "../entities/ProfileTraining"; +import HttpSuccess from "../interfaces/http-success"; +import HttpStatus from "../interfaces/http-status"; +import HttpError from "../interfaces/http-error"; +import { ProfileTrainingHistory } from "../entities/ProfileTrainingHistory"; +import { RequestWithUser } from "../middlewares/user"; + +@Route("api/v1/org/profile/training") +@Tags("ProfileTraining") +@Security("bearerAuth") +export class ProfileTrainingController extends Controller { + private trainingRepo = AppDataSource.getRepository(ProfileTraining); + private trainingHistoryRepo = AppDataSource.getRepository(ProfileTrainingHistory); + + @Get("{profileId}") + public async getTraining(@Path() profileId: string) { + const record = await this.trainingRepo.findBy({ profileId }); + return new HttpSuccess(record); + } + + @Get("history/{trainingId}") + public async trainingHistory(@Path() trainingId: string) { + const record = await this.trainingHistoryRepo.findBy({ + profileTrainingId: trainingId, + }); + return record; + } + + @Post() + public async newTraining(@Request() req: RequestWithUser, @Body() body: CreateProfileTraining) { + const data = new ProfileTraining(); + const history = new ProfileTrainingHistory(); + + const meta = { + createdUserId: req.user.sub, + createdFullName: req.user.name, + lastUpdateUserId: req.user.sub, + lastUpdateFullName: req.user.name, + }; + + Object.assign(data, { ...body, ...meta }); + Object.assign(history, { ...body, ...meta }); + + const result = await this.trainingRepo.save(data); + + history.profileTrainingId = result.id; + + await this.trainingHistoryRepo.save(history); + + return new HttpSuccess(); + } + + @Patch("{trainingId}") + public async editTraining( + @Request() req: RequestWithUser, + @Body() body: UpdateProfileTraining, + @Path() trainingId: string, + ) { + const record = await this.trainingRepo.findOneBy({ id: trainingId }); + + if (!record) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + + const history = new ProfileTrainingHistory(); + + Object.assign(record, body); + Object.assign(history, { ...body, id: undefined }); + history.profileTrainingId = trainingId; + record.lastUpdateFullName = req.user.name; + history.lastUpdateFullName = req.user.name; + + await Promise.all([this.trainingRepo.save(record), this.trainingHistoryRepo.save(history)]); + + return new HttpSuccess(); + } + + @Delete("{trainingId}") + public async deleteTraining(@Path() trainingId: string) { + await this.trainingHistoryRepo.delete({ + profileTrainingId: trainingId, + }); + + const result = await this.trainingRepo.delete({ id: trainingId }); + + if (result.affected && result.affected <= 0) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + + return new HttpSuccess(); + } +} From 2f9314bc9c5d3ebe69fab268d5952f220274c326 Mon Sep 17 00:00:00 2001 From: Methapon2001 <61303214+Methapon2001@users.noreply.github.com> Date: Tue, 12 Mar 2024 16:49:07 +0700 Subject: [PATCH 08/12] fix: missing id --- src/middlewares/user.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/middlewares/user.ts b/src/middlewares/user.ts index 12c5d597..a35cdc4a 100644 --- a/src/middlewares/user.ts +++ b/src/middlewares/user.ts @@ -2,6 +2,7 @@ import type { Request } from "express"; export type RequestWithUser = Request & { user: { + sub: string; name: string; given_name: string; familiy_name: string; From 03ce83b89896b0f28bad194f595dee6dc440e40b Mon Sep 17 00:00:00 2001 From: Methapon2001 <61303214+Methapon2001@users.noreply.github.com> Date: Tue, 12 Mar 2024 17:01:02 +0700 Subject: [PATCH 09/12] fix: history response --- src/controllers/ProfileCertificateController.ts | 2 +- src/controllers/ProfileHonorController.ts | 2 +- src/controllers/ProfileInsigniaController.ts | 2 +- src/controllers/ProfileTrainingController.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/controllers/ProfileCertificateController.ts b/src/controllers/ProfileCertificateController.ts index b4e17a21..b7cc239a 100644 --- a/src/controllers/ProfileCertificateController.ts +++ b/src/controllers/ProfileCertificateController.ts @@ -41,7 +41,7 @@ export class ProfileCertificateController extends Controller { const record = await this.certificateHistoryRepo.findBy({ profileCertificateId: certificateId, }); - return record; + return new HttpSuccess(record); } @Post() diff --git a/src/controllers/ProfileHonorController.ts b/src/controllers/ProfileHonorController.ts index f5e34158..818383e2 100644 --- a/src/controllers/ProfileHonorController.ts +++ b/src/controllers/ProfileHonorController.ts @@ -37,7 +37,7 @@ export class ProfileHonorController extends Controller { const record = await this.honorHistoryRepo.findBy({ profileHonorId: honorId, }); - return record; + return new HttpSuccess(record); } @Post() diff --git a/src/controllers/ProfileInsigniaController.ts b/src/controllers/ProfileInsigniaController.ts index a24c6730..b3316fb9 100644 --- a/src/controllers/ProfileInsigniaController.ts +++ b/src/controllers/ProfileInsigniaController.ts @@ -41,7 +41,7 @@ export class ProfileInsigniaController extends Controller { const record = await this.insigniaHistoryRepo.findBy({ profileInsigniaId: InsigniaId, }); - return record; + return new HttpSuccess(record); } @Post() diff --git a/src/controllers/ProfileTrainingController.ts b/src/controllers/ProfileTrainingController.ts index e5a02183..f3b53608 100644 --- a/src/controllers/ProfileTrainingController.ts +++ b/src/controllers/ProfileTrainingController.ts @@ -41,7 +41,7 @@ export class ProfileTrainingController extends Controller { const record = await this.trainingHistoryRepo.findBy({ profileTrainingId: trainingId, }); - return record; + return new HttpSuccess(record); } @Post() From 9c79a1104769e9e16d814b535fce4139613bc761 Mon Sep 17 00:00:00 2001 From: Methapon2001 <61303214+Methapon2001@users.noreply.github.com> Date: Tue, 12 Mar 2024 17:07:54 +0700 Subject: [PATCH 10/12] fix: wrong database save --- src/controllers/ProfileInsigniaController.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/controllers/ProfileInsigniaController.ts b/src/controllers/ProfileInsigniaController.ts index b3316fb9..864e26d0 100644 --- a/src/controllers/ProfileInsigniaController.ts +++ b/src/controllers/ProfileInsigniaController.ts @@ -63,7 +63,7 @@ export class ProfileInsigniaController extends Controller { history.profileInsigniaId = result.id; - await this.insigniaHistoryRepo.save(data); + await this.insigniaHistoryRepo.save(history); return new HttpSuccess(); } From 96b53a4ca550fbee19a049bdf0d5a1c7ef6daa47 Mon Sep 17 00:00:00 2001 From: Methapon2001 <61303214+Methapon2001@users.noreply.github.com> Date: Tue, 12 Mar 2024 17:11:42 +0700 Subject: [PATCH 11/12] chore: add response example --- .../ProfileCertificateController.ts | 61 +++++++++++++ src/controllers/ProfileHonorController.ts | 62 ++++++++++++++ src/controllers/ProfileInsigniaController.ts | 85 +++++++++++++++++++ src/controllers/ProfileTrainingController.ts | 77 +++++++++++++++++ 4 files changed, 285 insertions(+) diff --git a/src/controllers/ProfileCertificateController.ts b/src/controllers/ProfileCertificateController.ts index b7cc239a..d859491c 100644 --- a/src/controllers/ProfileCertificateController.ts +++ b/src/controllers/ProfileCertificateController.ts @@ -2,6 +2,7 @@ import { Body, Controller, Delete, + Example, Get, Patch, Path, @@ -31,12 +32,72 @@ export class ProfileCertificateController extends Controller { private certificateHistoryRepo = AppDataSource.getRepository(ProfileCertificateHistory); @Get("{profileId}") + @Example({ + status: 200, + message: "สำเร็จ", + result: [ + { + id: "e1ef9c3d-079a-40d8-8332-664c3e9a5a70", + createdAt: "2024-03-12T03:02:27.532Z", + createdUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", + lastUpdatedAt: "2024-03-12T03:02:27.532Z", + lastUpdateUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", + createdFullName: "สาวิตรี ศรีสมัย", + lastUpdateFullName: "สาวิตรี ศรีสมัย", + profileId: "1526d9d3-d8b1-43ab-81b5-a84dfbe99201", + expireDate: "2024-03-12T10:01:48.000Z", + isActive: true, + issueDate: "2024-03-12T10:01:48.000Z", + certificateNo: "string", + certificateType: "string", + issuer: "string", + }, + ], + }) public async getCertificate(@Path() profileId: string) { const record = await this.certificateRepo.findBy({ profileId }); return new HttpSuccess(record); } @Get("history/{certificateId}") + @Example({ + status: 200, + message: "สำเร็จ", + result: [ + { + id: "c0ecf986-b290-44ca-b45e-f4448cdd34dd", + createdAt: "2024-03-12T03:03:30.169Z", + createdUserId: "00000000-0000-0000-0000-000000000000", + lastUpdatedAt: "2024-03-12T03:03:30.169Z", + lastUpdateUserId: "00000000-0000-0000-0000-000000000000", + createdFullName: "string", + lastUpdateFullName: "สาวิตรี ศรีสมัย", + expireDate: "2024-03-12T10:03:05.000Z", + isActive: true, + issueDate: "2024-03-12T10:03:05.000Z", + certificateNo: "no", + certificateType: "type", + issuer: "issuer", + profileCertificateId: "e1ef9c3d-079a-40d8-8332-664c3e9a5a70", + }, + { + id: "dc4c2800-5fc5-4ec3-b19a-c4a27beac35f", + createdAt: "2024-03-12T03:02:27.583Z", + createdUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", + lastUpdatedAt: "2024-03-12T03:02:27.583Z", + lastUpdateUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", + createdFullName: "สาวิตรี ศรีสมัย", + lastUpdateFullName: "สาวิตรี ศรีสมัย", + expireDate: "2024-03-12T10:01:48.000Z", + isActive: true, + issueDate: "2024-03-12T10:01:48.000Z", + certificateNo: "string", + certificateType: "string", + issuer: "string", + profileCertificateId: "e1ef9c3d-079a-40d8-8332-664c3e9a5a70", + }, + ], + }) public async certificateHistory(@Path() certificateId: string) { const record = await this.certificateHistoryRepo.findBy({ profileCertificateId: certificateId, diff --git a/src/controllers/ProfileHonorController.ts b/src/controllers/ProfileHonorController.ts index 818383e2..b0cf23a6 100644 --- a/src/controllers/ProfileHonorController.ts +++ b/src/controllers/ProfileHonorController.ts @@ -2,6 +2,7 @@ import { Body, Controller, Delete, + Example, Get, Patch, Path, @@ -27,12 +28,73 @@ export class ProfileHonorController extends Controller { private honorHistoryRepo = AppDataSource.getRepository(ProfileHonorHistory); @Get("{profileId}") + @Example({ + status: 200, + message: "สำเร็จ", + result: [ + { + id: "debfa8a7-83fb-4801-a940-8ae74e7638d3", + createdAt: "2024-03-12T03:10:05.594Z", + createdUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", + lastUpdatedAt: "2024-03-12T03:10:05.594Z", + lastUpdateUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", + createdFullName: "สาวิตรี ศรีสมัย", + lastUpdateFullName: "สาวิตรี ศรีสมัย", + profileId: "1526d9d3-d8b1-43ab-81b5-a84dfbe99201", + isActive: true, + detail: "string", + issueDate: "2024-03-12T10:09:47.000Z", + issuer: "string", + refCommandDate: "2024-03-12T10:09:47.000Z", + refCommandNo: "string", + isDate: true, + }, + ], + }) public async getHonor(@Path() profileId: string) { const record = await this.honorRepo.findBy({ profileId }); return new HttpSuccess(record); } @Get("history/{honorId}") + @Example({ + status: 200, + message: "สำเร็จ", + result: [ + { + id: "3bedb365-4a41-4df5-8f47-b6e143221d2c", + createdAt: "2024-03-12T03:11:01.395Z", + createdUserId: "00000000-0000-0000-0000-000000000000", + lastUpdatedAt: "2024-03-12T03:11:01.395Z", + lastUpdateUserId: "00000000-0000-0000-0000-000000000000", + createdFullName: "string", + lastUpdateFullName: "สาวิตรี ศรีสมัย", + isActive: true, + detail: "detail", + issueDate: "2024-03-12T10:10:31.000Z", + issuer: "issuer", + refCommandDate: "2024-03-12T10:10:31.000Z", + refCommandNo: "refCommandNo", + profileHonorId: "debfa8a7-83fb-4801-a940-8ae74e7638d3", + }, + { + id: "ba0e2f82-014e-46c6-8b82-a7c28eb5325f", + createdAt: "2024-03-12T03:10:05.657Z", + createdUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", + lastUpdatedAt: "2024-03-12T03:10:05.657Z", + lastUpdateUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", + createdFullName: "สาวิตรี ศรีสมัย", + lastUpdateFullName: "สาวิตรี ศรีสมัย", + isActive: true, + detail: "string", + issueDate: "2024-03-12T10:09:47.000Z", + issuer: "string", + refCommandDate: "2024-03-12T10:09:47.000Z", + refCommandNo: "string", + profileHonorId: "debfa8a7-83fb-4801-a940-8ae74e7638d3", + }, + ], + }) public async honorHistory(@Path() honorId: string) { const record = await this.honorHistoryRepo.findBy({ profileHonorId: honorId, diff --git a/src/controllers/ProfileInsigniaController.ts b/src/controllers/ProfileInsigniaController.ts index 864e26d0..5e659265 100644 --- a/src/controllers/ProfileInsigniaController.ts +++ b/src/controllers/ProfileInsigniaController.ts @@ -2,6 +2,7 @@ import { Body, Controller, Delete, + Example, Get, Patch, Path, @@ -31,12 +32,96 @@ export class ProfileInsigniaController extends Controller { private insigniaHistoryRepo = AppDataSource.getRepository(ProfileInsigniaHistory); @Get("{profileId}") + @Example({ + status: 200, + message: "สำเร็จ", + result: [ + { + id: "c9d4dd52-25f5-491a-852d-28bfe00d66cb", + createdAt: "2024-03-12T03:05:09.393Z", + createdUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", + lastUpdatedAt: "2024-03-12T03:05:09.393Z", + lastUpdateUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", + createdFullName: "สาวิตรี ศรีสมัย", + lastUpdateFullName: "สาวิตรี ศรีสมัย", + profileId: "1526d9d3-d8b1-43ab-81b5-a84dfbe99201", + isActive: true, + year: 0, + no: "string", + volume: "string", + section: "string", + page: "string", + receiveDate: "2024-03-12T10:05:02.000Z", + insigniaId: "string", + insigniaType: "string", + dateAnnounce: "2024-03-12T10:05:02.000Z", + issue: "string", + volumeNo: "string", + refCommandDate: "2024-03-12T10:05:02.000Z", + refCommandNo: "string", + }, + ], + }) public async getInsignia(@Path() profileId: string) { const record = await this.insigniaRepo.findBy({ profileId }); return new HttpSuccess(record); } @Get("history/{InsigniaId}") + @Example({ + status: 200, + message: "สำเร็จ", + result: [ + { + id: "c363d13c-88bd-4954-adf5-70d3f5ca9c30", + createdAt: "2024-03-12T03:06:31.062Z", + createdUserId: "00000000-0000-0000-0000-000000000000", + lastUpdatedAt: "2024-03-12T03:06:31.062Z", + lastUpdateUserId: "00000000-0000-0000-0000-000000000000", + createdFullName: "string", + lastUpdateFullName: "สาวิตรี ศรีสมัย", + isActive: true, + year: 0, + no: "no", + volume: "volume", + section: "section", + page: "page", + receiveDate: "2024-03-12T10:05:44.000Z", + insigniaId: "insigniaId", + insigniaType: "insigniaType", + dateAnnounce: "2024-03-12T10:05:44.000Z", + issue: "string", + volumeNo: "volumeNo", + refCommandDate: "2024-03-12T10:05:44.000Z", + refCommandNo: "refCommandNo", + profileInsigniaId: "c9d4dd52-25f5-491a-852d-28bfe00d66cb", + }, + { + id: "c9d4dd52-25f5-491a-852d-28bfe00d66cb", + createdAt: "2024-03-12T03:05:09.393Z", + createdUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", + lastUpdatedAt: "2024-03-12T03:09:04.905Z", + lastUpdateUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", + createdFullName: "สาวิตรี ศรีสมัย", + lastUpdateFullName: "สาวิตรี ศรีสมัย", + isActive: true, + year: 0, + no: "string", + volume: "string", + section: "string", + page: "string", + receiveDate: "2024-03-12T10:05:02.000Z", + insigniaId: "string", + insigniaType: "string", + dateAnnounce: "2024-03-12T10:05:02.000Z", + issue: "string", + volumeNo: "string", + refCommandDate: "2024-03-12T10:05:02.000Z", + refCommandNo: "string", + profileInsigniaId: "c9d4dd52-25f5-491a-852d-28bfe00d66cb", + }, + ], + }) public async getInsigniaHistory(@Path() InsigniaId: string) { const record = await this.insigniaHistoryRepo.findBy({ profileInsigniaId: InsigniaId, diff --git a/src/controllers/ProfileTrainingController.ts b/src/controllers/ProfileTrainingController.ts index f3b53608..a2c6f457 100644 --- a/src/controllers/ProfileTrainingController.ts +++ b/src/controllers/ProfileTrainingController.ts @@ -2,6 +2,7 @@ import { Body, Controller, Delete, + Example, Get, Patch, Path, @@ -31,12 +32,88 @@ export class ProfileTrainingController extends Controller { private trainingHistoryRepo = AppDataSource.getRepository(ProfileTrainingHistory); @Get("{profileId}") + @Example({ + status: 200, + message: "สำเร็จ", + result: [ + { + id: "3cf02fb7-2f0c-471b-b641-51d557375c0a", + createdAt: "2024-03-12T02:55:56.915Z", + createdUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", + lastUpdatedAt: "2024-03-12T02:55:56.915Z", + lastUpdateUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", + createdFullName: "สาวิตรี ศรีสมัย", + lastUpdateFullName: "สาวิตรี ศรีสมัย", + profileId: "1526d9d3-d8b1-43ab-81b5-a84dfbe99201", + isActive: true, + startDate: "2024-03-12T09:55:23.000Z", + endDate: "2024-03-12T09:55:23.000Z", + numberOrder: "string", + topic: "string", + place: "string", + dateOrder: "2024-03-12T09:55:23.000Z", + department: "string", + duration: "string", + name: "string", + yearly: 0, + isDate: true, + }, + ], + }) public async getTraining(@Path() profileId: string) { const record = await this.trainingRepo.findBy({ profileId }); return new HttpSuccess(record); } @Get("history/{trainingId}") + @Example({ + status: 200, + message: "สำเร็จ", + result: [ + { + id: "6d4e9dbe-8697-4546-9651-0a1c3ea0a82d", + createdAt: "2024-03-12T02:55:56.971Z", + createdUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", + lastUpdatedAt: "2024-03-12T02:55:56.971Z", + lastUpdateUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", + createdFullName: "สาวิตรี ศรีสมัย", + lastUpdateFullName: "สาวิตรี ศรีสมัย", + isActive: true, + startDate: "2024-03-12T09:55:23.000Z", + endDate: "2024-03-12T09:55:23.000Z", + numberOrder: "string", + topic: "string", + place: "string", + dateOrder: "2024-03-12T09:55:23.000Z", + department: "string", + duration: "string", + name: "string", + yearly: 0, + profileTrainingId: "3cf02fb7-2f0c-471b-b641-51d557375c0a", + }, + { + id: "a251c176-3dac-4d09-9813-38c8db1127e3", + createdAt: "2024-03-12T02:58:17.917Z", + createdUserId: "00000000-0000-0000-0000-000000000000", + lastUpdatedAt: "2024-03-12T02:58:17.917Z", + lastUpdateUserId: "00000000-0000-0000-0000-000000000000", + createdFullName: "string", + lastUpdateFullName: "สาวิตรี ศรีสมัย", + isActive: true, + startDate: "2024-03-12T09:57:44.000Z", + endDate: "2024-03-12T09:57:44.000Z", + numberOrder: "string", + topic: "topic", + place: "place", + dateOrder: "2024-03-12T09:57:44.000Z", + department: "department", + duration: "string", + name: "name", + yearly: 0, + profileTrainingId: "3cf02fb7-2f0c-471b-b641-51d557375c0a", + }, + ], + }) public async trainingHistory(@Path() trainingId: string) { const record = await this.trainingHistoryRepo.findBy({ profileTrainingId: trainingId, From 6e7086c0857dfec98e24ed274a8ed346a18f01d3 Mon Sep 17 00:00:00 2001 From: Methapon2001 <61303214+Methapon2001@users.noreply.github.com> Date: Tue, 12 Mar 2024 17:17:16 +0700 Subject: [PATCH 12/12] feat: check if profile exists --- src/controllers/ProfileCertificateController.ts | 12 ++++++++++++ src/controllers/ProfileHonorController.ts | 12 ++++++++++++ src/controllers/ProfileInsigniaController.ts | 12 ++++++++++++ src/controllers/ProfileTrainingController.ts | 12 ++++++++++++ 4 files changed, 48 insertions(+) diff --git a/src/controllers/ProfileCertificateController.ts b/src/controllers/ProfileCertificateController.ts index d859491c..18ed3f3e 100644 --- a/src/controllers/ProfileCertificateController.ts +++ b/src/controllers/ProfileCertificateController.ts @@ -23,11 +23,13 @@ import HttpStatus from "../interfaces/http-status"; import HttpError from "../interfaces/http-error"; import { ProfileCertificateHistory } from "../entities/ProfileCertificateHistory"; import { RequestWithUser } from "../middlewares/user"; +import { Profile } from "../entities/Profile"; @Route("api/v1/org/profile/certificate") @Tags("ProfileCertificate") @Security("bearerAuth") export class ProfileCertificateController extends Controller { + private profileRepo = AppDataSource.getRepository(Profile); private certificateRepo = AppDataSource.getRepository(ProfileCertificate); private certificateHistoryRepo = AppDataSource.getRepository(ProfileCertificateHistory); @@ -110,6 +112,16 @@ export class ProfileCertificateController extends Controller { @Request() req: RequestWithUser, @Body() body: CreateProfileCertificate, ) { + if (!body.profileId) { + throw new HttpError(HttpStatus.BAD_REQUEST, "กรุณากรอก profileId"); + } + + const profile = await this.profileRepo.findOneBy({ id: body.profileId }); + + if (!profile) { + throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว"); + } + const data = new ProfileCertificate(); const history = new ProfileCertificateHistory(); diff --git a/src/controllers/ProfileHonorController.ts b/src/controllers/ProfileHonorController.ts index b0cf23a6..1cf305b2 100644 --- a/src/controllers/ProfileHonorController.ts +++ b/src/controllers/ProfileHonorController.ts @@ -19,11 +19,13 @@ import HttpStatus from "../interfaces/http-status"; import HttpError from "../interfaces/http-error"; import { ProfileHonorHistory } from "../entities/ProfileHonorHistory"; import { RequestWithUser } from "../middlewares/user"; +import { Profile } from "../entities/Profile"; @Route("api/v1/org/profile/honor") @Tags("ProfileHonor") @Security("bearerAuth") export class ProfileHonorController extends Controller { + private profileRepo = AppDataSource.getRepository(Profile); private honorRepo = AppDataSource.getRepository(ProfileHonor); private honorHistoryRepo = AppDataSource.getRepository(ProfileHonorHistory); @@ -104,6 +106,16 @@ export class ProfileHonorController extends Controller { @Post() public async newHonor(@Request() req: RequestWithUser, @Body() body: CreateProfileHonor) { + if (!body.profileId) { + throw new HttpError(HttpStatus.BAD_REQUEST, "กรุณากรอก profileId"); + } + + const profile = await this.profileRepo.findOneBy({ id: body.profileId }); + + if (!profile) { + throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว"); + } + const data = new ProfileHonor(); const history = new ProfileHonorHistory(); diff --git a/src/controllers/ProfileInsigniaController.ts b/src/controllers/ProfileInsigniaController.ts index 5e659265..d05ef9f7 100644 --- a/src/controllers/ProfileInsigniaController.ts +++ b/src/controllers/ProfileInsigniaController.ts @@ -23,11 +23,13 @@ import HttpStatus from "../interfaces/http-status"; import HttpError from "../interfaces/http-error"; import { ProfileInsigniaHistory } from "../entities/ProfileInsigniaHistory"; import { RequestWithUser } from "../middlewares/user"; +import { Profile } from "../entities/Profile"; @Route("api/v1/org/profile/insignia") @Tags("ProfileInsignia") @Security("bearerAuth") export class ProfileInsigniaController extends Controller { + private profileRepo = AppDataSource.getRepository(Profile); private insigniaRepo = AppDataSource.getRepository(ProfileInsignia); private insigniaHistoryRepo = AppDataSource.getRepository(ProfileInsigniaHistory); @@ -131,6 +133,16 @@ export class ProfileInsigniaController extends Controller { @Post() public async newInsignia(@Request() req: RequestWithUser, @Body() body: CreateProfileInsignia) { + if (!body.profileId) { + throw new HttpError(HttpStatus.BAD_REQUEST, "กรุณากรอก profileId"); + } + + const profile = await this.profileRepo.findOneBy({ id: body.profileId }); + + if (!profile) { + throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว"); + } + const data = new ProfileInsignia(); const history = new ProfileInsigniaHistory(); diff --git a/src/controllers/ProfileTrainingController.ts b/src/controllers/ProfileTrainingController.ts index a2c6f457..32a1a123 100644 --- a/src/controllers/ProfileTrainingController.ts +++ b/src/controllers/ProfileTrainingController.ts @@ -23,11 +23,13 @@ import HttpStatus from "../interfaces/http-status"; import HttpError from "../interfaces/http-error"; import { ProfileTrainingHistory } from "../entities/ProfileTrainingHistory"; import { RequestWithUser } from "../middlewares/user"; +import { Profile } from "../entities/Profile"; @Route("api/v1/org/profile/training") @Tags("ProfileTraining") @Security("bearerAuth") export class ProfileTrainingController extends Controller { + private profileRepo = AppDataSource.getRepository(Profile); private trainingRepo = AppDataSource.getRepository(ProfileTraining); private trainingHistoryRepo = AppDataSource.getRepository(ProfileTrainingHistory); @@ -123,6 +125,16 @@ export class ProfileTrainingController extends Controller { @Post() public async newTraining(@Request() req: RequestWithUser, @Body() body: CreateProfileTraining) { + if (!body.profileId) { + throw new HttpError(HttpStatus.BAD_REQUEST, "กรุณากรอก profileId"); + } + + const profile = await this.profileRepo.findOneBy({ id: body.profileId }); + + if (!profile) { + throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว"); + } + const data = new ProfileTraining(); const history = new ProfileTrainingHistory();