From d4ce99975dd1e6b0520b6fd69d08f3be1fd64d0f Mon Sep 17 00:00:00 2001 From: Supan Adit Pratama Date: Wed, 30 Oct 2024 22:55:25 +0700 Subject: [PATCH] feat: full working simple crud with id as unique identifier --- libs/prisma/src/processes/create.process.ts | 14 +++++------ libs/prisma/src/processes/delete.process.ts | 12 +++++----- libs/prisma/src/processes/list.process.ts | 6 ++--- .../src/processes/pagination.process.ts | 24 ++++++++++++++++++- libs/prisma/src/processes/read.process.ts | 12 +++++----- libs/prisma/src/processes/update.process.ts | 16 ++++++------- .../skeleton/src/executors/create.executor.ts | 16 +++++++++++++ .../src/executors/default.executor.ts | 6 ----- .../skeleton/src/executors/delete.executor.ts | 17 +++++++++++++ libs/skeleton/src/executors/index.ts | 6 +++++ libs/skeleton/src/executors/list.executor.ts | 14 +++++++++++ .../src/executors/pagination.executor.ts | 22 +++++++++++++++++ libs/skeleton/src/executors/read.executor.ts | 16 +++++++++++++ .../skeleton/src/executors/update.executor.ts | 18 ++++++++++++++ libs/skeleton/src/processes/create.process.ts | 4 +++- libs/skeleton/src/processes/delete.process.ts | 5 +++- .../src/processes/pagination.process.ts | 4 +++- libs/skeleton/src/processes/read.process.ts | 4 +++- libs/skeleton/src/processes/update.process.ts | 7 +++++- libs/skeleton/src/skeleton-crud.controller.ts | 22 ++++++++++------- 20 files changed, 194 insertions(+), 51 deletions(-) create mode 100644 libs/skeleton/src/executors/create.executor.ts create mode 100644 libs/skeleton/src/executors/delete.executor.ts create mode 100644 libs/skeleton/src/executors/list.executor.ts create mode 100644 libs/skeleton/src/executors/pagination.executor.ts create mode 100644 libs/skeleton/src/executors/read.executor.ts create mode 100644 libs/skeleton/src/executors/update.executor.ts diff --git a/libs/prisma/src/processes/create.process.ts b/libs/prisma/src/processes/create.process.ts index 1517727..5670b62 100644 --- a/libs/prisma/src/processes/create.process.ts +++ b/libs/prisma/src/processes/create.process.ts @@ -5,18 +5,16 @@ export class PrismaCreateProcess extends PrismaProcess implements CreateProcess { - private dataInsert; - private dataResult; - - setData(data) { - this.dataInsert = data; - } + public data; + public result; async process(): Promise { - this.dataResult = await this.getDelegate().create(this.dataInsert); + this.result = await this.getDelegate().create({ + data: this.data, + }); } output() { - this.dataResult; + this.result; } } diff --git a/libs/prisma/src/processes/delete.process.ts b/libs/prisma/src/processes/delete.process.ts index 38a4647..e66ad15 100644 --- a/libs/prisma/src/processes/delete.process.ts +++ b/libs/prisma/src/processes/delete.process.ts @@ -1,20 +1,20 @@ -import { CreateProcess } from '@aditama-labs/nest-autocrud/skeleton'; +import { DeleteProcess } from '@aditama-labs/nest-autocrud/skeleton'; import { PrismaProcess } from './prisma.process'; export class PrismaDeleteProcess extends PrismaProcess - implements CreateProcess + implements DeleteProcess { - private dataResult: any; - private id: any; + public id: any; + private result: any; async process(): Promise { - this.dataResult = await this.getDelegate().delete({ + this.result = await this.getDelegate().delete({ where: { id: this.id }, }); } output() { - return this.dataResult; + return this.result; } } diff --git a/libs/prisma/src/processes/list.process.ts b/libs/prisma/src/processes/list.process.ts index e42928d..d0f776a 100644 --- a/libs/prisma/src/processes/list.process.ts +++ b/libs/prisma/src/processes/list.process.ts @@ -2,13 +2,13 @@ import { ListProcess } from '@aditama-labs/nest-autocrud/skeleton'; import { PrismaProcess } from './prisma.process'; export class PrismaListProcess extends PrismaProcess implements ListProcess { - private data: any; + private result; async process(): Promise { - this.data = await this.getDelegate().findMany(); + this.result = await this.getDelegate().findMany(); } output() { - return this.data; + return this.result; } } diff --git a/libs/prisma/src/processes/pagination.process.ts b/libs/prisma/src/processes/pagination.process.ts index c545ce7..414b8f3 100644 --- a/libs/prisma/src/processes/pagination.process.ts +++ b/libs/prisma/src/processes/pagination.process.ts @@ -1,3 +1,25 @@ import { PaginationProcess } from '@aditama-labs/nest-autocrud/skeleton'; +import { PrismaProcess } from './prisma.process'; -export class PrismaPaginationProcess extends PaginationProcess {} +export class PrismaPaginationProcess + extends PrismaProcess + implements PaginationProcess +{ + public params: { page: number; limit: number }; + private result; + + async process(): Promise { + const { page, limit } = this.params; + const skip = (page - 1) * limit; + + this.result = await this.getDelegate().findMany({ + skip, + // @TODO: I don't know why this actually string even the type is number, without parseInt it will throw error + take: parseInt(limit.toString(), 10), + }); + } + + output() { + return this.result; + } +} diff --git a/libs/prisma/src/processes/read.process.ts b/libs/prisma/src/processes/read.process.ts index ac6250d..4c0b627 100644 --- a/libs/prisma/src/processes/read.process.ts +++ b/libs/prisma/src/processes/read.process.ts @@ -1,17 +1,17 @@ -import { CreateProcess } from '@aditama-labs/nest-autocrud/skeleton'; +import { ReadProcess } from '@aditama-labs/nest-autocrud/skeleton'; import { PrismaProcess } from './prisma.process'; -export class PrismaReadProcess extends PrismaProcess implements CreateProcess { - private data: any; - private id: any; +export class PrismaReadProcess extends PrismaProcess implements ReadProcess { + public id; + private result; async process(): Promise { - this.data = await this.getDelegate().findUnique({ + this.result = await this.getDelegate().findUnique({ where: { id: this.id }, }); } output() { - return this.data; + return this.result; } } diff --git a/libs/prisma/src/processes/update.process.ts b/libs/prisma/src/processes/update.process.ts index 539a018..9dc7e6c 100644 --- a/libs/prisma/src/processes/update.process.ts +++ b/libs/prisma/src/processes/update.process.ts @@ -1,22 +1,22 @@ -import { CreateProcess } from '@aditama-labs/nest-autocrud/skeleton'; +import { UpdateProcess } from '@aditama-labs/nest-autocrud/skeleton'; import { PrismaProcess } from './prisma.process'; export class PrismaUpdateProcess extends PrismaProcess - implements CreateProcess + implements UpdateProcess { - private dataResult: any; - private dataUpdate: any; - private id: any; + public id: any; + public data: any; + private result: any; async process(): Promise { - this.dataResult = await this.getDelegate().update({ - data: this.dataUpdate, + this.result = await this.getDelegate().update({ + data: this.data, where: { id: this.id }, }); } output() { - return this.dataResult; + return this.result; } } diff --git a/libs/skeleton/src/executors/create.executor.ts b/libs/skeleton/src/executors/create.executor.ts new file mode 100644 index 0000000..b8ffc53 --- /dev/null +++ b/libs/skeleton/src/executors/create.executor.ts @@ -0,0 +1,16 @@ +import { CreateProcess } from '../processes'; +import { DefaultExecutor } from './default.executor'; + +export class CreateExcutor extends DefaultExecutor { + constructor(process: CreateProcess, data) { + super(process); + // Set data to process + process.data = data; + } + + static async bootstrap(process: CreateProcess, data): Promise { + const executor = new CreateExcutor(process, data); + await executor.execute(); + return executor.getOutput(); + } +} diff --git a/libs/skeleton/src/executors/default.executor.ts b/libs/skeleton/src/executors/default.executor.ts index d5f5571..016d75a 100644 --- a/libs/skeleton/src/executors/default.executor.ts +++ b/libs/skeleton/src/executors/default.executor.ts @@ -15,10 +15,4 @@ export class DefaultExecutor { getOutput(): any { return this.process.output(); } - - static async bootstrap(process: ISkeletonProcess): Promise { - const executor = new DefaultExecutor(process); - await executor.execute(); - return executor.getOutput(); - } } diff --git a/libs/skeleton/src/executors/delete.executor.ts b/libs/skeleton/src/executors/delete.executor.ts new file mode 100644 index 0000000..635a2ad --- /dev/null +++ b/libs/skeleton/src/executors/delete.executor.ts @@ -0,0 +1,17 @@ +import { DeleteProcess } from '../processes'; +import { DefaultExecutor } from './default.executor'; + +// @TODO: ReadExecutor and DeleteExecutor can be merged into one executor +export class DeleteExecutor extends DefaultExecutor { + constructor(process: DeleteProcess, id) { + super(process); + // Set the id of the data + process.id = id; + } + + static async bootstrap(process: DeleteProcess, id): Promise { + const executor = new DeleteExecutor(process, id); + await executor.execute(); + return executor.getOutput(); + } +} diff --git a/libs/skeleton/src/executors/index.ts b/libs/skeleton/src/executors/index.ts index cdc72f2..60b8019 100644 --- a/libs/skeleton/src/executors/index.ts +++ b/libs/skeleton/src/executors/index.ts @@ -1 +1,7 @@ +export * from './create.executor'; export * from './default.executor'; +export * from './delete.executor'; +export * from './list.executor'; +export * from './pagination.executor'; +export * from './read.executor'; +export * from './update.executor'; diff --git a/libs/skeleton/src/executors/list.executor.ts b/libs/skeleton/src/executors/list.executor.ts new file mode 100644 index 0000000..6102540 --- /dev/null +++ b/libs/skeleton/src/executors/list.executor.ts @@ -0,0 +1,14 @@ +import { DefaultExecutor } from '.'; +import { ListProcess } from '../processes'; + +export class ListExecutor extends DefaultExecutor { + constructor(process: ListProcess) { + super(process); + } + + static async bootstrap(process: ListProcess): Promise { + const executor = new ListExecutor(process); + await executor.execute(); + return executor.getOutput(); + } +} diff --git a/libs/skeleton/src/executors/pagination.executor.ts b/libs/skeleton/src/executors/pagination.executor.ts new file mode 100644 index 0000000..54fd728 --- /dev/null +++ b/libs/skeleton/src/executors/pagination.executor.ts @@ -0,0 +1,22 @@ +import { DefaultExecutor } from '.'; +import { PaginationProcess } from '../processes'; + +export class PaginationExecutor extends DefaultExecutor { + constructor( + process: PaginationProcess, + params: { page: number; limit: number }, + ) { + super(process); + // Set params to process + process.params = params; + } + + static async bootstrap( + process: PaginationProcess, + params: { page: number; limit: number }, + ): Promise { + const executor = new PaginationExecutor(process, params); + await executor.execute(); + return executor.getOutput(); + } +} diff --git a/libs/skeleton/src/executors/read.executor.ts b/libs/skeleton/src/executors/read.executor.ts new file mode 100644 index 0000000..dd6be53 --- /dev/null +++ b/libs/skeleton/src/executors/read.executor.ts @@ -0,0 +1,16 @@ +import { ReadProcess } from '../processes'; +import { DefaultExecutor } from './default.executor'; + +export class ReadExecutor extends DefaultExecutor { + constructor(process: ReadProcess, id) { + super(process); + // Set the id of the data + process.id = id; + } + + static async bootstrap(process: ReadProcess, id): Promise { + const executor = new ReadExecutor(process, id); + await executor.execute(); + return executor.getOutput(); + } +} diff --git a/libs/skeleton/src/executors/update.executor.ts b/libs/skeleton/src/executors/update.executor.ts new file mode 100644 index 0000000..580880a --- /dev/null +++ b/libs/skeleton/src/executors/update.executor.ts @@ -0,0 +1,18 @@ +import { UpdateProcess } from '../processes'; +import { DefaultExecutor } from './default.executor'; + +// @TODO: This executor should be able to extend from ReadExecutor and CreateExecutor +export class UpdateExecutor extends DefaultExecutor { + constructor(process: UpdateProcess, id, data) { + super(process); + // Set the id and data to process + process.id = id; + process.data = data; + } + + static async bootstrap(process: UpdateProcess, id, data): Promise { + const executor = new UpdateExecutor(process, id, data); + await executor.execute(); + return executor.getOutput(); + } +} diff --git a/libs/skeleton/src/processes/create.process.ts b/libs/skeleton/src/processes/create.process.ts index 8896dcd..c1bd302 100644 --- a/libs/skeleton/src/processes/create.process.ts +++ b/libs/skeleton/src/processes/create.process.ts @@ -1,3 +1,5 @@ import { DefaultProcess } from './default.process'; -export class CreateProcess extends DefaultProcess {} +export class CreateProcess extends DefaultProcess { + public data; +} diff --git a/libs/skeleton/src/processes/delete.process.ts b/libs/skeleton/src/processes/delete.process.ts index db72350..dbb101c 100644 --- a/libs/skeleton/src/processes/delete.process.ts +++ b/libs/skeleton/src/processes/delete.process.ts @@ -1,3 +1,6 @@ import { DefaultProcess } from './default.process'; -export class DeleteProcess extends DefaultProcess {} +// @TODO: DeleteProcess and ReadProcess are the same, should be refactored next +export class DeleteProcess extends DefaultProcess { + public id; +} diff --git a/libs/skeleton/src/processes/pagination.process.ts b/libs/skeleton/src/processes/pagination.process.ts index c7e4b46..19dc821 100644 --- a/libs/skeleton/src/processes/pagination.process.ts +++ b/libs/skeleton/src/processes/pagination.process.ts @@ -1,3 +1,5 @@ import { DefaultProcess } from './default.process'; -export class PaginationProcess extends DefaultProcess {} +export class PaginationProcess extends DefaultProcess { + params: { page: number; limit: number }; +} diff --git a/libs/skeleton/src/processes/read.process.ts b/libs/skeleton/src/processes/read.process.ts index 63485b4..5a14dc1 100644 --- a/libs/skeleton/src/processes/read.process.ts +++ b/libs/skeleton/src/processes/read.process.ts @@ -1,3 +1,5 @@ import { DefaultProcess } from './default.process'; -export class ReadProcess extends DefaultProcess {} +export class ReadProcess extends DefaultProcess { + public id; +} diff --git a/libs/skeleton/src/processes/update.process.ts b/libs/skeleton/src/processes/update.process.ts index f4ff283..7a6b37f 100644 --- a/libs/skeleton/src/processes/update.process.ts +++ b/libs/skeleton/src/processes/update.process.ts @@ -1,3 +1,8 @@ import { DefaultProcess } from './default.process'; -export class UpdateProcess extends DefaultProcess {} +export class UpdateProcess extends DefaultProcess { + // @TODO: The property of id can be take from ReadProcess which is extended + public id; + // @TODO: The property of data can be take from CreateProcess which is extended + public data; +} diff --git a/libs/skeleton/src/skeleton-crud.controller.ts b/libs/skeleton/src/skeleton-crud.controller.ts index 5a7d8f2..77e6772 100644 --- a/libs/skeleton/src/skeleton-crud.controller.ts +++ b/libs/skeleton/src/skeleton-crud.controller.ts @@ -16,8 +16,14 @@ import { READ_PROCESS, UPDATE_PROCESS, } from './constants'; +import { CreateExcutor } from './executors/create.executor'; import { DefaultExecutor } from './executors/default.executor'; +import { DeleteExecutor } from './executors/delete.executor'; +import { ListExecutor } from './executors/list.executor'; +import { ReadExecutor } from './executors/read.executor'; +import { UpdateExecutor } from './executors/update.executor'; import { ISkeletonCRUDController } from './interfaces/controller/skeleton-crud.controller.interface'; +import { PaginationExecutor } from './executors'; export class SkeletonCRUDController implements ISkeletonCRUDController { constructor( @@ -37,33 +43,33 @@ export class SkeletonCRUDController implements ISkeletonCRUDController { @Post() async create(@Body() body): Promise { - return await DefaultExecutor.bootstrap(this.createProcess); + return await CreateExcutor.bootstrap(this.createProcess, body); } @Delete(':id') async delete(@Param('id') id) { - return await DefaultExecutor.bootstrap(this.deleteProcess); + return await DeleteExecutor.bootstrap(this.deleteProcess, id); } @Get('list') async list() { - return await DefaultExecutor.bootstrap(this.listProcess); + return await ListExecutor.bootstrap(this.listProcess); } @Get() async pagination( - @Query() params: { page?: number; limit?: number } = { page: 1, limit: 10 }, + @Query() params: { page: number; limit: number } = { page: 1, limit: 10 }, ) { - return await DefaultExecutor.bootstrap(this.paginationProcess); + return await PaginationExecutor.bootstrap(this.paginationProcess, params); } @Get(':id') async read(@Param('id') id) { - return await DefaultExecutor.bootstrap(this.readProcess); + return await ReadExecutor.bootstrap(this.readProcess, id); } - @Patch() + @Patch(':id') async update(@Param('id') id, @Body() body) { - return await DefaultExecutor.bootstrap(this.updateProcess); + return await UpdateExecutor.bootstrap(this.updateProcess, id, body); } }