add script delete org old

This commit is contained in:
Warunee Tamkoo 2026-05-20 17:51:15 +07:00
parent a28c099f86
commit 9a5184bb55
2 changed files with 259 additions and 0 deletions

View file

@ -0,0 +1,27 @@
import "dotenv/config";
import "reflect-metadata";
import { AppDataSource } from "../database/data-source";
import { clearOldOrgRevisionData } from "../services/ClearOldOrgRevisionService";
// "clear:old-org-revision": "ts-node src/scripts/ClearOldOrgRevision.ts",
const defaultOrgRevisionId = "24dacf63-d289-496c-8102-8b25079dbaf2";
async function main(): Promise<void> {
const orgRevisionId = process.argv[2] || defaultOrgRevisionId;
try {
await AppDataSource.initialize();
const result = await clearOldOrgRevisionData(orgRevisionId);
console.info(JSON.stringify(result, null, 2));
} catch (error) {
console.error("[ClearOldOrgRevision] Failed:", error);
process.exitCode = 1;
} finally {
if (AppDataSource.isInitialized) {
await AppDataSource.destroy();
}
}
}
void main();

View file

@ -0,0 +1,232 @@
import { EntityManager, EntityTarget, In } from "typeorm";
import { AppDataSource } from "../database/data-source";
import { OrgRevision } from "../entities/OrgRevision";
import { PosMaster } from "../entities/PosMaster";
import { Position } from "../entities/Position";
import { OrgRoot } from "../entities/OrgRoot";
import { OrgChild1 } from "../entities/OrgChild1";
import { OrgChild2 } from "../entities/OrgChild2";
import { OrgChild3 } from "../entities/OrgChild3";
import { OrgChild4 } from "../entities/OrgChild4";
import { PosMasterAct } from "../entities/PosMasterAct";
import { PosMasterAssign } from "../entities/PosMasterAssign";
import { PermissionOrg } from "../entities/PermissionOrg";
import { PermissionProfile } from "../entities/PermissionProfile";
import { EmployeePosMaster } from "../entities/EmployeePosMaster";
import { EmployeeTempPosMaster } from "../entities/EmployeeTempPosMaster";
import { EmployeePosition } from "../entities/EmployeePosition";
import { orgStructureCache } from "../utils/OrgStructureCache";
export interface ClearOldOrgRevisionSummary {
orgRevisionId: string;
orgRevisionName: string;
deleted: {
positions: number;
employeePositionsByPosMaster: number;
employeePositionsByTempPosMaster: number;
posMasterActsByParent: number;
posMasterActsByChild: number;
posMasterAssigns: number;
posMasters: number;
employeePosMasters: number;
employeeTempPosMasters: number;
permissionOrgs: number;
permissionProfiles: number;
orgChild4s: number;
orgChild3s: number;
orgChild2s: number;
orgChild1s: number;
orgRoots: number;
orgRevisions: number;
};
}
interface OrgRevisionSnapshot {
id: string;
orgRevisionName: string;
orgRevisionIsCurrent: boolean;
orgRevisionIsDraft: boolean;
}
export async function clearOldOrgRevisionData(
orgRevisionId: string,
): Promise<ClearOldOrgRevisionSummary> {
const result = await AppDataSource.transaction(async (manager) => {
const orgRevision = await manager.findOne(OrgRevision, {
where: { id: orgRevisionId },
select: ["id", "orgRevisionName", "orgRevisionIsCurrent", "orgRevisionIsDraft"],
});
if (!orgRevision) {
throw new Error(`ไม่พบ orgRevision ที่ต้องการล้างข้อมูล: ${orgRevisionId}`);
}
validateOrgRevisionForDeletion(orgRevision);
const [posMasters, orgRoots, employeePosMasters, employeeTempPosMasters] = await Promise.all([
manager.find(PosMaster, {
where: { orgRevisionId },
select: ["id"],
}),
manager.find(OrgRoot, {
where: { orgRevisionId },
select: ["id"],
}),
manager.find(EmployeePosMaster, {
where: { orgRevisionId },
select: ["id"],
}),
manager.find(EmployeeTempPosMaster, {
where: { orgRevisionId },
select: ["id"],
}),
]);
const posMasterIds = posMasters.map((item) => item.id);
const orgRootIds = orgRoots.map((item) => item.id);
const employeePosMasterIds = employeePosMasters.map((item) => item.id);
const employeeTempPosMasterIds = employeeTempPosMasters.map((item) => item.id);
const [
positionsCount,
employeePositionsByPosMasterCount,
employeePositionsByTempPosMasterCount,
posMasterActsByParentCount,
posMasterActsByChildCount,
posMasterAssignsCount,
permissionOrgsCount,
permissionProfilesCount,
orgChild4sCount,
orgChild3sCount,
orgChild2sCount,
orgChild1sCount,
] = await Promise.all([
countByIds(manager, Position, "posMasterId", posMasterIds),
countByIds(manager, EmployeePosition, "posMasterId", employeePosMasterIds),
countByIds(manager, EmployeePosition, "posMasterTempId", employeeTempPosMasterIds),
countByIds(manager, PosMasterAct, "posMasterId", posMasterIds),
countByIds(manager, PosMasterAct, "posMasterChildId", posMasterIds),
countByIds(manager, PosMasterAssign, "posMasterId", posMasterIds),
countByIds(manager, PermissionOrg, "orgRootId", orgRootIds),
countByIds(manager, PermissionProfile, "orgRootId", orgRootIds),
manager.count(OrgChild4, { where: { orgRevisionId } }),
manager.count(OrgChild3, { where: { orgRevisionId } }),
manager.count(OrgChild2, { where: { orgRevisionId } }),
manager.count(OrgChild1, { where: { orgRevisionId } }),
]);
if (positionsCount > 0) {
await manager.delete(Position, { posMasterId: In(posMasterIds) });
}
if (employeePositionsByPosMasterCount > 0) {
await manager.delete(EmployeePosition, { posMasterId: In(employeePosMasterIds) });
}
if (employeePositionsByTempPosMasterCount > 0) {
await manager.delete(EmployeePosition, { posMasterTempId: In(employeeTempPosMasterIds) });
}
if (posMasterActsByParentCount > 0) {
await manager.delete(PosMasterAct, { posMasterId: In(posMasterIds) });
}
if (posMasterActsByChildCount > 0) {
await manager.delete(PosMasterAct, { posMasterChildId: In(posMasterIds) });
}
if (posMasterAssignsCount > 0) {
await manager.delete(PosMasterAssign, { posMasterId: In(posMasterIds) });
}
const posMastersCount = posMasterIds.length;
const employeePosMastersCount = employeePosMasterIds.length;
const employeeTempPosMastersCount = employeeTempPosMasterIds.length;
if (posMastersCount > 0) {
await manager.delete(PosMaster, { orgRevisionId });
}
if (employeePosMastersCount > 0) {
await manager.delete(EmployeePosMaster, { orgRevisionId });
}
if (employeeTempPosMastersCount > 0) {
await manager.delete(EmployeeTempPosMaster, { orgRevisionId });
}
if (permissionOrgsCount > 0) {
await manager.delete(PermissionOrg, { orgRootId: In(orgRootIds) });
}
if (permissionProfilesCount > 0) {
await manager.delete(PermissionProfile, { orgRootId: In(orgRootIds) });
}
if (orgChild4sCount > 0) {
await manager.delete(OrgChild4, { orgRevisionId });
}
if (orgChild3sCount > 0) {
await manager.delete(OrgChild3, { orgRevisionId });
}
if (orgChild2sCount > 0) {
await manager.delete(OrgChild2, { orgRevisionId });
}
if (orgChild1sCount > 0) {
await manager.delete(OrgChild1, { orgRevisionId });
}
const orgRootsCount = orgRootIds.length;
if (orgRootsCount > 0) {
await manager.delete(OrgRoot, { orgRevisionId });
}
await manager.delete(OrgRevision, { id: orgRevisionId });
return {
orgRevisionId: orgRevision.id,
orgRevisionName: orgRevision.orgRevisionName,
deleted: {
positions: positionsCount,
employeePositionsByPosMaster: employeePositionsByPosMasterCount,
employeePositionsByTempPosMaster: employeePositionsByTempPosMasterCount,
posMasterActsByParent: posMasterActsByParentCount,
posMasterActsByChild: posMasterActsByChildCount,
posMasterAssigns: posMasterAssignsCount,
posMasters: posMastersCount,
employeePosMasters: employeePosMastersCount,
employeeTempPosMasters: employeeTempPosMastersCount,
permissionOrgs: permissionOrgsCount,
permissionProfiles: permissionProfilesCount,
orgChild4s: orgChild4sCount,
orgChild3s: orgChild3sCount,
orgChild2s: orgChild2sCount,
orgChild1s: orgChild1sCount,
orgRoots: orgRootsCount,
orgRevisions: 1,
},
};
});
orgStructureCache.invalidate(orgRevisionId);
return result;
}
function validateOrgRevisionForDeletion(orgRevision: OrgRevisionSnapshot): void {
if (orgRevision.orgRevisionIsCurrent) {
throw new Error(`ไม่สามารถลบ orgRevision ปัจจุบันได้: ${orgRevision.id}`);
}
if (orgRevision.orgRevisionIsDraft) {
throw new Error(`ไม่สามารถลบ orgRevision แบบร่างได้ด้วยสคริปต์นี้: ${orgRevision.id}`);
}
}
async function countByIds<Entity extends object>(
manager: EntityManager,
entity: EntityTarget<Entity>,
field: keyof Entity,
ids: string[],
): Promise<number> {
if (ids.length === 0) {
return 0;
}
const alias = "entity";
return manager
.createQueryBuilder(entity, alias)
.where(`${alias}.${String(field)} IN (:...ids)`, { ids })
.getCount();
}