hrms-api-org/reports/batch-04-controllers-31-40-analysis.md
DESKTOP-1R2VSQH\Lenovo ThinkPad E490 85e9be08f6 report: Controllers
2026-05-08 18:15:03 +07:00

9.9 KiB

รายงานการวิเคราะห์ความเสี่ยงการหยุดทำงานของระบบ (Crash Risk Analysis)

ชุดที่ 4 (Batch 4) - Controllers 31-40

วันที่ 8 พฤษภาคม 2568


รายชื่อ Controllers ที่ตรวจสอบ (31-40)

  1. MainController.ts
  2. MyController.ts
  3. OrgChild1Controller.ts
  4. OrgChild2Controller.ts
  5. OrgChild3Controller.ts
  6. OrgChild4Controller.ts
  7. OrgRootController.ts
  8. OrganizationController.ts (ไฟล์ขนาดใหญ่ >397KB)
  9. OrganizationDotnetController.ts (ไฟล์ขนาดใหญ่ >329KB)
  10. OrganizationUnauthorizeController.ts

สรุปผลการตรวจสอบ

จำนวนปัญหาที่พบ: 8 ปัญหา

ระดับความรุนแรง จำนวน ประเภท
🔴 วิกฤติ 2 มีโอกาสทำให้ Service Crash สูงมาก
🟠 สูง 4 มีโอกาสทำให้เกิด Unhandled Exception
🟡 ปานกลาง 2 อาจทำให้เกิดปัญหาในสถานการณ์เฉพาะ

รายละเอียดปัญหาแต่ละรายการ


🔴 ปัญหาที่ 1: การลบข้อมูลหลายตารางโดยไม่ใช้ Transaction (OrgRootController)

ไฟล์และตำแหน่ง:

  • ไฟล์: src/controllers/OrgRootController.ts
  • บรรทัด: 467-475
  • Method: delete

ประเภทปัญหา:

  1. Unhandled Exception - การดำเนินการหลายอย่างโดยไม่มี Transaction

สาเหตุที่ทำให้เสี่ยงต่อการ Crash:

โค้ดทำการลบข้อมูล 6 ตารางต่อเนื่องกันโดยไม่มี error handling และไม่ใช้ transaction:

  • หาก delete ตัวใดตัวหนึ่งล้มเหลว ข้อมูลจะไม่สมบูรณ์
  • ไม่มีการ rollback เมื่อเกิด error
  • หากมี foreign key constraint violation อาจทำให้ service crash

โค้ดปัจจุบัน (มีปัญหา):

await this.empPositionRepository.remove(empPositions, { data: request });
await this.empPosMasterRepository.remove(empPosMasters, { data: request });
await this.positionRepository.remove(positions, { data: request });
await this.posMasterRepository.remove(posMasters, { data: request });
await this.child4Repository.delete({ orgRootId: id });
await this.child3Repository.delete({ orgRootId: id });
await this.child2Repository.delete({ orgRootId: id });
await this.child1Repository.delete({ orgRootId: id });
await this.orgRootRepository.delete({ id });
// ❌ ไม่มี try-catch หรือ transaction

วิธีแก้ไขที่แนะนำ:

try {
  await AppDataSource.transaction(async (transactionalEntityManager) => {
    await transactionalEntityManager.remove(EmployeePosition, empPositions);
    await transactionalEntityManager.remove(EmployeePosMaster, empPosMasters);
    await transactionalEntityManager.remove(Position, positions);
    await transactionalEntityManager.remove(PosMaster, posMasters);
    await transactionalEntityManager.delete(OrgChild4, { orgRootId: id });
    await transactionalEntityManager.delete(OrgChild3, { orgRootId: id });
    await transactionalEntityManager.delete(OrgChild2, { orgRootId: id });
    await transactionalEntityManager.delete(OrgChild1, { orgRootId: id });
    await transactionalEntityManager.delete(OrgRoot, { id });
  });
  return new HttpSuccess();
} catch (error) {
  console.error('ลบข้อมูล OrgRoot ล้มเหลว:', error);
  
  if (error.code === '23503') {
    throw new HttpError(
      HttpStatusCode.CONFLICT,
      "ไม่สามารถลบได้ เนื่องจากมีการใช้งานข้อมูลนี้อยู่"
    );
  }
  
  throw new HttpError(
    HttpStatusCode.INTERNAL_SERVER_ERROR,
    "เกิดข้อผิดพลาดในการลบข้อมูล"
  );
}

🔴 ปัญหาที่ 2: Nested forEach กับ Async Operations (OrgRootController)

ไฟล์และตำแหน่ง:

  • ไฟล์: src/controllers/OrgRootController.ts
  • บรรทัด: 571-1009
  • Method: publishEmployee

ประเภทปัญหา:

  1. Unhandled Exception - Async operations ใน forEach ไม่ได้รับการจัดการ

