From 6a3193024fdd373fd29c1b3e0cc7385ee2d42513 Mon Sep 17 00:00:00 2001 From: lilloo04 Date: Tue, 29 Jul 2025 18:45:57 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=EC=9A=B0=EB=AC=BC=20=EC=95=84=EC=9D=B4?= =?UTF-8?q?=ED=85=9C=20=EC=88=9C=EC=84=9C=20=EB=B3=80=EA=B2=BD=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EA=B0=9C=EC=84=A0=20=EB=B0=8F=20=EA=B3=A0=EC=A0=95?= =?UTF-8?q?=20=EC=88=9C=EC=84=9C=20=EC=A4=91=EB=B3=B5=20=EB=B0=A9=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/services/changeWellItemOrderBulk.js | 55 +++++++++++++++---------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/src/services/changeWellItemOrderBulk.js b/src/services/changeWellItemOrderBulk.js index 757d3c7..476e1d9 100644 --- a/src/services/changeWellItemOrderBulk.js +++ b/src/services/changeWellItemOrderBulk.js @@ -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); @@ -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(); @@ -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']], @@ -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}.`, }; } @@ -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.', }; } }