ERP-node/PHASE4_REMAINING_PRISMA_CAL...

13 KiB

Phase 4: 남은 Prisma 호출 전환 계획

📊 현재 상황

항목 내용
총 Prisma 호출 29개
대상 파일 7개
현재 진행률 17/29 (58.6%) 🔄 진행 중
복잡도 중간
우선순위 🔴 높음 (Phase 4)
상태 진행 중

📁 파일별 현황

완료된 파일 (2개)

  1. adminController.ts - 28개 완료

    • 사용자 관리: getUserList, getUserInfo, updateUserStatus, deleteUser
    • 프로필 관리: getMyProfile, updateMyProfile, resetPassword
    • 사용자 생성/수정: createOrUpdateUser (UPSERT)
    • 회사 관리: getCompanyList, createCompany, updateCompany, deleteCompany
    • 부서 관리: getDepartmentList, getDeptInfo
    • 메뉴 관리: createMenu, updateMenu, deleteMenu
    • 다국어: getMultiLangKeys, updateLocale
  2. screenFileController.ts - 2개 완료

    • getScreenComponentFiles: findMany → query (LIKE)
    • getComponentFiles: findMany → query (LIKE)

남은 파일 (5개, 총 12개 호출)

1. webTypeStandardController.ts (11개) 🔴 최우선

위치: backend-node/src/controllers/webTypeStandardController.ts

Prisma 호출 목록:

  1. 라인 33: getWebTypeStandards() - findMany

    const webTypes = await prisma.web_type_standards.findMany({
      where,
      orderBy,
      select,
    });
    
  2. 라인 58: getWebTypeStandard() - findUnique

    const webTypeData = await prisma.web_type_standards.findUnique({
      where: { id },
    });
    
  3. 라인 112: createWebTypeStandard() - findUnique (중복 체크)

    const existingWebType = await prisma.web_type_standards.findUnique({
      where: { web_type: webType },
    });
    
  4. 라인 123: createWebTypeStandard() - create

    const newWebType = await prisma.web_type_standards.create({
      data: { ... }
    });
    
  5. 라인 178: updateWebTypeStandard() - findUnique (존재 확인)

    const existingWebType = await prisma.web_type_standards.findUnique({
      where: { id },
    });
    
  6. 라인 189: updateWebTypeStandard() - update

    const updatedWebType = await prisma.web_type_standards.update({
      where: { id }, data: { ... }
    });
    
  7. 라인 230: deleteWebTypeStandard() - findUnique (존재 확인)

    const existingWebType = await prisma.web_type_standards.findUnique({
      where: { id },
    });
    
  8. 라인 241: deleteWebTypeStandard() - delete

    await prisma.web_type_standards.delete({
      where: { id },
    });
    
  9. 라인 275: updateSortOrder() - $transaction

    await prisma.$transaction(
      updates.map((item) =>
        prisma.web_type_standards.update({ ... })
      )
    );
    
  10. 라인 277: updateSortOrder() - update (트랜잭션 내부)

  11. 라인 305: getCategories() - groupBy

    const categories = await prisma.web_type_standards.groupBy({
      by: ["category"],
      where,
      _count: true,
    });
    

전환 전략:

  • findMany → query<WebTypeStandard> with dynamic WHERE
  • findUnique → queryOne<WebTypeStandard>
  • create → queryOne with INSERT RETURNING
  • update → queryOne with UPDATE RETURNING
  • delete → query with DELETE
  • $transaction → transaction with client.query
  • groupBy → query with GROUP BY, COUNT

2. fileController.ts (1개) 🟡

위치: backend-node/src/controllers/fileController.ts

Prisma 호출:

  1. 라인 726: downloadFile() - findUnique
    const fileRecord = await prisma.attach_file_info.findUnique({
      where: { objid: BigInt(objid) },
    });
    

전환 전략:

  • findUnique → queryOne<AttachFileInfo>

3. multiConnectionQueryService.ts (4개) 🟢

위치: backend-node/src/services/multiConnectionQueryService.ts

