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 {
|
import {
|
||||||
ScreenDefinition,
|
ScreenDefinition,
|
||||||
CreateScreenRequest,
|
CreateScreenRequest,
|
||||||
|
|
@ -39,7 +40,7 @@ export class ScreenManagementService {
|
||||||
// ========================================
|
// ========================================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 화면 정의 생성
|
* 화면 정의 생성 (✅ Raw Query 전환 완료)
|
||||||
*/
|
*/
|
||||||
async createScreen(
|
async createScreen(
|
||||||
screenData: CreateScreenRequest,
|
screenData: CreateScreenRequest,
|
||||||
|
|
@ -49,75 +50,97 @@ export class ScreenManagementService {
|
||||||
console.log(`요청 데이터:`, screenData);
|
console.log(`요청 데이터:`, screenData);
|
||||||
console.log(`사용자 회사 코드:`, userCompanyCode);
|
console.log(`사용자 회사 코드:`, userCompanyCode);
|
||||||
|
|
||||||
// 화면 코드 중복 확인
|
// 화면 코드 중복 확인 (Raw Query)
|
||||||
const existingScreen = await prisma.screen_definitions.findFirst({
|
const existingResult = await query<{ screen_id: number }>(
|
||||||
where: {
|
`SELECT screen_id FROM screen_definitions
|
||||||
screen_code: screenData.screenCode,
|
WHERE screen_code = $1 AND is_active != 'D'
|
||||||
is_active: { not: "D" }, // 삭제되지 않은 화면만 중복 검사
|
LIMIT 1`,
|
||||||
},
|
[screenData.screenCode]
|
||||||
});
|
);
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
`화면 코드 '${screenData.screenCode}' 중복 검사 결과:`,
|
`화면 코드 '${screenData.screenCode}' 중복 검사 결과:`,
|
||||||
existingScreen ? "중복됨" : "사용 가능"
|
existingResult.length > 0 ? "중복됨" : "사용 가능"
|
||||||
);
|
);
|
||||||
|
|
||||||
if (existingScreen) {
|
if (existingResult.length > 0) {
|
||||||
console.log(`기존 화면 정보:`, existingScreen);
|
console.log(`기존 화면 정보:`, existingResult[0]);
|
||||||
throw new Error("이미 존재하는 화면 코드입니다.");
|
throw new Error("이미 존재하는 화면 코드입니다.");
|
||||||
}
|
}
|
||||||
|
|
||||||
const screen = await prisma.screen_definitions.create({
|
// 화면 생성 (Raw Query)
|
||||||
data: {
|
const [screen] = await query<any>(
|
||||||
screen_name: screenData.screenName,
|
`INSERT INTO screen_definitions (
|
||||||
screen_code: screenData.screenCode,
|
screen_name, screen_code, table_name, company_code, description, created_by
|
||||||
table_name: screenData.tableName,
|
) VALUES ($1, $2, $3, $4, $5, $6)
|
||||||
company_code: screenData.companyCode,
|
RETURNING *`,
|
||||||
description: screenData.description,
|
[
|
||||||
created_by: screenData.createdBy,
|
screenData.screenName,
|
||||||
},
|
screenData.screenCode,
|
||||||
});
|
screenData.tableName,
|
||||||
|
screenData.companyCode,
|
||||||
|
screenData.description || null,
|
||||||
|
screenData.createdBy,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
return this.mapToScreenDefinition(screen);
|
return this.mapToScreenDefinition(screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 회사별 화면 목록 조회 (페이징 지원) - 활성 화면만
|
* 회사별 화면 목록 조회 (페이징 지원) - 활성 화면만 (✅ Raw Query 전환 완료)
|
||||||
*/
|
*/
|
||||||
async getScreensByCompany(
|
async getScreensByCompany(
|
||||||
companyCode: string,
|
companyCode: string,
|
||||||
page: number = 1,
|
page: number = 1,
|
||||||
size: number = 20
|
size: number = 20
|
||||||
): Promise<PaginatedResponse<ScreenDefinition>> {
|
): 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 !== "*") {
|
if (companyCode !== "*") {
|
||||||
whereClause.company_code = companyCode;
|
whereConditions.push(`company_code = $${params.length + 1}`);
|
||||||
|
params.push(companyCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
const [screens, total] = await Promise.all([
|
const whereSQL = whereConditions.join(" AND ");
|
||||||
prisma.screen_definitions.findMany({
|
|
||||||
where: whereClause,
|
// 페이징 쿼리 (Raw Query)
|
||||||
skip: (page - 1) * size,
|
const [screens, totalResult] = await Promise.all([
|
||||||
take: size,
|
query<any>(
|
||||||
orderBy: { created_date: "desc" },
|
`SELECT * FROM screen_definitions
|
||||||
}),
|
WHERE ${whereSQL}
|
||||||
prisma.screen_definitions.count({ where: whereClause }),
|
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 = [
|
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>();
|
let tableLabelMap = new Map<string, string>();
|
||||||
|
|
||||||
if (tableNames.length > 0) {
|
if (tableNames.length > 0) {
|
||||||
try {
|
try {
|
||||||
const tableLabels = await prisma.table_labels.findMany({
|
const placeholders = tableNames.map((_, i) => `$${i + 1}`).join(", ");
|
||||||
where: { table_name: { in: tableNames } },
|
const tableLabels = await query<{ table_name: string; table_label: string | null }>(
|
||||||
select: { table_name: true, table_label: true },
|
`SELECT table_name, table_label FROM table_labels
|
||||||
});
|
WHERE table_name IN (${placeholders})`,
|
||||||
|
tableNames
|
||||||
|
);
|
||||||
|
|
||||||
tableLabelMap = new Map(
|
tableLabelMap = new Map(
|
||||||
tableLabels.map((tl) => [
|
tableLabels.map((tl) => [
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue