From 13c1bc48ded92fe6666ab0e6c299b2028404f8d0 Mon Sep 17 00:00:00 2001 From: kjs Date: Tue, 30 Sep 2025 16:25:27 +0900 Subject: [PATCH] feat: Phase 2.1 Stage 1 complete - Basic CRUD converted (6/46) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stage 1 완료: 기본 CRUD Raw Query 전환 ✅ 전환 완료 (6개): 1. createScreen() - 화면 생성 (중복확인 + INSERT) 2. getScreensByCompany() - 목록 조회 (페이징 + 동적 WHERE) 3. getScreenById() - ID로 조회 4. updateScreen() - 화면 수정 (권한확인 + UPDATE) 5. deleteScreen() - 소프트 삭제 (트랜잭션) 6. getScreenByCode() - 코드로 조회 📊 진행률: 6/46 (13%) 🎯 다음: Stage 1 나머지 조회 함수 (getScreens, getAllScreens) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../src/services/screenManagementService.ts | 116 ++++++++++-------- 1 file changed, 64 insertions(+), 52 deletions(-) diff --git a/backend-node/src/services/screenManagementService.ts b/backend-node/src/services/screenManagementService.ts index 3d05e253..777ab6ae 100644 --- a/backend-node/src/services/screenManagementService.ts +++ b/backend-node/src/services/screenManagementService.ts @@ -195,17 +195,17 @@ export class ScreenManagementService { } /** - * 화면 정의 조회 (활성 화면만) + * 화면 정의 조회 (활성 화면만) (✅ Raw Query 전환 완료) */ async getScreenById(screenId: number): Promise { - const screen = await prisma.screen_definitions.findFirst({ - where: { - screen_id: screenId, - is_active: { not: "D" }, // 삭제된 화면 제외 - }, - }); + const screens = await query( + `SELECT * FROM screen_definitions + WHERE screen_id = $1 AND is_active != 'D' + LIMIT 1`, + [screenId] + ); - return screen ? this.mapToScreenDefinition(screen) : null; + return screens.length > 0 ? this.mapToScreenDefinition(screens[0]) : null; } /** @@ -233,22 +233,25 @@ export class ScreenManagementService { } /** - * 화면 정의 수정 + * 화면 정의 수정 (✅ Raw Query 전환 완료) */ async updateScreen( screenId: number, updateData: UpdateScreenRequest, userCompanyCode: string ): Promise { - // 권한 확인 - const existingScreen = await prisma.screen_definitions.findUnique({ - where: { screen_id: screenId }, - }); + // 권한 확인 (Raw Query) + const existingResult = await query<{ company_code: string | null }>( + `SELECT company_code FROM screen_definitions WHERE screen_id = $1 LIMIT 1`, + [screenId] + ); - if (!existingScreen) { + if (existingResult.length === 0) { throw new Error("화면을 찾을 수 없습니다."); } + const existingScreen = existingResult[0]; + if ( userCompanyCode !== "*" && existingScreen.company_code !== userCompanyCode @@ -256,16 +259,25 @@ export class ScreenManagementService { throw new Error("이 화면을 수정할 권한이 없습니다."); } - const screen = await prisma.screen_definitions.update({ - where: { screen_id: screenId }, - data: { - screen_name: updateData.screenName, - description: updateData.description, - is_active: updateData.isActive ? "Y" : "N", - updated_by: updateData.updatedBy, - updated_date: new Date(), - }, - }); + // 화면 업데이트 (Raw Query) + const [screen] = await query( + `UPDATE screen_definitions + SET screen_name = $1, + description = $2, + is_active = $3, + updated_by = $4, + updated_date = $5 + WHERE screen_id = $6 + RETURNING *`, + [ + updateData.screenName, + updateData.description || null, + updateData.isActive ? "Y" : "N", + updateData.updatedBy, + new Date(), + screenId, + ] + ); return this.mapToScreenDefinition(screen); } @@ -496,7 +508,7 @@ export class ScreenManagementService { } /** - * 화면 정의 삭제 (휴지통으로 이동 - 소프트 삭제) + * 화면 정의 삭제 (휴지통으로 이동 - 소프트 삭제) (✅ Raw Query 전환 완료) */ async deleteScreen( screenId: number, @@ -505,15 +517,18 @@ export class ScreenManagementService { deleteReason?: string, force: boolean = false ): Promise { - // 권한 확인 - const existingScreen = await prisma.screen_definitions.findUnique({ - where: { screen_id: screenId }, - }); + // 권한 확인 (Raw Query) + const existingResult = await query<{ company_code: string | null; is_active: string }>( + `SELECT company_code, is_active FROM screen_definitions WHERE screen_id = $1 LIMIT 1`, + [screenId] + ); - if (!existingScreen) { + if (existingResult.length === 0) { throw new Error("화면을 찾을 수 없습니다."); } + const existingScreen = existingResult[0]; + if ( userCompanyCode !== "*" && existingScreen.company_code !== userCompanyCode @@ -540,31 +555,28 @@ export class ScreenManagementService { } } - // 트랜잭션으로 화면 삭제와 메뉴 할당 정리를 함께 처리 - await prisma.$transaction(async (tx) => { + // 트랜잭션으로 화면 삭제와 메뉴 할당 정리를 함께 처리 (Raw Query) + await transaction(async (client) => { // 소프트 삭제 (휴지통으로 이동) - await tx.screen_definitions.update({ - where: { screen_id: screenId }, - data: { - is_active: "D", - deleted_date: new Date(), - deleted_by: deletedBy, - delete_reason: deleteReason, - updated_date: new Date(), - updated_by: deletedBy, - }, - }); + await client.query( + `UPDATE screen_definitions + SET is_active = 'D', + deleted_date = $1, + deleted_by = $2, + delete_reason = $3, + updated_date = $4, + updated_by = $5 + WHERE screen_id = $6`, + [new Date(), deletedBy, deleteReason || null, new Date(), deletedBy, screenId] + ); // 메뉴 할당도 비활성화 - await tx.screen_menu_assignments.updateMany({ - where: { - screen_id: screenId, - is_active: "Y", - }, - data: { - is_active: "N", - }, - }); + await client.query( + `UPDATE screen_menu_assignments + SET is_active = 'N' + WHERE screen_id = $1 AND is_active = 'Y'`, + [screenId] + ); }); }