diff --git a/src/controllers/ExRetirementController.ts b/src/controllers/ExRetirementController.ts index c9c45dae..6a19ddfc 100644 --- a/src/controllers/ExRetirementController.ts +++ b/src/controllers/ExRetirementController.ts @@ -43,35 +43,6 @@ class TokenCache { } } -// network/DNS error codes ที่ถือว่าเป็น transient (ควร retry) -const TRANSIENT_NETWORK_CODES = [ - "EAI_AGAIN", // DNS lookup ล้มเหลวชั่วคราว - "ENOTFOUND", - "ECONNRESET", - "ETIMEDOUT", - "ECONNREFUSED", - "EHOSTUNREACH", - "ENETUNREACH", -]; - -// ตรวจว่า error ควร retry: ครอบ network/DNS (ไม่มี response หรือ code ตรง TRANSIENT) และ HTTP 5xx -function isTransientError(error: any): boolean { - if (!error) return false; - if (!error.response || TRANSIENT_NETWORK_CODES.includes(error.code)) { - return true; - } - return error.response?.status >= 500; -} - -// หน่วงเวลา (backoff) ระหว่าง retry — ใช้รูปแบบ setTimeout เดียวกับ keycloak/index.ts -function sleep(ms: number): Promise { - return new Promise((resolve) => setTimeout(resolve, ms)); -} - -// config retry สำหรับเรียก Exprofile -const EXPROFILE_MAX_RETRIES = 3; // จากเดิม 2 -const EXPROFILE_BACKOFF_BASE_MS = 1000; // backoff = base * 2^retryCount → 1s, 2s - @Route("api/v1/org/ex/retirement") @Tags("ExRetirement") @Security("bearerAuth") @@ -89,7 +60,7 @@ export class ExRetirementController extends Controller { }, ) { let retryCount = 0; - const maxRetries = EXPROFILE_MAX_RETRIES; + const maxRetries = 2; while (retryCount < maxRetries) { try { @@ -121,9 +92,8 @@ export class ExRetirementController extends Controller { // return res.data; return new HttpSuccess(res.data.data); } catch (error: any) { - if (isTransientError(error) && retryCount < maxRetries - 1) { + if (error.response?.status === 500 && retryCount < maxRetries - 1) { TokenCache.delete(`${clientId}:${clientSecret}`); - await sleep(EXPROFILE_BACKOFF_BASE_MS * 2 ** retryCount); retryCount++; continue; } @@ -137,7 +107,7 @@ export class ExRetirementController extends Controller { @Get("/document/{documentId}") async getDocument(@Path("documentId") officerDocumentID: string, @Request() req: any) { let retryCount = 0; - const maxRetries = EXPROFILE_MAX_RETRIES; + const maxRetries = 2; while (retryCount < maxRetries) { try { const token = await getToken(clientId, clientSecret); @@ -166,9 +136,8 @@ export class ExRetirementController extends Controller { return; } } catch (error: any) { - if (isTransientError(error) && retryCount < maxRetries - 1) { + if (error.response?.status === 500 && retryCount < maxRetries - 1) { TokenCache.delete(`${clientId}:${clientSecret}`); - await sleep(EXPROFILE_BACKOFF_BASE_MS * 2 ** retryCount); retryCount++; continue; } @@ -202,13 +171,8 @@ async function getToken(ClientID: string, ClientSecret: string): Promise TokenCache.set(cacheKey, token); return token; } catch (error) { - // log แบบกระชับ (ลด log noise จากการ dump object ใหญ่ตามที่เห็นใน log จริง) - console.error( - "getToken error:", - error instanceof Error ? `${error.name}: ${error.message}` : error, - ); - // โยน AxiosError ตัวจริงออกไปให้ caller อ่าน code / response / status เพื่อตัดสินใจ retry - throw error; + console.error('getToken error:', error); + return Promise.reject({ message: "Error occurred", error }); } } @@ -234,7 +198,7 @@ export async function PostRetireToExprofile( } let retryCount = 0; - const maxRetries = EXPROFILE_MAX_RETRIES; + const maxRetries = 2; while (retryCount < maxRetries) { try { @@ -271,9 +235,8 @@ export async function PostRetireToExprofile( return res.data; } catch (error: any) { - if (isTransientError(error) && retryCount < maxRetries - 1) { + if (error.response?.status === 500 && retryCount < maxRetries - 1) { TokenCache.delete(`${clientId}:${clientSecret}`); - await sleep(EXPROFILE_BACKOFF_BASE_MS * 2 ** retryCount); retryCount++; continue; } diff --git a/src/controllers/ProfileController.ts b/src/controllers/ProfileController.ts index 254f5c46..05ab62f8 100644 --- a/src/controllers/ProfileController.ts +++ b/src/controllers/ProfileController.ts @@ -11451,10 +11451,11 @@ export class ProfileController extends Controller { system?: string; }, ) { - // ค้นหารายชื่อถ้าไม่ส่ง system มาให้ default ตามทะเบียนประวัติ - let _system: string = "SYS_REGISTRY_OFFICER"; - if (body.system) _system = body.system; - let _data = await new permission().PermissionOrgList(request, _system); + // comment ออกก่อนเพราะยังไม่ได้ใช้ + // // ค้นหารายชื่อถ้าไม่ส่ง system มาให้ default ตามทะเบียนประวัติ + // let _system: string = "SYS_REGISTRY_OFFICER"; + // if (body.system) _system = body.system; + // let _data = await new permission().PermissionOrgList(request, _system); const findRevision = await this.orgRevisionRepo.findOne({ where: { orgRevisionIsCurrent: true }, }); @@ -11499,50 +11500,10 @@ export class ProfileController extends Controller { .leftJoinAndSelect("current_holders.orgChild2", "orgChild2") .leftJoinAndSelect("current_holders.orgChild3", "orgChild3") .leftJoinAndSelect("current_holders.orgChild4", "orgChild4") - .where("profile.isActive = :isActive AND profile.isDelete = :isDelete", { - isActive: true, - isDelete: false, + .where(body.system ? "profile.isActive = :isActive" : "profile.isDelete = :isDelete", { + isActive: false, + isDelete: true, }) - .andWhere( - _data.root != undefined && _data.root != null - ? _data.root[0] != null - ? `current_holders.orgRootId IN (:...root)` - : `current_holders.orgRootId is null` - : "1=1", - { root: _data.root }, - ) - .andWhere( - _data.child1 != undefined && _data.child1 != null - ? _data.child1[0] != null - ? `current_holders.orgChild1Id IN (:...child1)` - : `current_holders.orgChild1Id is null` - : "1=1", - { child1: _data.child1 }, - ) - .andWhere( - _data.child2 != undefined && _data.child2 != null - ? _data.child2[0] != null - ? `current_holders.orgChild2Id IN (:...child2)` - : `current_holders.orgChild2Id is null` - : "1=1", - { child2: _data.child2 }, - ) - .andWhere( - _data.child3 != undefined && _data.child3 != null - ? _data.child3[0] != null - ? `current_holders.orgChild3Id IN (:...child3)` - : `current_holders.orgChild3Id is null` - : "1=1", - { child3: _data.child3 }, - ) - .andWhere( - _data.child4 != undefined && _data.child4 != null - ? _data.child4[0] != null - ? `current_holders.orgChild4Id IN (:...child4)` - : `current_holders.orgChild4Id is null` - : "1=1", - { child4: _data.child4 }, - ) .andWhere( new Brackets((qb) => { qb.orWhere(body.keyword ? queryLike : "1=1", { keyword: `%${body.keyword}%` }); diff --git a/src/controllers/ProfileEmployeeController.ts b/src/controllers/ProfileEmployeeController.ts index 3dd769ed..21eb9a5d 100644 --- a/src/controllers/ProfileEmployeeController.ts +++ b/src/controllers/ProfileEmployeeController.ts @@ -6172,7 +6172,6 @@ export class ProfileEmployeeController extends Controller { */ @Post("search-personal-no-keycloak") async getProfileBySearchKeywordNoKeyCloak( - @Request() request: RequestWithUser, @Query("page") page: number = 1, @Query("pageSize") pageSize: number = 10, @Body() @@ -6182,10 +6181,6 @@ export class ProfileEmployeeController extends Controller { system?: string; }, ) { - // ค้นหารายชื่อถ้าไม่ส่ง system มาให้ default ตามทะเบียนประวัติ - let _system: string = "SYS_REGISTRY_EMP"; - if (body.system) _system = body.system; - let _data = await new permission().PermissionOrgList(request, _system); const findRevision = await this.orgRevisionRepo.findOne({ where: { orgRevisionIsCurrent: true }, }); @@ -6230,50 +6225,10 @@ export class ProfileEmployeeController extends Controller { .leftJoinAndSelect("current_holders.orgChild2", "orgChild2") .leftJoinAndSelect("current_holders.orgChild3", "orgChild3") .leftJoinAndSelect("current_holders.orgChild4", "orgChild4") - .where("profile.isActive = :isActive AND profile.isDelete = :isDelete", { - isActive: true, - isDelete: false, + .where(body.system ? "profile.isActive = :isActive" : "profile.isDelete = :isDelete", { + isActive: false, + isDelete: true, }) - .andWhere( - _data.root != undefined && _data.root != null - ? _data.root[0] != null - ? `current_holders.orgRootId IN (:...root)` - : `current_holders.orgRootId is null` - : "1=1", - { root: _data.root }, - ) - .andWhere( - _data.child1 != undefined && _data.child1 != null - ? _data.child1[0] != null - ? `current_holders.orgChild1Id IN (:...child1)` - : `current_holders.orgChild1Id is null` - : "1=1", - { child1: _data.child1 }, - ) - .andWhere( - _data.child2 != undefined && _data.child2 != null - ? _data.child2[0] != null - ? `current_holders.orgChild2Id IN (:...child2)` - : `current_holders.orgChild2Id is null` - : "1=1", - { child2: _data.child2 }, - ) - .andWhere( - _data.child3 != undefined && _data.child3 != null - ? _data.child3[0] != null - ? `current_holders.orgChild3Id IN (:...child3)` - : `current_holders.orgChild3Id is null` - : "1=1", - { child3: _data.child3 }, - ) - .andWhere( - _data.child4 != undefined && _data.child4 != null - ? _data.child4[0] != null - ? `current_holders.orgChild4Id IN (:...child4)` - : `current_holders.orgChild4Id is null` - : "1=1", - { child4: _data.child4 }, - ) .andWhere( new Brackets((qb) => { qb.orWhere(body.keyword ? queryLike : "1=1", { keyword: `%${body.keyword}%` });