สาเหตุที่ทำให้เสี่ยงต่อการ Crash:

มีการใช้ forEach ซ้อนกัน 4-5 ระดับ:

  • forEach ไม่รอ callback ให้ทำงานเสร็จ
  • Promise rejections อาจไม่ได้รับการ handle
  • หากเกิด error ใน nested operations อาจทำให้ unhandled rejection

🟠 ปัญหาที่ 3: Promise.all ที่ไม่มี Error Handling (OrgChild Controllers)

ไฟล์และตำแหน่ง:

  • ไฟล์: src/controllers/OrgChild1Controller.ts
  • บรรทัด: 105-113, 122-130, 242-250, 259-268
  • Method: save, Edit

ประเภทปัญหา:

  1. Missing Error Handle - Promise.all ไม่มี catch

สาเหตุที่ทำให้เสี่ยงต่อการ Crash:

มีการใช้ Promise.all หลายครั้งแต่ไม่มี error handling:

  • หาก database operations fail จะเกิด unhandled rejection
  • ไม่มี try-catch รอบ Promise.all

🟠 ปัญหาที่ 4-6: การลบข้อมูลหลายตารางโดยไม่ใช้ Transaction (OrgChild1-4 Controllers)

ไฟล์และตำแหน่ง:

  • ไฟล์: src/controllers/OrgChild1Controller.ts (บรรทัด 456-463)
  • ไฟล์: src/controllers/OrgChild2Controller.ts (บรรทัด 317-323)
  • ไฟล์: src/controllers/OrgChild3Controller.ts (บรรทัด 272-278)
  • ไฟล์: src/controllers/OrgChild4Controller.ts (บรรทัด 311-315)
  • Method: delete

ประเภทปัญหา:

  1. Unhandled Exception - การลบข้อมูลหลายตารางไม่มี Transaction

🟠 ปัญหาที่ 7: Map ที่มี Null Reference (OrgRootController)

ไฟล์และตำแหน่ง:

  • ไฟล์: src/controllers/OrgRootController.ts
  • บรรทัด: 446-465
  • Method: delete

ประเภทปัญหา:

  1. Unhandled Exception - Null reference ใน map

🟡 ปัญหาที่ 8: Missing Error Handling ใน MainController

ไฟล์และตำแหน่ง:

  • ไฟล์: src/controllers/MainController.ts
  • บรรทัด: 42-52
  • Method: getMainPerson

ประเภทปัญหา:

  1. Missing Error Handle - ไม่มี error handling

สรุปสถิติ

ปัญหาตามระดับความรุนแรง:

ระดับ จำนวน ไฟล์ที่พบ
🔴 วิกฤติ 2 OrgRootController (2)
🟠 สูง 4 OrgRoot, OrgChild1-4Controllers
🟡 ปานกลาง 2 MainController, OrgRootController

ไฟล์ที่มีปัญหามากที่สุด:

  1. OrgRootController.ts - 4 ปัญหา (รุนแรงที่สุด)
  2. OrgChild1Controller.ts - 2 ปัญหา
  3. OrgChild2Controller.ts - 1 ปัญหา
  4. OrgChild3Controller.ts - 1 ปัญหา
  5. OrgChild4Controller.ts - 1 ปัญหา
  6. MainController.ts - 1 ปัญหา

ปัญหาที่พบบ่อยที่สุด:

  1. การลบข้อมูลหลายตารางโดยไม่ใช้ Transaction (พบ 5 ครั้ง)
  2. Promise.all/Async operations ไม่มี Error Handling (พบ 3 ครั้ง)

คำแนะนำเพื่อป้องกันปัญหา

1. สร้าง Transaction Wrapper Function

สร้าง utility function สำหรับ database operations หลายตาราง

2. ใช้ for...of แทน forEach สำหรับ Async Operations

// ❌ ไม่ดี
array.forEach(async (item) => {
  await processItem(item);
});

// ✅ ดี
for (const item of array) {
  await processItem(item);
}

3. เพิ่ม Error Handling รอบ Async Operations

ใช้ try-catch ครอบ Promise.all และ async operations ทั้งหมด

4. Enable Strict TypeScript

ตรวจสอบ tsconfig.json ให้แน่ใจว่ามีการเปิดใช้ strict mode


บันทึกเพิ่มเติม

  • วันที่สร้างรายงาน: 8 พฤษภาคม 2568
  • จำนวน Controllers ที่ตรวจสอบ: 10 ไฟล์ (31-40)
  • เครื่องมือที่ใช้: การวิเคราะห์ Code และ Pattern Recognition
  • ข้อจำกัด: OrganizationController.ts และ OrganizationDotnetController.ts มีขนาดใหญ่มาก (>300KB)

รายงานนี้ครอบคลุมเฉพาะ Controllers 31-40 สำหรับชุดที่ 4