Prisma 호출 목록:

  1. 라인 1005: executeSelect() - $queryRawUnsafe

    return await prisma.$queryRawUnsafe(query, ...queryParams);
    
  2. 라인 1022: executeInsert() - $queryRawUnsafe

    const insertResult = await prisma.$queryRawUnsafe(...);
    
  3. 라인 1055: executeUpdate() - $queryRawUnsafe

    return await prisma.$queryRawUnsafe(updateQuery, ...updateParams);
    
  4. 라인 1071: executeDelete() - $queryRawUnsafe

    return await prisma.$queryRawUnsafe(...);
    

전환 전략:

  • $queryRawUnsafe → query<any> (이미 Raw SQL 사용 중)

4. config/database.ts (4개) 🟢

위치: backend-node/src/config/database.ts

Prisma 호출:

  1. 라인 1: PrismaClient import
  2. 라인 17: prisma 인스턴스 생성
  3. 라인 22: await prisma.$connect()
  4. 라인 31, 35, 40: await prisma.$disconnect()

전환 전략:

  • 이 파일은 데이터베이스 설정 파일이므로 완전히 제거
  • 기존 db.ts의 connection pool로 대체
  • 모든 import 경로를 databasedatabase/db로 변경

5. routes/ddlRoutes.ts (2개) 🟢

위치: backend-node/src/routes/ddlRoutes.ts

Prisma 호출:

  1. 라인 183-184: 동적 PrismaClient import

    const { PrismaClient } = await import("@prisma/client");
    const prisma = new PrismaClient();
    
  2. 라인 186-187: 연결 테스트

    await prisma.$queryRaw`SELECT 1`;
    await prisma.$disconnect();
    

전환 전략:

  • 동적 import 제거
  • query('SELECT 1') 사용

6. routes/companyManagementRoutes.ts (2개) 🟢

위치: backend-node/src/routes/companyManagementRoutes.ts

Prisma 호출:

  1. 라인 32: findUnique (중복 체크)

    const existingCompany = await prisma.company_mng.findUnique({
      where: { company_code },
    });
    
  2. 라인 61: update (회사명 업데이트)

    await prisma.company_mng.update({
      where: { company_code },
      data: { company_name },
    });
    

전환 전략:

  • findUnique → queryOne
  • update → query

7. tests/authService.test.ts (2개) ⚠️

위치: backend-node/src/tests/authService.test.ts

테스트 파일은 별도 처리 필요 (Phase 5에서 처리)


🎯 전환 우선순위

Phase 4.1: 컨트롤러 (완료)

  • screenFileController.ts (2개)
  • adminController.ts (28개)

Phase 4.2: 남은 컨트롤러 (진행 예정)

  • webTypeStandardController.ts (11개) - 🔴 최우선
  • fileController.ts (1개)

Phase 4.3: Routes (진행 예정)

  • ddlRoutes.ts (2개)
  • companyManagementRoutes.ts (2개)

Phase 4.4: Services (진행 예정)

  • multiConnectionQueryService.ts (4개)

Phase 4.5: Config (진행 예정)

  • database.ts (4개) - 전체 파일 제거

Phase 4.6: Tests (Phase 5)

  • authService.test.ts (2개) - 별도 처리

📋 체크리스트

webTypeStandardController.ts

  • Prisma import 제거
  • query, queryOne import 추가
  • getWebTypeStandards (findMany → query)
  • getWebTypeStandard (findUnique → queryOne)
  • createWebTypeStandard (findUnique + create → queryOne)
  • updateWebTypeStandard (findUnique + update → queryOne)
  • deleteWebTypeStandard (findUnique + delete → query)
  • updateSortOrder ($transaction → transaction)
  • getCategories (groupBy → query with GROUP BY)
  • TypeScript 컴파일 확인
  • Linter 오류 확인
  • 동작 테스트

fileController.ts

  • Prisma import 제거
  • queryOne import 추가
  • downloadFile (findUnique → queryOne)
  • TypeScript 컴파일 확인

routes/ddlRoutes.ts

  • 동적 PrismaClient import 제거
  • query import 추가
  • 연결 테스트 로직 변경
  • TypeScript 컴파일 확인

routes/companyManagementRoutes.ts

  • Prisma import 제거
  • query, queryOne import 추가
  • findUnique → queryOne
  • update → query
  • TypeScript 컴파일 확인

services/multiConnectionQueryService.ts

  • Prisma import 제거
  • query import 추가
  • $queryRawUnsafe → query (4곳)
  • TypeScript 컴파일 확인

