# Phase 4: Controller Layer Raw Query ์ „ํ™˜ ๊ณ„ํš ## ๐Ÿ“‹ ๊ฐœ์š” ์ปจํŠธ๋กค๋Ÿฌ ๋ ˆ์ด์–ด์— ๋‚จ์•„์žˆ๋Š” Prisma ํ˜ธ์ถœ์„ Raw Query๋กœ ์ „ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ์ปจํŠธ๋กค๋Ÿฌ๋Š” Service ๋ ˆ์ด์–ด๋ฅผ ํ˜ธ์ถœํ•˜์ง€๋งŒ, ์ผ๋ถ€ ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ์ง์ ‘ Prisma๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. --- ### ๐Ÿ“Š ๊ธฐ๋ณธ ์ •๋ณด | ํ•ญ๋ชฉ | ๋‚ด์šฉ | | --------------- | ---------------------------------- | | ๋Œ€์ƒ ํŒŒ์ผ | 7๊ฐœ ์ปจํŠธ๋กค๋Ÿฌ | | ํŒŒ์ผ ์œ„์น˜ | `backend-node/src/controllers/` | | Prisma ํ˜ธ์ถœ | 70๊ฐœ (28๊ฐœ ์™„๋ฃŒ) | | **ํ˜„์žฌ ์ง„ํ–‰๋ฅ ** | **28/70 (40%)** ๐Ÿ”„ **์ง„ํ–‰ ์ค‘** | | ๋ณต์žก๋„ | ์ค‘๊ฐ„ (๋Œ€๋ถ€๋ถ„ ๋‹จ์ˆœ CRUD) | | ์šฐ์„ ์ˆœ์œ„ | ๐ŸŸก ์ค‘๊ฐ„ (Phase 4) | | **์ƒํƒœ** | ๐Ÿ”„ **์ง„ํ–‰ ์ค‘** (adminController ์™„๋ฃŒ) | --- ## ๐ŸŽฏ ์ „ํ™˜ ๋Œ€์ƒ ์ปจํŠธ๋กค๋Ÿฌ ### 1. adminController.ts โœ… ์™„๋ฃŒ (28๊ฐœ) - **๋ผ์ธ ์ˆ˜**: 2,569 ๋ผ์ธ - **Prisma ํ˜ธ์ถœ**: 28๊ฐœ โ†’ 0๊ฐœ - **์ฃผ์š” ๊ธฐ๋Šฅ**: - ์‚ฌ์šฉ์ž ๊ด€๋ฆฌ (์กฐํšŒ, ์ƒ์„ฑ, ์ˆ˜์ •, ์‚ญ์ œ) โœ… - ํšŒ์‚ฌ ๊ด€๋ฆฌ (์กฐํšŒ, ์ƒ์„ฑ, ์ˆ˜์ •, ์‚ญ์ œ) โœ… - ๋ถ€์„œ ๊ด€๋ฆฌ (์กฐํšŒ) โœ… - ๋ฉ”๋‰ด ๊ด€๋ฆฌ (์ƒ์„ฑ, ์ˆ˜์ •, ์‚ญ์ œ) โœ… - ๋‹ค๊ตญ์–ด ํ‚ค ์กฐํšŒ โœ… - **์šฐ์„ ์ˆœ์œ„**: ๐Ÿ”ด ๋†’์Œ - **์ƒํƒœ**: โœ… **์™„๋ฃŒ** (2025-10-01) - **๋ฌธ์„œ**: [PHASE4.1_ADMIN_CONTROLLER_MIGRATION.md](PHASE4.1_ADMIN_CONTROLLER_MIGRATION.md) ### 2. webTypeStandardController.ts (11๊ฐœ) - **Prisma ํ˜ธ์ถœ**: 11๊ฐœ - **์ฃผ์š” ๊ธฐ๋Šฅ**: ์›นํƒ€์ž… ํ‘œ์ค€ ๊ด€๋ฆฌ - **์šฐ์„ ์ˆœ์œ„**: ๐ŸŸก ์ค‘๊ฐ„ ### 3. fileController.ts (11๊ฐœ) - **Prisma ํ˜ธ์ถœ**: 11๊ฐœ - **์ฃผ์š” ๊ธฐ๋Šฅ**: ํŒŒ์ผ ์—…๋กœ๋“œ/๋‹ค์šด๋กœ๋“œ ๊ด€๋ฆฌ - **์šฐ์„ ์ˆœ์œ„**: ๐ŸŸก ์ค‘๊ฐ„ ### 4. buttonActionStandardController.ts (11๊ฐœ) - **Prisma ํ˜ธ์ถœ**: 11๊ฐœ - **์ฃผ์š” ๊ธฐ๋Šฅ**: ๋ฒ„ํŠผ ์•ก์…˜ ํ‘œ์ค€ ๊ด€๋ฆฌ - **์šฐ์„ ์ˆœ์œ„**: ๐ŸŸก ์ค‘๊ฐ„ ### 5. entityReferenceController.ts (4๊ฐœ) - **Prisma ํ˜ธ์ถœ**: 4๊ฐœ - **์ฃผ์š” ๊ธฐ๋Šฅ**: ์—”ํ‹ฐํ‹ฐ ์ฐธ์กฐ ๊ด€๋ฆฌ - **์šฐ์„ ์ˆœ์œ„**: ๐ŸŸข ๋‚ฎ์Œ ### 6. dataflowExecutionController.ts (3๊ฐœ) - **Prisma ํ˜ธ์ถœ**: 3๊ฐœ - **์ฃผ์š” ๊ธฐ๋Šฅ**: ๋ฐ์ดํ„ฐํ”Œ๋กœ์šฐ ์‹คํ–‰ - **์šฐ์„ ์ˆœ์œ„**: ๐ŸŸข ๋‚ฎ์Œ ### 7. screenFileController.ts (2๊ฐœ) - **Prisma ํ˜ธ์ถœ**: 2๊ฐœ - **์ฃผ์š” ๊ธฐ๋Šฅ**: ํ™”๋ฉด ํŒŒ์ผ ๊ด€๋ฆฌ - **์šฐ์„ ์ˆœ์œ„**: ๐ŸŸข ๋‚ฎ์Œ --- ## ๐Ÿ“ ์ „ํ™˜ ์ „๋žต ### ๊ธฐ๋ณธ ์›์น™ 1. **Service Layer ์šฐ์„ ** - ๊ฐ€๋Šฅํ•˜๋ฉด Service๋กœ ๋กœ์ง ์ด๋™ - Controller๋Š” ์ตœ์†Œํ•œ์˜ ๋กœ์ง๋งŒ ์œ ์ง€ 2. **๋‹จ์ˆœ ์ „ํ™˜** - ๋Œ€๋ถ€๋ถ„ ๋‹จ์ˆœ CRUD โ†’ `query`, `queryOne` ์‚ฌ์šฉ - ๋ณต์žกํ•œ ๋กœ์ง์€ Service๋กœ ์ด๋™ 3. **์—๋Ÿฌ ์ฒ˜๋ฆฌ ์œ ์ง€** - ๊ธฐ์กด try-catch ๊ตฌ์กฐ ์œ ์ง€ - ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ์ผ๊ด€์„ฑ ์œ ์ง€ ### ์ „ํ™˜ ํŒจํ„ด #### 1. findMany โ†’ query ```typescript // Before const users = await prisma.user_info.findMany({ where: { company_code: companyCode }, }); // After const users = await query( `SELECT * FROM user_info WHERE company_code = $1`, [companyCode] ); ``` #### 2. findUnique โ†’ queryOne ```typescript // Before const user = await prisma.user_info.findUnique({ where: { user_id: userId }, }); // After const user = await queryOne( `SELECT * FROM user_info WHERE user_id = $1`, [userId] ); ``` #### 3. create โ†’ queryOne with INSERT ```typescript // Before const newUser = await prisma.user_info.create({ data: userData }); // After const newUser = await queryOne( `INSERT INTO user_info (user_id, user_name, ...) VALUES ($1, $2, ...) RETURNING *`, [userData.user_id, userData.user_name, ...] ); ``` #### 4. update โ†’ queryOne with UPDATE ```typescript // Before const updated = await prisma.user_info.update({ where: { user_id: userId }, data: updateData }); // After const updated = await queryOne( `UPDATE user_info SET user_name = $1, ... WHERE user_id = $2 RETURNING *`, [updateData.user_name, ..., userId] ); ``` #### 5. delete โ†’ query with DELETE ```typescript // Before await prisma.user_info.delete({ where: { user_id: userId }, }); // After await query(`DELETE FROM user_info WHERE user_id = $1`, [userId]); ``` #### 6. count โ†’ queryOne ```typescript // Before const count = await prisma.user_info.count({ where: { company_code: companyCode }, }); // After const result = await queryOne<{ count: number }>( `SELECT COUNT(*) as count FROM user_info WHERE company_code = $1`, [companyCode] ); const count = parseInt(result?.count?.toString() || "0", 10); ``` --- ## โœ… ์ฒดํฌ๋ฆฌ์ŠคํŠธ ### Phase 4.1: adminController.ts - [ ] Prisma import ์ œ๊ฑฐ - [ ] query, queryOne import ์ถ”๊ฐ€ - [ ] ์‚ฌ์šฉ์ž ๊ด€๋ฆฌ ํ•จ์ˆ˜ ์ „ํ™˜ (8๊ฐœ) - [ ] getUserList - count + findMany - [ ] getUserInfo - findFirst - [ ] updateUserStatus - update - [ ] deleteUserByAdmin - update - [ ] getMyProfile - findUnique - [ ] updateMyProfile - update - [ ] createOrUpdateUser - upsert - [ ] count (getUserList) - [ ] ํšŒ์‚ฌ ๊ด€๋ฆฌ ํ•จ์ˆ˜ ์ „ํ™˜ (7๊ฐœ) - [ ] getCompanyList - findMany - [ ] createCompany - findFirst (์ค‘๋ณต์ฒดํฌ) + create - [ ] updateCompany - findFirst (์ค‘๋ณต์ฒดํฌ) + update - [ ] deleteCompany - findUnique + delete - [ ] ๋ถ€์„œ ๊ด€๋ฆฌ ํ•จ์ˆ˜ ์ „ํ™˜ (2๊ฐœ) - [ ] getDepartmentList - findMany - [ ] findUnique (๋ถ€์„œ ์กฐํšŒ) - [ ] ๋ฉ”๋‰ด ๊ด€๋ฆฌ ํ•จ์ˆ˜ ์ „ํ™˜ (3๊ฐœ) - [ ] createMenu - create - [ ] updateMenu - update - [ ] deleteMenu - delete - [ ] ๊ธฐํƒ€ ํ•จ์ˆ˜ ์ „ํ™˜ (8๊ฐœ) - [ ] getMultiLangKeys - findMany - [ ] ์ปดํŒŒ์ผ ํ™•์ธ - [ ] ๋ฆฐํ„ฐ ํ™•์ธ ### Phase 4.2: webTypeStandardController.ts - [ ] Prisma import ์ œ๊ฑฐ - [ ] query, queryOne import ์ถ”๊ฐ€ - [ ] ๋ชจ๋“  ํ•จ์ˆ˜ ์ „ํ™˜ (11๊ฐœ) - [ ] ์ปดํŒŒ์ผ ํ™•์ธ - [ ] ๋ฆฐํ„ฐ ํ™•์ธ ### Phase 4.3: fileController.ts - [ ] Prisma import ์ œ๊ฑฐ - [ ] query, queryOne import ์ถ”๊ฐ€ - [ ] ๋ชจ๋“  ํ•จ์ˆ˜ ์ „ํ™˜ (11๊ฐœ) - [ ] ์ปดํŒŒ์ผ ํ™•์ธ - [ ] ๋ฆฐํ„ฐ ํ™•์ธ ### Phase 4.4: buttonActionStandardController.ts - [ ] Prisma import ์ œ๊ฑฐ - [ ] query, queryOne import ์ถ”๊ฐ€ - [ ] ๋ชจ๋“  ํ•จ์ˆ˜ ์ „ํ™˜ (11๊ฐœ) - [ ] ์ปดํŒŒ์ผ ํ™•์ธ - [ ] ๋ฆฐํ„ฐ ํ™•์ธ ### Phase 4.5: entityReferenceController.ts - [ ] Prisma import ์ œ๊ฑฐ - [ ] query, queryOne import ์ถ”๊ฐ€ - [ ] ๋ชจ๋“  ํ•จ์ˆ˜ ์ „ํ™˜ (4๊ฐœ) - [ ] ์ปดํŒŒ์ผ ํ™•์ธ - [ ] ๋ฆฐํ„ฐ ํ™•์ธ ### Phase 4.6: dataflowExecutionController.ts - [ ] Prisma import ์ œ๊ฑฐ - [ ] query, queryOne import ์ถ”๊ฐ€ - [ ] ๋ชจ๋“  ํ•จ์ˆ˜ ์ „ํ™˜ (3๊ฐœ) - [ ] ์ปดํŒŒ์ผ ํ™•์ธ - [ ] ๋ฆฐํ„ฐ ํ™•์ธ ### Phase 4.7: screenFileController.ts - [ ] Prisma import ์ œ๊ฑฐ - [ ] query, queryOne import ์ถ”๊ฐ€ - [ ] ๋ชจ๋“  ํ•จ์ˆ˜ ์ „ํ™˜ (2๊ฐœ) - [ ] ์ปดํŒŒ์ผ ํ™•์ธ - [ ] ๋ฆฐํ„ฐ ํ™•์ธ --- ## ๐ŸŽฏ ์˜ˆ์ƒ ๊ฒฐ๊ณผ ### ์ฝ”๋“œ ํ’ˆ์งˆ - โœ… Prisma ์˜์กด์„ฑ ์™„์ „ ์ œ๊ฑฐ - โœ… ์ง์ ‘์ ์ธ SQL ์ œ์–ด - โœ… ํƒ€์ž… ์•ˆ์ „์„ฑ ์œ ์ง€ ### ์„ฑ๋Šฅ - โœ… ๋ถˆํ•„์š”ํ•œ ORM ์˜ค๋ฒ„ํ—ค๋“œ ์ œ๊ฑฐ - โœ… ์ฟผ๋ฆฌ ์ตœ์ ํ™” ๊ฐ€๋Šฅ ### ์œ ์ง€๋ณด์ˆ˜์„ฑ - โœ… ๋ช…ํ™•ํ•œ SQL ์ฟผ๋ฆฌ - โœ… ๋””๋ฒ„๊น… ์šฉ์ด - โœ… ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์šฉ์ด --- ## ๐Ÿ“Œ ์ฐธ๊ณ ์‚ฌํ•ญ ### Import ๋ณ€๊ฒฝ ```typescript // Before import { PrismaClient } from "@prisma/client"; const prisma = new PrismaClient(); // After import { query, queryOne } from "../database/db"; ``` ### ํƒ€์ž… ์ •์˜ - ๊ฐ ํ…Œ์ด๋ธ”์˜ ํƒ€์ž…์€ `types/` ๋””๋ ‰ํ† ๋ฆฌ์—์„œ import - ํ•„์š”์‹œ ์ƒˆ๋กœ์šด ํƒ€์ž… ์ •์˜ ์ถ”๊ฐ€ ### ์—๋Ÿฌ ์ฒ˜๋ฆฌ - ๊ธฐ์กด try-catch ๊ตฌ์กฐ ์œ ์ง€ - ์ ์ ˆํ•œ HTTP ์ƒํƒœ ์ฝ”๋“œ ๋ฐ˜ํ™˜ - ์‚ฌ์šฉ์ž ์นœํ™”์  ์—๋Ÿฌ ๋ฉ”์‹œ์ง€