feat: Phase 2.1 - Start ScreenManagementService Raw Query migration (2/46)
1단계 기본 CRUD 전환 시작 (2/6 완료) ✅ 전환 완료 (2개): 1. createScreen() - 화면 생성 - 중복 확인: findFirst → Raw Query SELECT - 생성: create → Raw Query INSERT RETURNING - 파라미터 바인딩 적용 2. getScreensByCompany() - 화면 목록 조회 (페이징) - 동적 WHERE 절 생성 - Promise.all로 병렬 조회 (목록 + 총개수) - table_labels IN 쿼리 전환 🔧 주요 변경사항: - Prisma import 제거 → query, transaction import - 파라미터 바인딩으로 SQL Injection 방지 - COUNT 결과 문자열 → 숫자 변환 📊 진행률: - 전환 완료: 2/46 (4.3%) - 남은 작업: 44개 Prisma 호출 🎯 다음 작업: - getScreenByCode() - getScreenById() - updateScreen() - deleteScreen() 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
ba10e7a12b
commit
95c9811c3b
|
|
@ -1,4 +1,5 @@
|
|||
import prisma from "../config/database";
|
||||
// ✅ Prisma → Raw Query 전환 (Phase 2.1)
|
||||
import { query, transaction } from "../database/db";
|
||||
import {
|
||||
ScreenDefinition,
|
||||
CreateScreenRequest,
|
||||
|
|
@ -39,7 +40,7 @@ export class ScreenManagementService {
|
|||
// ========================================
|
||||
|
||||
/**
|
||||
* 화면 정의 생성
|
||||
* 화면 정의 생성 (✅ Raw Query 전환 완료)
|
||||
*/
|
||||
async createScreen(
|
||||
screenData: CreateScreenRequest,
|
||||
|
|
@ -49,75 +50,97 @@ export class ScreenManagementService {
|
|||
console.log(`요청 데이터:`, screenData);
|
||||
console.log(`사용자 회사 코드:`, userCompanyCode);
|
||||
|
||||
// 화면 코드 중복 확인
|
||||
const existingScreen = await prisma.screen_definitions.findFirst({
|
||||
where: {
|
||||
screen_code: screenData.screenCode,
|
||||
is_active: { not: "D" }, // 삭제되지 않은 화면만 중복 검사
|
||||
},
|
||||
});
|
||||
// 화면 코드 중복 확인 (Raw Query)
|
||||
const existingResult = await query<{ screen_id: number }>(
|
||||
`SELECT screen_id FROM screen_definitions
|
||||
WHERE screen_code = $1 AND is_active != 'D'
|
||||
LIMIT 1`,
|
||||
[screenData.screenCode]
|
||||
);
|
||||
|
||||
console.log(
|
||||
`화면 코드 '${screenData.screenCode}' 중복 검사 결과:`,
|
||||
existingScreen ? "중복됨" : "사용 가능"
|
||||
existingResult.length > 0 ? "중복됨" : "사용 가능"
|
||||
);
|
||||
|
||||
if (existingScreen) {
|
||||
console.log(`기존 화면 정보:`, existingScreen);
|
||||
if (existingResult.length > 0) {
|
||||
console.log(`기존 화면 정보:`, existingResult[0]);
|
||||
throw new Error("이미 존재하는 화면 코드입니다.");
|
||||
}
|
||||
|
||||
const screen = await prisma.screen_definitions.create({
|
||||
data: {
|
||||
screen_name: screenData.screenName,
|
||||
screen_code: screenData.screenCode,
|
||||
table_name: screenData.tableName,
|
||||
company_code: screenData.companyCode,
|
||||
description: screenData.description,
|
||||
created_by: screenData.createdBy,
|
||||
},
|
||||
});
|
||||
// 화면 생성 (Raw Query)
|
||||
const [screen] = await query<any>(
|
||||
`INSERT INTO screen_definitions (
|
||||
screen_name, screen_code, table_name, company_code, description, created_by
|
||||
) VALUES ($1, $2, $3, $4, $5, $6)
|
||||
RETURNING *`,
|
||||
[
|
||||
screenData.screenName,
|
||||
screenData.screenCode,
|
||||
screenData.tableName,
|
||||
screenData.companyCode,
|
||||
screenData.description || null,
|
||||
screenData.createdBy,
|
||||
]
|
||||
);
|
||||
|
||||
return this.mapToScreenDefinition(screen);
|
||||
}
|
||||
|
||||
/**
|
||||
* 회사별 화면 목록 조회 (페이징 지원) - 활성 화면만
|
||||
* 회사별 화면 목록 조회 (페이징 지원) - 활성 화면만 (✅ Raw Query 전환 완료)
|
||||
*/
|
||||
async getScreensByCompany(
|
||||
companyCode: string,
|
||||
page: number = 1,
|
||||
size: number = 20
|
||||
): Promise<PaginatedResponse<ScreenDefinition>> {
|
||||
const whereClause: any = { is_active: { not: "D" } }; // 삭제된 화면 제외
|
||||
const offset = (page - 1) * size;
|
||||
|
||||
// WHERE 절 동적 생성
|
||||
const whereConditions: string[] = ["is_active != 'D'"];
|
||||
const params: any[] = [];
|
||||
|
||||
if (companyCode !== "*") {
|
||||
whereClause.company_code = companyCode;
|
||||
whereConditions.push(`company_code = $${params.length + 1}`);
|
||||
params.push(companyCode);
|
||||
}
|
||||
|
||||
const [screens, total] = await Promise.all([
|
||||
prisma.screen_definitions.findMany({
|
||||
where: whereClause,
|
||||
skip: (page - 1) * size,
|
||||
take: size,
|
||||
orderBy: { created_date: "desc" },
|
||||
}),
|
||||
prisma.screen_definitions.count({ where: whereClause }),
|
||||
const whereSQL = whereConditions.join(" AND ");
|
||||
|
||||
// 페이징 쿼리 (Raw Query)
|
||||
const [screens, totalResult] = await Promise.all([
|
||||
query<any>(
|
||||
`SELECT * FROM screen_definitions
|
||||
WHERE ${whereSQL}
|
||||
ORDER BY created_date DESC
|
||||
LIMIT $${params.length + 1} OFFSET $${params.length + 2}`,
|
||||
[...params, size, offset]
|
||||
),
|
||||
query<{ count: string }>(
|
||||
`SELECT COUNT(*)::text as count FROM screen_definitions
|
||||
WHERE ${whereSQL}`,
|
||||
params
|
||||
),
|
||||
]);
|
||||
|
||||
// 테이블 라벨 정보를 한 번에 조회
|
||||
const total = parseInt(totalResult[0]?.count || "0", 10);
|
||||
|
||||
// 테이블 라벨 정보를 한 번에 조회 (Raw Query)
|
||||
const tableNames = [
|
||||
...new Set(screens.map((s) => s.table_name).filter(Boolean)),
|
||||
...new Set(screens.map((s: any) => s.table_name).filter(Boolean)),
|
||||
];
|
||||
|
||||
let tableLabelMap = new Map<string, string>();
|
||||
|
||||
if (tableNames.length > 0) {
|
||||
try {
|
||||
const tableLabels = await prisma.table_labels.findMany({
|
||||
where: { table_name: { in: tableNames } },
|
||||
select: { table_name: true, table_label: true },
|
||||
});
|
||||
const placeholders = tableNames.map((_, i) => `$${i + 1}`).join(", ");
|
||||
const tableLabels = await query<{ table_name: string; table_label: string | null }>(
|
||||
`SELECT table_name, table_label FROM table_labels
|
||||
WHERE table_name IN (${placeholders})`,
|
||||
tableNames
|
||||
);
|
||||
|
||||
tableLabelMap = new Map(
|
||||
tableLabels.map((tl) => [
|
||||
|
|
|
|||
Loading…
Reference in New Issue