Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 34 additions & 21 deletions src/services/changeWellItemOrderBulk.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { handleSqlError } from '@frolog/express-api-server';
export default async function changeWellItemOrderBulk(reqDto, user) {
const t = await mysql.transaction();
try {
// (1) ID 디코딩 및 유효성 검사
const wellId = decodeHashId(reqDto.well_id);
const userId = decodeHashId(user.id);

Expand All @@ -35,7 +36,7 @@ export default async function changeWellItemOrderBulk(reqDto, user) {
};
}

// (1) 우물 존재 및 권한 확인
// (2) 우물 존재 및 권한 확인
const well = await Well.findByPk(wellId).catch(handleSqlError);
if (!well) {
await t.rollback();
Expand All @@ -46,7 +47,7 @@ export default async function changeWellItemOrderBulk(reqDto, user) {
return { result: false, message: 'Unauthorized access.' };
}

// (2) 전체 아이템 조회
// (3) 기존 우물 아이템 전체 조회
const allItems = await WellItem.findAll({
where: { well_id: wellId },
order: [['order', 'ASC']],
Expand All @@ -61,51 +62,62 @@ export default async function changeWellItemOrderBulk(reqDto, user) {
};
}

// (3) 요청 대상 분리
// (4) 고정 순서 맵 구성
const fixedMap = new Map();
const fixedSet = new Set();
for (const { id, order } of changes) {
if (fixedMap.has(order)) {
await t.rollback();
return {
result: false,
message: `Duplicate order ${order} in changes.`,
};
}
fixedMap.set(order, id);
fixedSet.add(id);
}

const restItems = allItems.filter((item) => !fixedSet.has(item.id));
const newOrderList = Array(allItems.length);
let restIdx = 0;
// (5) 나머지 아이템 필터링
const fixedIds = new Set(changes.map((c) => c.id));
const remainingItems = allItems.filter(
(item) => !fixedIds.has(item.item_id),
);

for (let i = 0; i < newOrderList.length; i++) {
// (6) 순서대로 배치할 새 배열 구성
const totalLength = allItems.length;
const newOrderList = Array(totalLength);
let remainIdx = 0;

for (let i = 0; i < totalLength; i++) {
const fixedId = fixedMap.get(i);
if (fixedId != null) {
const item = allItems.find((item) => item.item_id === fixedId);
if (!item) {
const found = allItems.find((item) => item.item_id === fixedId);
if (!found) {
await t.rollback();
return {
result: false,
message: `Item with ID ${fixedId} not found among existing items.`,
message: `Item with ID ${fixedId} not found.`,
};
}
newOrderList[i] = item;
newOrderList[i] = found;
} else {
if (restIdx >= restItems.length) {
if (remainIdx >= remainingItems.length) {
await t.rollback();
return {
result: false,
message:
'Mismatch between expected and available items.',
message: 'Mismatch in remaining item distribution.',
};
}
newOrderList[i] = restItems[restIdx++];
newOrderList[i] = remainingItems[remainIdx++];
}
}

// (4) 실제 update 수행
// (7) 실제 DB 업데이트 수행
for (let i = 0; i < newOrderList.length; i++) {
const item = newOrderList[i];
if (!item) {
await t.rollback();
return {
result: false,
message: `Item missing at index ${i} in new order list.`,
message: `Missing item at index ${i}.`,
};
}

Expand All @@ -114,14 +126,15 @@ export default async function changeWellItemOrderBulk(reqDto, user) {
}
}

// (8) 트랜잭션 커밋
await t.commit();
return { result: true };
} catch (err) {
console.error('[changeWellItemOrderBulk] Error occurred:', err);
console.error('[changeWellItemOrderBulk] Error:', err);
await t.rollback();
return {
result: false,
message: 'Failed to reorder well items due to unexpected error.',
message: 'Unexpected error occurred while reordering items.',
};
}
}