From 999ba1ff9b971da0bba3aa126078e2d1d0682a0b Mon Sep 17 00:00:00 2001 From: Firman Ramdhani <33869609+firmanramdhani@users.noreply.github.com> Date: Mon, 7 Jul 2025 17:21:38 +0700 Subject: [PATCH] feat: update guard time schedule --- package.json | 1 + .../data-scheduling/data-scheduling.module.ts | 12 +++++- .../data-scheduling-default.manager.ts | 22 ++++++++++- .../data-scheduling-data.controller.ts | 38 +++---------------- .../infrastructure/dto/data-scheduling.dto.ts | 8 +--- .../dto/filter-data-scheduling.dto.ts | 6 +-- .../guards/setup-scheduling.guard.ts | 14 +++++++ yarn.lock | 9 ++++- 8 files changed, 63 insertions(+), 47 deletions(-) diff --git a/package.json b/package.json index ef1f732..bb8761e 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,7 @@ "mathjs": "^13.0.2", "midtrans-client": "^1.3.1", "moment": "^2.30.1", + "moment-timezone": "^0.6.0", "nano": "^10.1.3", "nodemailer": "^6.9.14", "pdfmake": "^0.2.10", diff --git a/src/modules/configuration/data-scheduling/data-scheduling.module.ts b/src/modules/configuration/data-scheduling/data-scheduling.module.ts index 7e0dd21..3912b44 100644 --- a/src/modules/configuration/data-scheduling/data-scheduling.module.ts +++ b/src/modules/configuration/data-scheduling/data-scheduling.module.ts @@ -7,7 +7,6 @@ import { DataSchedulingReadService } from './data/services/data-scheduling-read. import { DataSchedulingReadController } from './infrastructure/data-scheduling-read.controller'; import { DataSchedulingReadOrchestrator } from './domain/usecases/data-scheduling-read.orchestrator'; import { - DataSchedulingActiveController, DataSchedulingDataController, DataSchedulingDefaultController, DataSchedulingSetupController, @@ -29,6 +28,11 @@ import { BatchInactiveDataSchedulingManager } from './domain/usecases/managers/b import { DataSchedulingModel } from './data/models/data-scheduling.model'; import { DataSchedulingDefaultModel } from './data/models/data-scheduling-default.model'; import { DataSchedulingManager } from './domain/usecases/managers/data-scheduling-default.manager'; +import { SetupSchedulingGuard } from './infrastructure/guards/setup-scheduling.guard'; + +import { JwtModule } from '@nestjs/jwt'; +import { JWT_EXPIRED } from 'src/core/sessions/constants'; +import { JWT_SECRET } from 'src/core/sessions/constants'; @Module({ imports: [ @@ -37,16 +41,20 @@ import { DataSchedulingManager } from './domain/usecases/managers/data-schedulin [DataSchedulingModel, DataSchedulingDefaultModel], CONNECTION_NAME.DEFAULT, ), + JwtModule.register({ + secret: JWT_SECRET, + signOptions: { expiresIn: JWT_EXPIRED }, + }), CqrsModule, ], controllers: [ DataSchedulingDataController, DataSchedulingReadController, DataSchedulingDefaultController, - DataSchedulingActiveController, DataSchedulingSetupController, ], providers: [ + SetupSchedulingGuard, IndexDataSchedulingManager, DetailDataSchedulingManager, CreateDataSchedulingManager, diff --git a/src/modules/configuration/data-scheduling/domain/usecases/managers/data-scheduling-default.manager.ts b/src/modules/configuration/data-scheduling/domain/usecases/managers/data-scheduling-default.manager.ts index 7d87a93..fb9da9c 100644 --- a/src/modules/configuration/data-scheduling/domain/usecases/managers/data-scheduling-default.manager.ts +++ b/src/modules/configuration/data-scheduling/domain/usecases/managers/data-scheduling-default.manager.ts @@ -13,6 +13,9 @@ import { TABLE_NAME } from 'src/core/strings/constants/table.constants'; import { SelectQueryBuilder } from 'typeorm'; import { DataSchedulingModel } from '../../../data/models/data-scheduling.model'; import { decryptionTotal } from '../../../infrastructure/helpers'; +import * as momentTz from 'moment-timezone'; +import { EventBus } from '@nestjs/cqrs'; +import { DataSchedulingChangeStatusEvent } from '../../entities/event/data-scheduling-change-status.event'; @Injectable() export class DataSchedulingManager { @@ -20,6 +23,8 @@ export class DataSchedulingManager { protected userProvider: UserProvider; constructor( + private eventBus: EventBus, + @InjectRepository(DataSchedulingDefaultModel) private repository: Repository, @@ -72,7 +77,11 @@ export class DataSchedulingManager { return this.queryBuilder().getOne(); } - async getActiveData(date) { + async getActiveData() { + const timeZoneWIB = 'Asia/Jakarta'; + const nowInWIB = momentTz().tz(timeZoneWIB).format('YYYY-MM-DD'); + const date = nowInWIB; + const qb = this.repoSchedule.createQueryBuilder(TABLE_NAME.DATA_SCHEDULING); const findData: DataSchedulingEntity = await qb @@ -86,6 +95,15 @@ export class DataSchedulingManager { return { value: defaultData?.default_value }; } - return { value: decryptionTotal(findData.indexing_key as string) }; + return { value: decryptionTotal(findData.indexing_key as string), date }; + } + + async setupActiveScheduling() { + const activeSchedule = await this.getActiveData(); + await this.eventBus.publish( + new DataSchedulingChangeStatusEvent({ data: activeSchedule } as any), + ); + + return { message: 'Berhasil setup transaction scheduling.' }; } } diff --git a/src/modules/configuration/data-scheduling/infrastructure/data-scheduling-data.controller.ts b/src/modules/configuration/data-scheduling/infrastructure/data-scheduling-data.controller.ts index c94187c..71dcfd2 100644 --- a/src/modules/configuration/data-scheduling/infrastructure/data-scheduling-data.controller.ts +++ b/src/modules/configuration/data-scheduling/infrastructure/data-scheduling-data.controller.ts @@ -7,12 +7,10 @@ import { Patch, Post, Put, - Query, UseGuards, } from '@nestjs/common'; import { DataSchedulingDataOrchestrator } from '../domain/usecases/data-scheduling-data.orchestrator'; import { - SetupDataSchedulingDto, CreateDataSchedulingDto, EditDataSchedulingDto, EditDataSchedulingDefaultDto, @@ -20,7 +18,6 @@ import { import { MODULE_NAME } from 'src/core/strings/constants/module.constants'; import { ApiBearerAuth, ApiTags } from '@nestjs/swagger'; import { - DataSchedulingActiveEntity, DataSchedulingDefaultEntity, DataSchedulingEntity, } from '../domain/entities/data-scheduling.entity'; @@ -29,7 +26,6 @@ import { BatchIdsDto } from 'src/core/modules/infrastructure/dto/base-batch.dto' import { ExcludePrivilege, Public } from 'src/core/guards'; import { SetupSchedulingGuard } from './guards/setup-scheduling.guard'; import { DataSchedulingManager } from '../domain/usecases/managers/data-scheduling-default.manager'; -import { FilterActiveDataSchedulingDto } from './dto/filter-data-scheduling.dto'; @ApiTags(`${MODULE_NAME.DATA_SCHEDULING.split('-').join(' ')} - data`) @Controller(`v1/${MODULE_NAME.DATA_SCHEDULING}`) @@ -115,43 +111,19 @@ export class DataSchedulingDefaultController { } } -@ApiTags( - `${MODULE_NAME.DATA_SCHEDULING_ACTIVE.split('-').join(' ')} active - Data`, -) -@Controller(`v1/${MODULE_NAME.DATA_SCHEDULING_ACTIVE}`) -@Public(false) -@ApiBearerAuth('JWT') -export class DataSchedulingActiveController { - constructor(private manager: DataSchedulingManager) {} - - @Get() - async get( - @Query() params: FilterActiveDataSchedulingDto, - ): Promise { - return await this.manager.getActiveData(params?.date); - } -} - @ApiTags( `${MODULE_NAME.DATA_SCHEDULING_SETUP.split('-').join(' ')} setup - Data`, ) @Controller(`v1/${MODULE_NAME.DATA_SCHEDULING_SETUP}`) @Public(true) +@ApiBearerAuth('JWT') export class DataSchedulingSetupController { + constructor(private manager: DataSchedulingManager) {} + @Post() @ExcludePrivilege() @UseGuards(SetupSchedulingGuard) - async setup( - @Body() data: SetupDataSchedulingDto, - ): Promise { - console.log('payload scheduling setup', { data }); - - // TODO: Implement logic for "Send to Black Hole" configuration. - // 1. Retrieve the relevant scheduling configuration based on the date provided in the request body. - // 2. If a specific scheduling configuration is found, apply its values to the main 'configuration' table. - // These values will then be used for the "Send to Black Hole" logic. - // 3. If no specific scheduling configuration is found for the given date, update the 'configuration' table - // with values from the 'data scheduling default' settings instead. - return; + async setup(): Promise<{ message: string }> { + return this.manager.setupActiveScheduling(); } } diff --git a/src/modules/configuration/data-scheduling/infrastructure/dto/data-scheduling.dto.ts b/src/modules/configuration/data-scheduling/infrastructure/dto/data-scheduling.dto.ts index 527ec22..868f4e8 100644 --- a/src/modules/configuration/data-scheduling/infrastructure/dto/data-scheduling.dto.ts +++ b/src/modules/configuration/data-scheduling/infrastructure/dto/data-scheduling.dto.ts @@ -83,10 +83,6 @@ export class EditDataSchedulingDefaultDto } export class SetupDataSchedulingDto { - @ApiProperty({ - type: Date, - required: true, - example: '2024-01-01', - }) - schedule_date: Date; + // @ApiProperty({ type: 'string', required: true, example: '2025-01-01' }) + // date: Date; } diff --git a/src/modules/configuration/data-scheduling/infrastructure/dto/filter-data-scheduling.dto.ts b/src/modules/configuration/data-scheduling/infrastructure/dto/filter-data-scheduling.dto.ts index 454aea5..ab6a50f 100644 --- a/src/modules/configuration/data-scheduling/infrastructure/dto/filter-data-scheduling.dto.ts +++ b/src/modules/configuration/data-scheduling/infrastructure/dto/filter-data-scheduling.dto.ts @@ -17,7 +17,7 @@ export class FilterDataSchedulingDto } export class FilterActiveDataSchedulingDto { - @ApiProperty({ type: 'string', required: true }) - @ValidateIf((body) => body.schedule_date_from) - date: Date; + // @ApiProperty({ type: 'string', required: true }) + // @ValidateIf((body) => body.schedule_date_from) + // date: Date; } diff --git a/src/modules/configuration/data-scheduling/infrastructure/guards/setup-scheduling.guard.ts b/src/modules/configuration/data-scheduling/infrastructure/guards/setup-scheduling.guard.ts index 1be4a0e..4993947 100644 --- a/src/modules/configuration/data-scheduling/infrastructure/guards/setup-scheduling.guard.ts +++ b/src/modules/configuration/data-scheduling/infrastructure/guards/setup-scheduling.guard.ts @@ -4,11 +4,15 @@ import { Injectable, UnprocessableEntityException, } from '@nestjs/common'; +import { JwtService } from '@nestjs/jwt'; @Injectable() export class SetupSchedulingGuard implements CanActivate { + constructor(private readonly jwtService: JwtService) {} + async canActivate(context: ExecutionContext): Promise { const request = context.switchToHttp().getRequest(); + const jwtAuth = request.headers['authorization']; const setupAuth = request.headers['x-setup-authorization']; if (setupAuth) { @@ -19,6 +23,16 @@ export class SetupSchedulingGuard implements CanActivate { } catch (err) { throw new UnprocessableEntityException('Invalid authentication.'); } + } else if (jwtAuth && jwtAuth.startsWith('Bearer ')) { + const token = jwtAuth.split(' ')[1]; + try { + const payload = await this.jwtService.verifyAsync(token); + if (payload) return true; + else new UnprocessableEntityException('Setup Authorization Not Found.'); + return true; + } catch (err) { + throw new UnprocessableEntityException('Invalid JWT token'); + } } throw new UnprocessableEntityException('Invalid authentication'); diff --git a/yarn.lock b/yarn.lock index a4abb7f..f235141 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5607,7 +5607,14 @@ module-details-from-path@^1.0.3: resolved "https://registry.yarnpkg.com/module-details-from-path/-/module-details-from-path-1.0.3.tgz#114c949673e2a8a35e9d35788527aa37b679da2b" integrity sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A== -moment@^2.30.1: +moment-timezone@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.6.0.tgz#c5a6519171f31a64739ea75d33f5c136c08ff608" + integrity sha512-ldA5lRNm3iJCWZcBCab4pnNL3HSZYXVb/3TYr75/1WCTWYuTqYUb5f/S384pncYjJ88lbO8Z4uPDvmoluHJc8Q== + dependencies: + moment "^2.29.4" + +moment@^2.29.4, moment@^2.30.1: version "2.30.1" resolved "https://registry.yarnpkg.com/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae" integrity sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==