From 381d19caeef7c71b9d468e681933a11f61db3b50 Mon Sep 17 00:00:00 2001 From: kjs Date: Wed, 1 Oct 2025 13:42:56 +0900 Subject: [PATCH] =?UTF-8?q?docs:=20Phase=204=20=EC=BB=A8=ED=8A=B8=EB=A1=A4?= =?UTF-8?q?=EB=9F=AC=20=EB=A0=88=EC=9D=B4=EC=96=B4=20=EB=A7=88=EC=9D=B4?= =?UTF-8?q?=EA=B7=B8=EB=A0=88=EC=9D=B4=EC=85=98=20=EA=B3=84=ED=9A=8D?= =?UTF-8?q?=EC=84=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 남은 70개 Prisma 호출 분석 및 계획: 컨트롤러별 호출 수: - adminController.ts (28개) - webTypeStandardController.ts (11개) - fileController.ts (11개) - buttonActionStandardController.ts (11개) - entityReferenceController.ts (4개) - dataflowExecutionController.ts (3개) - screenFileController.ts (2개) 계획서: - PHASE4_CONTROLLER_LAYER_MIGRATION.md (통합) - PHASE4.1_ADMIN_CONTROLLER_MIGRATION.md (상세) 특징: 대부분 단순 CRUD 전략: Service Layer 이동 고려 --- PHASE4.1_ADMIN_CONTROLLER_MIGRATION.md | 385 +++++++++++++++++++++++++ PHASE4_CONTROLLER_LAYER_MIGRATION.md | 290 +++++++++++++++++++ PRISMA_TO_RAW_QUERY_MIGRATION_PLAN.md | 30 +- 3 files changed, 694 insertions(+), 11 deletions(-) create mode 100644 PHASE4.1_ADMIN_CONTROLLER_MIGRATION.md create mode 100644 PHASE4_CONTROLLER_LAYER_MIGRATION.md diff --git a/PHASE4.1_ADMIN_CONTROLLER_MIGRATION.md b/PHASE4.1_ADMIN_CONTROLLER_MIGRATION.md new file mode 100644 index 00000000..6ebfd653 --- /dev/null +++ b/PHASE4.1_ADMIN_CONTROLLER_MIGRATION.md @@ -0,0 +1,385 @@ +# Phase 4.1: AdminController Raw Query 전환 계획 + +## 📋 개요 + +관리자 컨트롤러의 Prisma 호출을 Raw Query로 전환합니다. +사용자, 회사, 부서, 메뉴 관리 등 핵심 관리 기능을 포함합니다. + +--- + +### 📊 기본 정보 + +| 항목 | 내용 | +| --------------- | --------------------------------------------- | +| 파일 위치 | `backend-node/src/controllers/adminController.ts` | +| 파일 크기 | 2,571 라인 | +| Prisma 호출 | 28개 | +| **현재 진행률** | **0/28 (0%)** 🔄 **진행 예정** | +| 복잡도 | 중간 (다양한 CRUD 패턴) | +| 우선순위 | 🔴 높음 (Phase 4.1) | +| **상태** | ⏳ **대기 중** | + +--- + +## 🔍 Prisma 호출 분석 + +### 사용자 관리 (13개) + +#### 1. getUserList (라인 312-317) +```typescript +const totalCount = await prisma.user_info.count({ where }); +const users = await prisma.user_info.findMany({ where, skip, take, orderBy }); +``` +- **전환**: count → `queryOne`, findMany → `query` +- **복잡도**: 중간 (동적 WHERE, 페이징) + +#### 2. getUserInfo (라인 419) +```typescript +const userInfo = await prisma.user_info.findFirst({ where }); +``` +- **전환**: findFirst → `queryOne` +- **복잡도**: 낮음 + +#### 3. updateUserStatus (라인 498) +```typescript +await prisma.user_info.update({ where, data }); +``` +- **전환**: update → `query` +- **복잡도**: 낮음 + +#### 4. deleteUserByAdmin (라인 2387) +```typescript +await prisma.user_info.update({ where, data: { is_active: 'N' } }); +``` +- **전환**: update (soft delete) → `query` +- **복잡도**: 낮음 + +#### 5. getMyProfile (라인 1468, 1488, 2479) +```typescript +const user = await prisma.user_info.findUnique({ where }); +const dept = await prisma.dept_info.findUnique({ where }); +``` +- **전환**: findUnique → `queryOne` +- **복잡도**: 낮음 + +#### 6. updateMyProfile (라인 1864, 2527) +```typescript +const updateResult = await prisma.user_info.update({ where, data }); +``` +- **전환**: update → `queryOne` with RETURNING +- **복잡도**: 중간 (동적 UPDATE) + +#### 7. createOrUpdateUser (라인 1929, 1975) +```typescript +const savedUser = await prisma.user_info.upsert({ where, update, create }); +const userCount = await prisma.user_info.count({ where }); +``` +- **전환**: upsert → `INSERT ... ON CONFLICT`, count → `queryOne` +- **복잡도**: 높음 + +#### 8. 기타 findUnique (라인 1596, 1832, 2393) +```typescript +const existingUser = await prisma.user_info.findUnique({ where }); +const currentUser = await prisma.user_info.findUnique({ where }); +const updatedUser = await prisma.user_info.findUnique({ where }); +``` +- **전환**: findUnique → `queryOne` +- **복잡도**: 낮음 + +### 회사 관리 (7개) + +#### 9. getCompanyList (라인 550, 1276) +```typescript +const companies = await prisma.company_mng.findMany({ orderBy }); +``` +- **전환**: findMany → `query` +- **복잡도**: 낮음 + +#### 10. createCompany (라인 2035) +```typescript +const existingCompany = await prisma.company_mng.findFirst({ where }); +``` +- **전환**: findFirst (중복 체크) → `queryOne` +- **복잡도**: 낮음 + +#### 11. updateCompany (라인 2172, 2192) +```typescript +const duplicateCompany = await prisma.company_mng.findFirst({ where }); +const updatedCompany = await prisma.company_mng.update({ where, data }); +``` +- **전환**: findFirst → `queryOne`, update → `queryOne` +- **복잡도**: 중간 + +#### 12. deleteCompany (라인 2261, 2281) +```typescript +const existingCompany = await prisma.company_mng.findUnique({ where }); +await prisma.company_mng.delete({ where }); +``` +- **전환**: findUnique → `queryOne`, delete → `query` +- **복잡도**: 낮음 + +### 부서 관리 (2개) + +#### 13. getDepartmentList (라인 1348) +```typescript +const departments = await prisma.dept_info.findMany({ where, orderBy }); +``` +- **전환**: findMany → `query` +- **복잡도**: 낮음 + +#### 14. getDeptInfo (라인 1488) +```typescript +const dept = await prisma.dept_info.findUnique({ where }); +``` +- **전환**: findUnique → `queryOne` +- **복잡도**: 낮음 + +### 메뉴 관리 (3개) + +#### 15. createMenu (라인 1021) +```typescript +const savedMenu = await prisma.menu_info.create({ data }); +``` +- **전환**: create → `queryOne` with INSERT RETURNING +- **복잡도**: 중간 + +#### 16. updateMenu (라인 1087) +```typescript +const updatedMenu = await prisma.menu_info.update({ where, data }); +``` +- **전환**: update → `queryOne` with UPDATE RETURNING +- **복잡도**: 중간 + +#### 17. deleteMenu (라인 1149, 1211) +```typescript +const deletedMenu = await prisma.menu_info.delete({ where }); +// 재귀 삭제 +const deletedMenu = await prisma.menu_info.delete({ where }); +``` +- **전환**: delete → `query` +- **복잡도**: 중간 (재귀 삭제 로직) + +### 다국어 (1개) + +#### 18. getMultiLangKeys (라인 665) +```typescript +const result = await prisma.multi_lang_key_master.findMany({ where, orderBy }); +``` +- **전환**: findMany → `query` +- **복잡도**: 낮음 + +--- + +## 📝 전환 전략 + +### 1단계: Import 변경 +```typescript +// 제거 +import { PrismaClient } from "@prisma/client"; +const prisma = new PrismaClient(); + +// 추가 +import { query, queryOne } from "../database/db"; +``` + +### 2단계: 단순 조회 전환 +- findMany → `query` +- findUnique/findFirst → `queryOne` + +### 3단계: 동적 WHERE 처리 +```typescript +const whereConditions: string[] = []; +const params: any[] = []; +let paramIndex = 1; + +if (companyCode) { + whereConditions.push(`company_code = $${paramIndex++}`); + params.push(companyCode); +} + +const whereClause = whereConditions.length > 0 + ? `WHERE ${whereConditions.join(' AND ')}` + : ''; +``` + +### 4단계: 복잡한 로직 전환 +- count → `SELECT COUNT(*) as count` +- upsert → `INSERT ... ON CONFLICT DO UPDATE` +- 동적 UPDATE → 조건부 SET 절 생성 + +### 5단계: 테스트 및 검증 +- 각 함수별 동작 확인 +- 에러 처리 확인 +- 타입 안전성 확인 + +--- + +## 🎯 주요 변경 예시 + +### getUserList (count + findMany) +```typescript +// Before +const totalCount = await prisma.user_info.count({ where }); +const users = await prisma.user_info.findMany({ + where, + skip, + take, + orderBy +}); + +// After +const whereConditions: string[] = []; +const params: any[] = []; +let paramIndex = 1; + +// 동적 WHERE 구성 +if (where.company_code) { + whereConditions.push(`company_code = $${paramIndex++}`); + params.push(where.company_code); +} +if (where.user_name) { + whereConditions.push(`user_name ILIKE $${paramIndex++}`); + params.push(`%${where.user_name}%`); +} + +const whereClause = whereConditions.length > 0 + ? `WHERE ${whereConditions.join(' AND ')}` + : ''; + +// Count +const countResult = await queryOne<{ count: number }>( + `SELECT COUNT(*) as count FROM user_info ${whereClause}`, + params +); +const totalCount = parseInt(countResult?.count?.toString() || '0', 10); + +// 데이터 조회 +const usersQuery = ` + SELECT * FROM user_info + ${whereClause} + ORDER BY created_date DESC + LIMIT $${paramIndex} OFFSET $${paramIndex + 1} +`; +params.push(take, skip); + +const users = await query(usersQuery, params); +``` + +### createOrUpdateUser (upsert) +```typescript +// Before +const savedUser = await prisma.user_info.upsert({ + where: { user_id: userId }, + update: updateData, + create: createData +}); + +// After +const savedUser = await queryOne( + `INSERT INTO user_info (user_id, user_name, email, ...) + VALUES ($1, $2, $3, ...) + ON CONFLICT (user_id) + DO UPDATE SET + user_name = EXCLUDED.user_name, + email = EXCLUDED.email, + ... + RETURNING *`, + [userId, userName, email, ...] +); +``` + +### updateMyProfile (동적 UPDATE) +```typescript +// Before +const updateResult = await prisma.user_info.update({ + where: { user_id: userId }, + data: updateData +}); + +// After +const updates: string[] = []; +const params: any[] = []; +let paramIndex = 1; + +if (updateData.user_name !== undefined) { + updates.push(`user_name = $${paramIndex++}`); + params.push(updateData.user_name); +} +if (updateData.email !== undefined) { + updates.push(`email = $${paramIndex++}`); + params.push(updateData.email); +} +// ... 다른 필드들 + +params.push(userId); + +const updateResult = await queryOne( + `UPDATE user_info + SET ${updates.join(', ')}, updated_date = NOW() + WHERE user_id = $${paramIndex} + RETURNING *`, + params +); +``` + +--- + +## ✅ 체크리스트 + +### 기본 설정 +- [ ] Prisma import 제거 +- [ ] query, queryOne import 추가 +- [ ] 타입 import 확인 + +### 사용자 관리 +- [ ] getUserList (count + findMany) +- [ ] getUserInfo (findFirst) +- [ ] updateUserStatus (update) +- [ ] deleteUserByAdmin (soft delete) +- [ ] getMyProfile (findUnique x3) +- [ ] updateMyProfile (update x2) +- [ ] createOrUpdateUser (upsert + count) +- [ ] 기타 findUnique (x3) + +### 회사 관리 +- [ ] getCompanyList (findMany x2) +- [ ] createCompany (findFirst 중복체크) +- [ ] updateCompany (findFirst + update) +- [ ] deleteCompany (findUnique + delete) + +### 부서 관리 +- [ ] getDepartmentList (findMany) +- [ ] getDeptInfo (findUnique) + +### 메뉴 관리 +- [ ] createMenu (create) +- [ ] updateMenu (update) +- [ ] deleteMenu (delete x2, 재귀) + +### 다국어 +- [ ] getMultiLangKeys (findMany) + +### 검증 +- [ ] TypeScript 컴파일 확인 +- [ ] Linter 오류 확인 +- [ ] 기능 테스트 +- [ ] 에러 처리 확인 + +--- + +## 📌 참고사항 + +### 동적 쿼리 생성 패턴 +모든 동적 WHERE/UPDATE는 다음 패턴을 따릅니다: +1. 조건/필드 배열 생성 +2. 파라미터 배열 생성 +3. 파라미터 인덱스 관리 +4. SQL 문자열 조합 +5. query/queryOne 실행 + +### 에러 처리 +기존 try-catch 구조를 유지하며, 데이터베이스 에러를 적절히 변환합니다. + +### 트랜잭션 +복잡한 로직은 Service Layer로 이동을 고려합니다. + diff --git a/PHASE4_CONTROLLER_LAYER_MIGRATION.md b/PHASE4_CONTROLLER_LAYER_MIGRATION.md new file mode 100644 index 00000000..4bcc58e9 --- /dev/null +++ b/PHASE4_CONTROLLER_LAYER_MIGRATION.md @@ -0,0 +1,290 @@ +# Phase 4: Controller Layer Raw Query 전환 계획 + +## 📋 개요 + +컨트롤러 레이어에 남아있는 Prisma 호출을 Raw Query로 전환합니다. +대부분의 컨트롤러는 Service 레이어를 호출하지만, 일부 컨트롤러에서 직접 Prisma를 사용하고 있습니다. + +--- + +### 📊 기본 정보 + +| 항목 | 내용 | +| --------------- | --------------------------------------- | +| 대상 파일 | 7개 컨트롤러 | +| 파일 위치 | `backend-node/src/controllers/` | +| Prisma 호출 | 70개 | +| **현재 진행률** | **0/70 (0%)** 🔄 **진행 예정** | +| 복잡도 | 중간 (대부분 단순 CRUD) | +| 우선순위 | 🟡 중간 (Phase 4) | +| **상태** | ⏳ **대기 중** | + +--- + +## 🎯 전환 대상 컨트롤러 + +### 1. adminController.ts (28개) +- **라인 수**: 2,571 라인 +- **Prisma 호출**: 28개 +- **주요 기능**: + - 사용자 관리 (조회, 생성, 수정, 삭제) + - 회사 관리 (조회, 생성, 수정, 삭제) + - 부서 관리 (조회) + - 메뉴 관리 (생성, 수정, 삭제) + - 다국어 키 조회 +- **우선순위**: 🔴 높음 + +### 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 상태 코드 반환 +- 사용자 친화적 에러 메시지 + diff --git a/PRISMA_TO_RAW_QUERY_MIGRATION_PLAN.md b/PRISMA_TO_RAW_QUERY_MIGRATION_PLAN.md index 6ca6e9e2..fb91a3f5 100644 --- a/PRISMA_TO_RAW_QUERY_MIGRATION_PLAN.md +++ b/PRISMA_TO_RAW_QUERY_MIGRATION_PLAN.md @@ -152,18 +152,26 @@ backend-node/ (루트) - `ddlExecutionService.ts` (0개) - ✅ **전환 완료** (이미 완료됨) - [계획서](PHASE3.18_DDL_EXECUTION_SERVICE_MIGRATION.md) - `referenceCacheService.ts` (0개) - ✅ **전환 완료** (이미 완료됨) - [계획서](PHASE3.17_REFERENCE_CACHE_SERVICE_MIGRATION.md) -#### 🟢 **단순 (컨트롤러 레이어) - 4순위** +#### 🟢 **컨트롤러 레이어 (Phase 4) - 4순위** -- `adminController.ts` (28개) - 관리자 컨트롤러 ⭐ 신규 발견 -- `webTypeStandardController.ts` (11개) - 웹타입 표준 ⭐ 신규 발견 -- `fileController.ts` (11개) - 파일 컨트롤러 ⭐ 신규 발견 -- `buttonActionStandardController.ts` (11개) - 버튼 액션 표준 ⭐ 신규 발견 -- `entityReferenceController.ts` (4개) - 엔티티 참조 ⭐ 신규 발견 -- `database.ts` (4개) - 데이터베이스 설정 -- `dataflowExecutionController.ts` (3개) - 데이터플로우 실행 ⭐ 신규 발견 -- `screenFileController.ts` (2개) - 화면 파일 ⭐ 신규 발견 -- `ddlRoutes.ts` (2개) - DDL 라우트 ⭐ 신규 발견 -- `companyManagementRoutes.ts` (2개) - 회사 관리 라우트 ⭐ 신규 발견 +**통합 계획서**: [PHASE4_CONTROLLER_LAYER_MIGRATION.md](PHASE4_CONTROLLER_LAYER_MIGRATION.md) + +- `adminController.ts` (28개) - ⏳ **대기 중** - [상세 계획서](PHASE4.1_ADMIN_CONTROLLER_MIGRATION.md) + - 사용자 관리 (13개), 회사 관리 (7개), 부서 관리 (2개), 메뉴 관리 (3개), 다국어 (1개) +- `webTypeStandardController.ts` (11개) - ⏳ **대기 중** + - findMany (1), findUnique (4), create (1), update (2), delete (1), $transaction (1), groupBy (1) +- `fileController.ts` (11개) - ⏳ **대기 중** + - findMany (6), findUnique (4), create (1), update (1) +- `buttonActionStandardController.ts` (11개) - ⏳ **대기 중** + - findMany (1), findUnique (4), create (1), update (2), delete (1), $transaction (1), groupBy (1) +- `entityReferenceController.ts` (4개) - ⏳ **대기 중** +- `dataflowExecutionController.ts` (3개) - ⏳ **대기 중** +- `screenFileController.ts` (2개) - ⏳ **대기 중** + +**기타 설정 파일**: +- `database.ts` (4개) - 데이터베이스 연결 설정 ($connect, $disconnect) +- `ddlRoutes.ts` (2개) - DDL 라우트 +- `companyManagementRoutes.ts` (2개) - 회사 관리 라우트 #### 🗑️ **삭제 예정 Scripts (마이그레이션 대상 아님)**