fix: bug save posMasterHistory, tuning performance script

This commit is contained in:
Warunee Tamkoo 2026-02-12 13:16:43 +07:00
parent 9927c73547
commit ef17236eb0
3 changed files with 186 additions and 18 deletions

View file

@ -53,6 +53,7 @@ import {
} from "../keycloak";
// import { getPositionCounts, getCounts, getRootCounts } from "../services/OrganizationService";
import {
BatchSavePosMasterHistoryOfficer,
CreatePosMasterHistoryEmployee,
CreatePosMasterHistoryOfficer,
SavePosMasterHistoryOfficer,
@ -8062,9 +8063,26 @@ export class OrganizationController extends Controller {
// Clear current_holderId for positions that will have new holders
const nextHolderIds = posMasterDraft
.filter((x) => x.next_holderId != null)
.map((x) => x.next_holderId);
.map((x) => x.next_holderId) as string[];
if (nextHolderIds.length > 0) {
// FIX: Fetch positions first before updating (to avoid race condition)
const posMastersToUpdate = await queryRunner.manager.find(PosMaster, {
where: {
orgRevisionId: currentRevisionId,
current_holderId: In(nextHolderIds),
},
});
// Save history BEFORE clearing current_holderId
const historyOps = posMastersToUpdate.map((pos) => ({
posMasterDnaId: pos.ancestorDNA,
profileId: null,
pm: null,
}));
await BatchSavePosMasterHistoryOfficer(queryRunner, historyOps);
// Now clear current_holderId
await queryRunner.manager.update(
PosMaster,
{
@ -8112,11 +8130,12 @@ export class OrganizationController extends Controller {
// Then delete posMaster records
await queryRunner.manager.delete(PosMaster, toDeleteIds);
await Promise.all(
toDelete.map(async (pos) => {
await SavePosMasterHistoryOfficer(queryRunner, pos.ancestorDNA, null, null);
}),
);
const deleteHistoryOps = toDelete.map((pos) => ({
posMasterDnaId: pos.ancestorDNA,
profileId: null,
pm: null,
}));
await BatchSavePosMasterHistoryOfficer(queryRunner, deleteHistoryOps);
}
// 2.4 Process draft positions (UPDATE or INSERT)
@ -8705,17 +8724,18 @@ export class OrganizationController extends Controller {
// Bulk DELETE
if (allToDelete.length > 0) {
await queryRunner.manager.delete(Position, allToDelete);
await Promise.all(
allToDeleteHistory.map(async (ancestorDNA) => {
await SavePosMasterHistoryOfficer(queryRunner, ancestorDNA, null, null);
}),
);
const deleteOps = allToDeleteHistory.map((ancestorDNA) => ({
posMasterDnaId: ancestorDNA,
profileId: null,
pm: null,
}));
await BatchSavePosMasterHistoryOfficer(queryRunner, deleteOps);
deletedCount = allToDelete.length;
}
// Bulk UPDATE (batch by 500 to avoid query size limits)
// Bulk UPDATE (batch by 100 to avoid query size limits)
if (allToUpdate.length > 0) {
const batchSize = 500;
const batchSize = 100;
for (let i = 0; i < allToUpdate.length; i += batchSize) {
const batch = allToUpdate.slice(i, i + batchSize);
await Promise.all(
@ -8727,7 +8747,7 @@ export class OrganizationController extends Controller {
// Bulk INSERT
if (allToInsert.length > 0) {
const batchSize = 500;
const batchSize = 100;
for (let i = 0; i < allToInsert.length; i += batchSize) {
const batch = allToInsert.slice(i, i + batchSize);
await queryRunner.manager.save(Position, batch);
@ -8747,10 +8767,13 @@ export class OrganizationController extends Controller {
// Save PosMasterHistory for updated positions
if (historyCalls.length > 0) {
await Promise.all(
historyCalls.map(({ ancestorDNA, profileId, historyData }) =>
SavePosMasterHistoryOfficer(queryRunner, ancestorDNA, profileId, historyData),
),
await BatchSavePosMasterHistoryOfficer(
queryRunner,
historyCalls.map(({ ancestorDNA, profileId, historyData }) => ({
posMasterDnaId: ancestorDNA,
profileId,
pm: historyData,
})),
);
}