From 12e8cdb0809a1ef8cb3a558456e991df93fd2540 Mon Sep 17 00:00:00 2001 From: waruneeauy Date: Thu, 21 May 2026 10:30:09 +0700 Subject: [PATCH] fixed bug sync org to leave service --- src/controllers/ScriptProfileOrgController.ts | 93 ++++++++++++++++--- 1 file changed, 78 insertions(+), 15 deletions(-) diff --git a/src/controllers/ScriptProfileOrgController.ts b/src/controllers/ScriptProfileOrgController.ts index aa6908e2..4881249e 100644 --- a/src/controllers/ScriptProfileOrgController.ts +++ b/src/controllers/ScriptProfileOrgController.ts @@ -38,6 +38,10 @@ export class ScriptProfileOrgController extends Controller { process.env.CRONJOB_UPDATE_WINDOW_HOURS || "24", 10, ); + private readonly LEAVE_SERVICE_BATCH_SIZE = parseInt( + process.env.LEAVE_SERVICE_BATCH_SIZE || "50", + 10, + ); /** * Script to update profile's organizational structure in leave service and sync to Keycloak @@ -176,21 +180,6 @@ export class ScriptProfileOrgController extends Controller { }); } - // Update profile's org structure in leave service by calling API - console.log("cronjobUpdateOrg: Calling leave service API", { - payloadCount: payloads.length, - }); - - await axios.put(`${process.env.API_URL}/leave-beginning/schedule/update-dna`, payloads, { - headers: { - "Content-Type": "application/json", - api_key: process.env.API_KEY, - }, - timeout: 30000, // 30 second timeout - }); - - console.log("cronjobUpdateOrg: Leave service API call successful"); - // Group profile IDs by type for proper syncing const profileIdsByType = this.groupProfileIdsByType(payloads); @@ -256,16 +245,90 @@ export class ScriptProfileOrgController extends Controller { syncResults.failed += typeResult.failed; } + // Update profile's org structure in leave service by calling API + console.log("cronjobUpdateOrg: Calling leave service API with chunking", { + payloadCount: payloads.length, + batchSize: this.LEAVE_SERVICE_BATCH_SIZE, + expectedBatches: Math.ceil(payloads.length / this.LEAVE_SERVICE_BATCH_SIZE), + }); + + const chunks = this.chunkArray(payloads, this.LEAVE_SERVICE_BATCH_SIZE); + const leaveServiceResults = { + total: payloads.length, + success: 0, + failed: 0, + batchesCompleted: 0, + batchesFailed: 0, + }; + + for (let i = 0; i < chunks.length; i++) { + const chunk = chunks[i]; + const batchNumber = i + 1; + + console.log( + `cronjobUpdateOrg: Processing leave service batch ${batchNumber}/${chunks.length}`, + { + batchSize: chunk.length, + batchRange: `${i * this.LEAVE_SERVICE_BATCH_SIZE + 1}-${Math.min( + (batchNumber + 1) * this.LEAVE_SERVICE_BATCH_SIZE, + payloads.length, + )}`, + }, + ); + + try { + await axios.put( + `${process.env.API_URL}/leave-beginning/schedule/update-dna`, + chunk, + { + headers: { + "Content-Type": "application/json", + api_key: process.env.API_KEY, + }, + timeout: 120000, // 120 second timeout per chunk + }, + ); + + leaveServiceResults.success += chunk.length; + leaveServiceResults.batchesCompleted++; + + console.log(`cronjobUpdateOrg: Leave service batch ${batchNumber}/${chunks.length} completed`, { + success: chunk.length, + }); + } catch (error: any) { + leaveServiceResults.failed += chunk.length; + leaveServiceResults.batchesFailed++; + + console.error( + `cronjobUpdateOrg: Leave service batch ${batchNumber}/${chunks.length} failed`, + { + error: error.message, + batchSize: chunk.length, + responseStatus: error.response?.status, + responseData: error.response?.data, + }, + ); + + // Continue processing remaining batches + } + } + + console.log("cronjobUpdateOrg: Leave service API call completed", { + ...leaveServiceResults, + }); + const duration = Date.now() - startTime; console.log("cronjobUpdateOrg: Job completed", { duration: `${duration}ms`, processed: payloads.length, + leaveServiceResults, syncResults, }); return new HttpSuccess({ message: "Update org completed", processed: payloads.length, + leaveServiceResults, syncResults, duration: `${duration}ms`, });