7.3 KiB
7.3 KiB
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
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개
- 주요 기능: 화면 파일 관리
- 우선순위: 🟢 낮음
📝 전환 전략
기본 원칙
-
Service Layer 우선
- 가능하면 Service로 로직 이동
- Controller는 최소한의 로직만 유지
-
단순 전환
- 대부분 단순 CRUD →
query,queryOne사용 - 복잡한 로직은 Service로 이동
- 대부분 단순 CRUD →
-
에러 처리 유지
- 기존 try-catch 구조 유지
- 에러 메시지 일관성 유지
전환 패턴
1. findMany → query
// Before
const users = await prisma.user_info.findMany({
where: { company_code: companyCode },
});
// After
const users = await query<UserInfo>(
`SELECT * FROM user_info WHERE company_code = $1`,
[companyCode]
);
2. findUnique → queryOne
// Before
const user = await prisma.user_info.findUnique({
where: { user_id: userId },
});
// After
const user = await queryOne<UserInfo>(
`SELECT * FROM user_info WHERE user_id = $1`,
[userId]
);
3. create → queryOne with INSERT
// Before
const newUser = await prisma.user_info.create({
data: userData
});
// After
const newUser = await queryOne<UserInfo>(
`INSERT INTO user_info (user_id, user_name, ...)
VALUES ($1, $2, ...) RETURNING *`,
[userData.user_id, userData.user_name, ...]
);
4. update → queryOne with UPDATE
// Before
const updated = await prisma.user_info.update({
where: { user_id: userId },
data: updateData
});
// After
const updated = await queryOne<UserInfo>(
`UPDATE user_info SET user_name = $1, ...
WHERE user_id = $2 RETURNING *`,
[updateData.user_name, ..., userId]
);
5. delete → query with DELETE
// 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
// 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 변경
// Before
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
// After
import { query, queryOne } from "../database/db";
타입 정의
- 각 테이블의 타입은
types/디렉토리에서 import - 필요시 새로운 타입 정의 추가
에러 처리
- 기존 try-catch 구조 유지
- 적절한 HTTP 상태 코드 반환
- 사용자 친화적 에러 메시지