hrms-api-org/src/utils/LogMemoryStore.ts

166 lines
4.3 KiB
TypeScript
Raw Normal View History

feat: optimize detailSuperAdmin API to fix database connection issue ปัญหา: API GET /api/v1/org/super-admin/{id} ทำให้ระบบดับเพราะ N+1 queries - เดิม: >1,000,000 queries (100 orgRoots × 10 children × 10 counts/level) - ใหม่: ~10 queries (query รวมครั้งเดียว + 5 org queries) การเปลี่ยนแปลง: 1. สร้าง OrganizationController-optimized.ts - getPositionCounts(): query posMaster ทั้งหมดครั้งเดียว - สร้าง maps (orgRootMap, orgChild1Map, etc.) สำหรับ lookup - ลด queries จาก 1,000,000+ → ~10 queries 2. เพิ่ม import สำหรับ helper functions ใน OrganizationController.ts - import { getPositionCounts, getCounts, getRootCounts } - ต้อง replace ฟังก์ชัน detailSuperAdmin ด้วย optimized version - ดู OPTIMIZED_FUNCTION.ts สำหรับฟังก์ชันใหม่ ไฟล์ที่เพิ่ม: - src/controllers/OrganizationController-optimized.ts (helper functions) - OPTIMIZED_FUNCTION.ts (optimized function reference) - src/utils/log-memory-store.ts (from earlier log middleware fix) หมายเหตุ: ฟังก์ชัน detailSuperAdmin ใน OrganizationController.ts ยังไม่ถูก replace (ต้องทำ manual) - ดู OPTIMIZED_FUNCTION.ts Co-Authored-By: Claude (glm-4.7) <noreply@anthropic.com>
2026-01-28 13:45:52 +07:00
import { AppDataSource } from "../database/data-source";
import { OrgRevision } from "../entities/OrgRevision";
import { Profile } from "../entities/Profile";
import { PosMaster } from "../entities/PosMaster";
feat: optimize detailSuperAdmin API to fix database connection issue ปัญหา: API GET /api/v1/org/super-admin/{id} ทำให้ระบบดับเพราะ N+1 queries - เดิม: >1,000,000 queries (100 orgRoots × 10 children × 10 counts/level) - ใหม่: ~10 queries (query รวมครั้งเดียว + 5 org queries) การเปลี่ยนแปลง: 1. สร้าง OrganizationController-optimized.ts - getPositionCounts(): query posMaster ทั้งหมดครั้งเดียว - สร้าง maps (orgRootMap, orgChild1Map, etc.) สำหรับ lookup - ลด queries จาก 1,000,000+ → ~10 queries 2. เพิ่ม import สำหรับ helper functions ใน OrganizationController.ts - import { getPositionCounts, getCounts, getRootCounts } - ต้อง replace ฟังก์ชัน detailSuperAdmin ด้วย optimized version - ดู OPTIMIZED_FUNCTION.ts สำหรับฟังก์ชันใหม่ ไฟล์ที่เพิ่ม: - src/controllers/OrganizationController-optimized.ts (helper functions) - OPTIMIZED_FUNCTION.ts (optimized function reference) - src/utils/log-memory-store.ts (from earlier log middleware fix) หมายเหตุ: ฟังก์ชัน detailSuperAdmin ใน OrganizationController.ts ยังไม่ถูก replace (ต้องทำ manual) - ดู OPTIMIZED_FUNCTION.ts Co-Authored-By: Claude (glm-4.7) <noreply@anthropic.com>
2026-01-28 13:45:52 +07:00
interface LogCacheData {
currentRevision: OrgRevision | null;
profileCache: Map<string, Profile>; // keycloak → Profile
rootIdCache: Map<string, string>; // profileId → rootId
feat: optimize detailSuperAdmin API to fix database connection issue ปัญหา: API GET /api/v1/org/super-admin/{id} ทำให้ระบบดับเพราะ N+1 queries - เดิม: >1,000,000 queries (100 orgRoots × 10 children × 10 counts/level) - ใหม่: ~10 queries (query รวมครั้งเดียว + 5 org queries) การเปลี่ยนแปลง: 1. สร้าง OrganizationController-optimized.ts - getPositionCounts(): query posMaster ทั้งหมดครั้งเดียว - สร้าง maps (orgRootMap, orgChild1Map, etc.) สำหรับ lookup - ลด queries จาก 1,000,000+ → ~10 queries 2. เพิ่ม import สำหรับ helper functions ใน OrganizationController.ts - import { getPositionCounts, getCounts, getRootCounts } - ต้อง replace ฟังก์ชัน detailSuperAdmin ด้วย optimized version - ดู OPTIMIZED_FUNCTION.ts สำหรับฟังก์ชันใหม่ ไฟล์ที่เพิ่ม: - src/controllers/OrganizationController-optimized.ts (helper functions) - OPTIMIZED_FUNCTION.ts (optimized function reference) - src/utils/log-memory-store.ts (from earlier log middleware fix) หมายเหตุ: ฟังก์ชัน detailSuperAdmin ใน OrganizationController.ts ยังไม่ถูก replace (ต้องทำ manual) - ดู OPTIMIZED_FUNCTION.ts Co-Authored-By: Claude (glm-4.7) <noreply@anthropic.com>
2026-01-28 13:45:52 +07:00
updatedAt: Date;
}
class LogMemoryStore {
private cache: LogCacheData = {
currentRevision: null,
profileCache: new Map(),
rootIdCache: new Map(),
feat: optimize detailSuperAdmin API to fix database connection issue ปัญหา: API GET /api/v1/org/super-admin/{id} ทำให้ระบบดับเพราะ N+1 queries - เดิม: >1,000,000 queries (100 orgRoots × 10 children × 10 counts/level) - ใหม่: ~10 queries (query รวมครั้งเดียว + 5 org queries) การเปลี่ยนแปลง: 1. สร้าง OrganizationController-optimized.ts - getPositionCounts(): query posMaster ทั้งหมดครั้งเดียว - สร้าง maps (orgRootMap, orgChild1Map, etc.) สำหรับ lookup - ลด queries จาก 1,000,000+ → ~10 queries 2. เพิ่ม import สำหรับ helper functions ใน OrganizationController.ts - import { getPositionCounts, getCounts, getRootCounts } - ต้อง replace ฟังก์ชัน detailSuperAdmin ด้วย optimized version - ดู OPTIMIZED_FUNCTION.ts สำหรับฟังก์ชันใหม่ ไฟล์ที่เพิ่ม: - src/controllers/OrganizationController-optimized.ts (helper functions) - OPTIMIZED_FUNCTION.ts (optimized function reference) - src/utils/log-memory-store.ts (from earlier log middleware fix) หมายเหตุ: ฟังก์ชัน detailSuperAdmin ใน OrganizationController.ts ยังไม่ถูก replace (ต้องทำ manual) - ดู OPTIMIZED_FUNCTION.ts Co-Authored-By: Claude (glm-4.7) <noreply@anthropic.com>
2026-01-28 13:45:52 +07:00
updatedAt: new Date(),
};
private readonly CACHE_TTL = 60 * 60 * 1000; // 60 minutes
feat: optimize detailSuperAdmin API to fix database connection issue ปัญหา: API GET /api/v1/org/super-admin/{id} ทำให้ระบบดับเพราะ N+1 queries - เดิม: >1,000,000 queries (100 orgRoots × 10 children × 10 counts/level) - ใหม่: ~10 queries (query รวมครั้งเดียว + 5 org queries) การเปลี่ยนแปลง: 1. สร้าง OrganizationController-optimized.ts - getPositionCounts(): query posMaster ทั้งหมดครั้งเดียว - สร้าง maps (orgRootMap, orgChild1Map, etc.) สำหรับ lookup - ลด queries จาก 1,000,000+ → ~10 queries 2. เพิ่ม import สำหรับ helper functions ใน OrganizationController.ts - import { getPositionCounts, getCounts, getRootCounts } - ต้อง replace ฟังก์ชัน detailSuperAdmin ด้วย optimized version - ดู OPTIMIZED_FUNCTION.ts สำหรับฟังก์ชันใหม่ ไฟล์ที่เพิ่ม: - src/controllers/OrganizationController-optimized.ts (helper functions) - OPTIMIZED_FUNCTION.ts (optimized function reference) - src/utils/log-memory-store.ts (from earlier log middleware fix) หมายเหตุ: ฟังก์ชัน detailSuperAdmin ใน OrganizationController.ts ยังไม่ถูก replace (ต้องทำ manual) - ดู OPTIMIZED_FUNCTION.ts Co-Authored-By: Claude (glm-4.7) <noreply@anthropic.com>
2026-01-28 13:45:52 +07:00
private isInitialized = false;
constructor() {
// ไม่ refresh ทันที - รอให้เรียก initialize() หลัง TypeORM ready
}
// เริ่มต้น cache หลังจาก TypeORM initialize เสร็จ
initialize() {
if (this.isInitialized) {
console.log("[LogMemoryStore] Already initialized");
return;
}
this.isInitialized = true;
this.refreshCache();
console.log(
"[LogMemoryStore] Initialized with",
this.CACHE_TTL / 1000 / 60,
"minute TTL (passive cleanup on access)",
);
feat: optimize detailSuperAdmin API to fix database connection issue ปัญหา: API GET /api/v1/org/super-admin/{id} ทำให้ระบบดับเพราะ N+1 queries - เดิม: >1,000,000 queries (100 orgRoots × 10 children × 10 counts/level) - ใหม่: ~10 queries (query รวมครั้งเดียว + 5 org queries) การเปลี่ยนแปลง: 1. สร้าง OrganizationController-optimized.ts - getPositionCounts(): query posMaster ทั้งหมดครั้งเดียว - สร้าง maps (orgRootMap, orgChild1Map, etc.) สำหรับ lookup - ลด queries จาก 1,000,000+ → ~10 queries 2. เพิ่ม import สำหรับ helper functions ใน OrganizationController.ts - import { getPositionCounts, getCounts, getRootCounts } - ต้อง replace ฟังก์ชัน detailSuperAdmin ด้วย optimized version - ดู OPTIMIZED_FUNCTION.ts สำหรับฟังก์ชันใหม่ ไฟล์ที่เพิ่ม: - src/controllers/OrganizationController-optimized.ts (helper functions) - OPTIMIZED_FUNCTION.ts (optimized function reference) - src/utils/log-memory-store.ts (from earlier log middleware fix) หมายเหตุ: ฟังก์ชัน detailSuperAdmin ใน OrganizationController.ts ยังไม่ถูก replace (ต้องทำ manual) - ดู OPTIMIZED_FUNCTION.ts Co-Authored-By: Claude (glm-4.7) <noreply@anthropic.com>
2026-01-28 13:45:52 +07:00
}
private async refreshCache() {
try {
// Refresh revision cache
feat: optimize detailSuperAdmin API to fix database connection issue ปัญหา: API GET /api/v1/org/super-admin/{id} ทำให้ระบบดับเพราะ N+1 queries - เดิม: >1,000,000 queries (100 orgRoots × 10 children × 10 counts/level) - ใหม่: ~10 queries (query รวมครั้งเดียว + 5 org queries) การเปลี่ยนแปลง: 1. สร้าง OrganizationController-optimized.ts - getPositionCounts(): query posMaster ทั้งหมดครั้งเดียว - สร้าง maps (orgRootMap, orgChild1Map, etc.) สำหรับ lookup - ลด queries จาก 1,000,000+ → ~10 queries 2. เพิ่ม import สำหรับ helper functions ใน OrganizationController.ts - import { getPositionCounts, getCounts, getRootCounts } - ต้อง replace ฟังก์ชัน detailSuperAdmin ด้วย optimized version - ดู OPTIMIZED_FUNCTION.ts สำหรับฟังก์ชันใหม่ ไฟล์ที่เพิ่ม: - src/controllers/OrganizationController-optimized.ts (helper functions) - OPTIMIZED_FUNCTION.ts (optimized function reference) - src/utils/log-memory-store.ts (from earlier log middleware fix) หมายเหตุ: ฟังก์ชัน detailSuperAdmin ใน OrganizationController.ts ยังไม่ถูก replace (ต้องทำ manual) - ดู OPTIMIZED_FUNCTION.ts Co-Authored-By: Claude (glm-4.7) <noreply@anthropic.com>
2026-01-28 13:45:52 +07:00
const repoRevision = AppDataSource.getRepository(OrgRevision);
const revision = await repoRevision.findOne({
where: {
orgRevisionIsCurrent: true,
orgRevisionIsDraft: false,
},
});
this.cache.currentRevision = revision;
// Clear on-demand caches (they will be rebuilt as needed)
this.cache.profileCache.clear();
this.cache.rootIdCache.clear();
feat: optimize detailSuperAdmin API to fix database connection issue ปัญหา: API GET /api/v1/org/super-admin/{id} ทำให้ระบบดับเพราะ N+1 queries - เดิม: >1,000,000 queries (100 orgRoots × 10 children × 10 counts/level) - ใหม่: ~10 queries (query รวมครั้งเดียว + 5 org queries) การเปลี่ยนแปลง: 1. สร้าง OrganizationController-optimized.ts - getPositionCounts(): query posMaster ทั้งหมดครั้งเดียว - สร้าง maps (orgRootMap, orgChild1Map, etc.) สำหรับ lookup - ลด queries จาก 1,000,000+ → ~10 queries 2. เพิ่ม import สำหรับ helper functions ใน OrganizationController.ts - import { getPositionCounts, getCounts, getRootCounts } - ต้อง replace ฟังก์ชัน detailSuperAdmin ด้วย optimized version - ดู OPTIMIZED_FUNCTION.ts สำหรับฟังก์ชันใหม่ ไฟล์ที่เพิ่ม: - src/controllers/OrganizationController-optimized.ts (helper functions) - OPTIMIZED_FUNCTION.ts (optimized function reference) - src/utils/log-memory-store.ts (from earlier log middleware fix) หมายเหตุ: ฟังก์ชัน detailSuperAdmin ใน OrganizationController.ts ยังไม่ถูก replace (ต้องทำ manual) - ดู OPTIMIZED_FUNCTION.ts Co-Authored-By: Claude (glm-4.7) <noreply@anthropic.com>
2026-01-28 13:45:52 +07:00
this.cache.updatedAt = new Date();
console.log("[LogMemoryStore] Cache refreshed at", this.cache.updatedAt.toISOString());
feat: optimize detailSuperAdmin API to fix database connection issue ปัญหา: API GET /api/v1/org/super-admin/{id} ทำให้ระบบดับเพราะ N+1 queries - เดิม: >1,000,000 queries (100 orgRoots × 10 children × 10 counts/level) - ใหม่: ~10 queries (query รวมครั้งเดียว + 5 org queries) การเปลี่ยนแปลง: 1. สร้าง OrganizationController-optimized.ts - getPositionCounts(): query posMaster ทั้งหมดครั้งเดียว - สร้าง maps (orgRootMap, orgChild1Map, etc.) สำหรับ lookup - ลด queries จาก 1,000,000+ → ~10 queries 2. เพิ่ม import สำหรับ helper functions ใน OrganizationController.ts - import { getPositionCounts, getCounts, getRootCounts } - ต้อง replace ฟังก์ชัน detailSuperAdmin ด้วย optimized version - ดู OPTIMIZED_FUNCTION.ts สำหรับฟังก์ชันใหม่ ไฟล์ที่เพิ่ม: - src/controllers/OrganizationController-optimized.ts (helper functions) - OPTIMIZED_FUNCTION.ts (optimized function reference) - src/utils/log-memory-store.ts (from earlier log middleware fix) หมายเหตุ: ฟังก์ชัน detailSuperAdmin ใน OrganizationController.ts ยังไม่ถูก replace (ต้องทำ manual) - ดู OPTIMIZED_FUNCTION.ts Co-Authored-By: Claude (glm-4.7) <noreply@anthropic.com>
2026-01-28 13:45:52 +07:00
} catch (error) {
console.error("[LogMemoryStore] Error refreshing cache:", error);
}
}
// Check if cache is stale and refresh if needed
private async checkAndRefreshIfNeeded() {
const now = new Date();
const age = now.getTime() - this.cache.updatedAt.getTime();
if (age > this.CACHE_TTL) {
console.log(
"[LogMemoryStore] Cache is stale (age:",
Math.round(age / 1000 / 60),
"minutes), refreshing...",
);
await this.refreshCache();
feat: optimize detailSuperAdmin API to fix database connection issue ปัญหา: API GET /api/v1/org/super-admin/{id} ทำให้ระบบดับเพราะ N+1 queries - เดิม: >1,000,000 queries (100 orgRoots × 10 children × 10 counts/level) - ใหม่: ~10 queries (query รวมครั้งเดียว + 5 org queries) การเปลี่ยนแปลง: 1. สร้าง OrganizationController-optimized.ts - getPositionCounts(): query posMaster ทั้งหมดครั้งเดียว - สร้าง maps (orgRootMap, orgChild1Map, etc.) สำหรับ lookup - ลด queries จาก 1,000,000+ → ~10 queries 2. เพิ่ม import สำหรับ helper functions ใน OrganizationController.ts - import { getPositionCounts, getCounts, getRootCounts } - ต้อง replace ฟังก์ชัน detailSuperAdmin ด้วย optimized version - ดู OPTIMIZED_FUNCTION.ts สำหรับฟังก์ชันใหม่ ไฟล์ที่เพิ่ม: - src/controllers/OrganizationController-optimized.ts (helper functions) - OPTIMIZED_FUNCTION.ts (optimized function reference) - src/utils/log-memory-store.ts (from earlier log middleware fix) หมายเหตุ: ฟังก์ชัน detailSuperAdmin ใน OrganizationController.ts ยังไม่ถูก replace (ต้องทำ manual) - ดู OPTIMIZED_FUNCTION.ts Co-Authored-By: Claude (glm-4.7) <noreply@anthropic.com>
2026-01-28 13:45:52 +07:00
}
}
getCurrentRevision(): OrgRevision | null {
// Check for stale data (fire and forget)
this.checkAndRefreshIfNeeded();
feat: optimize detailSuperAdmin API to fix database connection issue ปัญหา: API GET /api/v1/org/super-admin/{id} ทำให้ระบบดับเพราะ N+1 queries - เดิม: >1,000,000 queries (100 orgRoots × 10 children × 10 counts/level) - ใหม่: ~10 queries (query รวมครั้งเดียว + 5 org queries) การเปลี่ยนแปลง: 1. สร้าง OrganizationController-optimized.ts - getPositionCounts(): query posMaster ทั้งหมดครั้งเดียว - สร้าง maps (orgRootMap, orgChild1Map, etc.) สำหรับ lookup - ลด queries จาก 1,000,000+ → ~10 queries 2. เพิ่ม import สำหรับ helper functions ใน OrganizationController.ts - import { getPositionCounts, getCounts, getRootCounts } - ต้อง replace ฟังก์ชัน detailSuperAdmin ด้วย optimized version - ดู OPTIMIZED_FUNCTION.ts สำหรับฟังก์ชันใหม่ ไฟล์ที่เพิ่ม: - src/controllers/OrganizationController-optimized.ts (helper functions) - OPTIMIZED_FUNCTION.ts (optimized function reference) - src/utils/log-memory-store.ts (from earlier log middleware fix) หมายเหตุ: ฟังก์ชัน detailSuperAdmin ใน OrganizationController.ts ยังไม่ถูก replace (ต้องทำ manual) - ดู OPTIMIZED_FUNCTION.ts Co-Authored-By: Claude (glm-4.7) <noreply@anthropic.com>
2026-01-28 13:45:52 +07:00
return this.cache.currentRevision;
}
getLastUpdateTime(): Date {
return this.cache.updatedAt;
}
/**
* Get Profile by keycloak ID with caching
*/
async getProfileByKeycloak(keycloak: string): Promise<Profile | null> {
// Check for stale data
await this.checkAndRefreshIfNeeded();
// Check cache first
if (this.cache.profileCache.has(keycloak)) {
return this.cache.profileCache.get(keycloak)!;
}
// Fetch from database
const repoProfile = AppDataSource.getRepository(Profile);
const profile = await repoProfile.findOne({
where: { keycloak },
});
// Cache the result
if (profile) {
this.cache.profileCache.set(keycloak, profile);
}
return profile;
}
/**
* Get RootId by profileId with caching
*/
async getRootIdByProfileId(profileId: string | undefined): Promise<string | null> {
if (!profileId) return null;
// Check for stale data
await this.checkAndRefreshIfNeeded();
// Check cache first
if (this.cache.rootIdCache.has(profileId)) {
return this.cache.rootIdCache.get(profileId)!;
}
// Fetch from database
const repoPosmaster = AppDataSource.getRepository(PosMaster);
const revision = this.getCurrentRevision();
//
const posMaster = await repoPosmaster.findOne({
where: {
current_holderId: profileId,
orgRevisionId: revision?.id,
},
relations: ["orgRoot"],
select: {
orgRoot: {
ancestorDNA: true,
},
},
});
const rootId = posMaster?.orgRoot?.ancestorDNA ?? null;
// Cache the result
if (rootId) {
this.cache.rootIdCache.set(profileId, rootId);
}
return rootId;
}
feat: optimize detailSuperAdmin API to fix database connection issue ปัญหา: API GET /api/v1/org/super-admin/{id} ทำให้ระบบดับเพราะ N+1 queries - เดิม: >1,000,000 queries (100 orgRoots × 10 children × 10 counts/level) - ใหม่: ~10 queries (query รวมครั้งเดียว + 5 org queries) การเปลี่ยนแปลง: 1. สร้าง OrganizationController-optimized.ts - getPositionCounts(): query posMaster ทั้งหมดครั้งเดียว - สร้าง maps (orgRootMap, orgChild1Map, etc.) สำหรับ lookup - ลด queries จาก 1,000,000+ → ~10 queries 2. เพิ่ม import สำหรับ helper functions ใน OrganizationController.ts - import { getPositionCounts, getCounts, getRootCounts } - ต้อง replace ฟังก์ชัน detailSuperAdmin ด้วย optimized version - ดู OPTIMIZED_FUNCTION.ts สำหรับฟังก์ชันใหม่ ไฟล์ที่เพิ่ม: - src/controllers/OrganizationController-optimized.ts (helper functions) - OPTIMIZED_FUNCTION.ts (optimized function reference) - src/utils/log-memory-store.ts (from earlier log middleware fix) หมายเหตุ: ฟังก์ชัน detailSuperAdmin ใน OrganizationController.ts ยังไม่ถูก replace (ต้องทำ manual) - ดู OPTIMIZED_FUNCTION.ts Co-Authored-By: Claude (glm-4.7) <noreply@anthropic.com>
2026-01-28 13:45:52 +07:00
// สำหรับ shutdown
destroy() {
// No active timer to clear
console.log("[LogMemoryStore] Destroyed");
feat: optimize detailSuperAdmin API to fix database connection issue ปัญหา: API GET /api/v1/org/super-admin/{id} ทำให้ระบบดับเพราะ N+1 queries - เดิม: >1,000,000 queries (100 orgRoots × 10 children × 10 counts/level) - ใหม่: ~10 queries (query รวมครั้งเดียว + 5 org queries) การเปลี่ยนแปลง: 1. สร้าง OrganizationController-optimized.ts - getPositionCounts(): query posMaster ทั้งหมดครั้งเดียว - สร้าง maps (orgRootMap, orgChild1Map, etc.) สำหรับ lookup - ลด queries จาก 1,000,000+ → ~10 queries 2. เพิ่ม import สำหรับ helper functions ใน OrganizationController.ts - import { getPositionCounts, getCounts, getRootCounts } - ต้อง replace ฟังก์ชัน detailSuperAdmin ด้วย optimized version - ดู OPTIMIZED_FUNCTION.ts สำหรับฟังก์ชันใหม่ ไฟล์ที่เพิ่ม: - src/controllers/OrganizationController-optimized.ts (helper functions) - OPTIMIZED_FUNCTION.ts (optimized function reference) - src/utils/log-memory-store.ts (from earlier log middleware fix) หมายเหตุ: ฟังก์ชัน detailSuperAdmin ใน OrganizationController.ts ยังไม่ถูก replace (ต้องทำ manual) - ดู OPTIMIZED_FUNCTION.ts Co-Authored-By: Claude (glm-4.7) <noreply@anthropic.com>
2026-01-28 13:45:52 +07:00
}
}
export const logMemoryStore = new LogMemoryStore();