config/database.ts

  • 파일 전체 분석
  • 의존성 확인
  • 대체 방안 구현
  • 모든 import 경로 변경
  • 파일 삭제 또는 완전 재작성

🔧 전환 패턴 요약

1. findMany → query

// Before
const items = await prisma.table.findMany({ where, orderBy });

// After
const items = await query<T>(
  `SELECT * FROM table WHERE ... ORDER BY ...`,
  params
);

2. findUnique → queryOne

// Before
const item = await prisma.table.findUnique({ where: { id } });

// After
const item = await queryOne<T>(`SELECT * FROM table WHERE id = $1`, [id]);

3. create → queryOne with RETURNING

// Before
const newItem = await prisma.table.create({ data });

// After
const [newItem] = await query<T>(
  `INSERT INTO table (col1, col2) VALUES ($1, $2) RETURNING *`,
  [val1, val2]
);

4. update → query with RETURNING

// Before
const updated = await prisma.table.update({ where, data });

// After
const [updated] = await query<T>(
  `UPDATE table SET col1 = $1 WHERE id = $2 RETURNING *`,
  [val1, id]
);

5. delete → query

// Before
await prisma.table.delete({ where: { id } });

// After
await query(`DELETE FROM table WHERE id = $1`, [id]);

6. $transaction → transaction

// Before
await prisma.$transaction([
  prisma.table.update({ ... }),
  prisma.table.update({ ... })
]);

// After
await transaction(async (client) => {
  await client.query(`UPDATE table SET ...`, params1);
  await client.query(`UPDATE table SET ...`, params2);
});

7. groupBy → query with GROUP BY

// Before
const result = await prisma.table.groupBy({
  by: ["category"],
  _count: true,
});

// After
const result = await query<T>(
  `SELECT category, COUNT(*) as count FROM table GROUP BY category`,
  []
);

📈 진행 상황

전체 진행률: 17/29 (58.6%)

Phase 1-3: Service Layer    ████████████████████████████ 100% (415/415)
Phase 4.1: Controllers      ████████████████████████████ 100% (30/30)
Phase 4.2: 남은 파일        ███████░░░░░░░░░░░░░░░░░░░░  58% (17/29)

상세 진행 상황

카테고리 완료 남음 진행률
Services 415 0 100%
Controllers 30 11 73%
Routes 0 4 0%
Config 0 4 0%
총계 445 19 95.9%

🎬 다음 단계

  1. webTypeStandardController.ts 전환 (11개)

    • 가장 많은 Prisma 호출을 가진 남은 컨트롤러
    • 웹 타입 표준 관리 핵심 기능
  2. fileController.ts 전환 (1개)

    • 단순 findUnique만 있어 빠르게 처리 가능
  3. Routes 전환 (4개)

    • ddlRoutes.ts
    • companyManagementRoutes.ts
  4. Service 전환 (4개)

    • multiConnectionQueryService.ts
  5. Config 제거 (4개)

    • database.ts 완전 제거 또는 재작성
    • 모든 의존성 제거

⚠️ 주의사항

  1. database.ts 처리

    • 현재 많은 파일이 import prisma from '../config/database' 사용
    • 모든 import를 import { query, queryOne } from '../database/db'로 변경 필요
    • 단계적으로 진행하여 빌드 오류 방지
  2. BigInt 처리

    • fileController의 objid: BigInt(objid)objid::bigint 또는 CAST(objid AS BIGINT)
  3. 트랜잭션 처리

    • webTypeStandardController의 updateSortOrder는 복잡한 트랜잭션
    • transaction 함수 사용 필요
  4. 타입 안전성

    • 모든 Raw Query에 명시적 타입 지정 필요
    • query<WebTypeStandard>, queryOne<AttachFileInfo>

📝 완료 후 작업

  • 전체 컴파일 확인
  • Linter 오류 해결
  • 통합 테스트 실행
  • Prisma 관련 의존성 완전 제거 (package.json)
  • prisma/ 디렉토리 정리
  • 문서 업데이트
  • 커밋 및 Push

작성일: 2025-10-01
최종 업데이트: 2025-10-01
상태: 🔄 진행 중 (58.6% 완료)