docs: Phase 4 남은 Prisma 호출 전환 계획서 작성
현재 상황 분석 및 문서화: 컨트롤러 레이어: - ✅ adminController.ts (28개) 완료 - ✅ screenFileController.ts (2개) 완료 - 🔄 남은 파일 (12개 호출): * webTypeStandardController.ts (11개) * fileController.ts (1개) Routes & Services: - ddlRoutes.ts (2개) - companyManagementRoutes.ts (2개) - multiConnectionQueryService.ts (4개) Config: - database.ts (4개 - 제거 예정) 새로운 계획서: - PHASE4_REMAINING_PRISMA_CALLS.md (상세 전환 계획) - 파일별 Prisma 호출 상세 분석 - 전환 패턴 및 우선순위 정리 전체 진행률: 445/444 (100.2%) 남은 작업: 12개 (추가 조사 필요한 파일 제외)
This commit is contained in:
@@ -7,7 +7,7 @@ import { DatabaseConnectorFactory } from "../database/DatabaseConnectorFactory";
|
||||
|
||||
// 배치관리 전용 타입 정의
|
||||
export interface BatchConnectionInfo {
|
||||
type: 'internal' | 'external';
|
||||
type: "internal" | "external";
|
||||
id?: number;
|
||||
name: string;
|
||||
db_type?: string;
|
||||
@@ -37,15 +37,17 @@ export class BatchManagementService {
|
||||
/**
|
||||
* 배치관리용 연결 목록 조회
|
||||
*/
|
||||
static async getAvailableConnections(): Promise<BatchApiResponse<BatchConnectionInfo[]>> {
|
||||
static async getAvailableConnections(): Promise<
|
||||
BatchApiResponse<BatchConnectionInfo[]>
|
||||
> {
|
||||
try {
|
||||
const connections: BatchConnectionInfo[] = [];
|
||||
|
||||
// 내부 DB 추가
|
||||
connections.push({
|
||||
type: 'internal',
|
||||
name: '내부 데이터베이스 (PostgreSQL)',
|
||||
db_type: 'postgresql'
|
||||
type: "internal",
|
||||
name: "내부 데이터베이스 (PostgreSQL)",
|
||||
db_type: "postgresql",
|
||||
});
|
||||
|
||||
// 활성화된 외부 DB 연결 조회
|
||||
@@ -63,26 +65,26 @@ export class BatchManagementService {
|
||||
);
|
||||
|
||||
// 외부 DB 연결 추가
|
||||
externalConnections.forEach(conn => {
|
||||
externalConnections.forEach((conn) => {
|
||||
connections.push({
|
||||
type: 'external',
|
||||
type: "external",
|
||||
id: conn.id,
|
||||
name: `${conn.connection_name} (${conn.db_type?.toUpperCase()})`,
|
||||
db_type: conn.db_type || undefined
|
||||
db_type: conn.db_type || undefined,
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: connections,
|
||||
message: `${connections.length}개의 연결을 조회했습니다.`
|
||||
message: `${connections.length}개의 연결을 조회했습니다.`,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("배치관리 연결 목록 조회 실패:", error);
|
||||
return {
|
||||
success: false,
|
||||
message: "연결 목록 조회 중 오류가 발생했습니다.",
|
||||
error: error instanceof Error ? error.message : "알 수 없는 오류"
|
||||
error: error instanceof Error ? error.message : "알 수 없는 오류",
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -91,13 +93,13 @@ export class BatchManagementService {
|
||||
* 배치관리용 테이블 목록 조회
|
||||
*/
|
||||
static async getTablesFromConnection(
|
||||
connectionType: 'internal' | 'external',
|
||||
connectionType: "internal" | "external",
|
||||
connectionId?: number
|
||||
): Promise<BatchApiResponse<BatchTableInfo[]>> {
|
||||
try {
|
||||
let tables: BatchTableInfo[] = [];
|
||||
|
||||
if (connectionType === 'internal') {
|
||||
if (connectionType === "internal") {
|
||||
// 내부 DB 테이블 조회
|
||||
const result = await query<{ table_name: string }>(
|
||||
`SELECT table_name
|
||||
@@ -108,11 +110,11 @@ export class BatchManagementService {
|
||||
[]
|
||||
);
|
||||
|
||||
tables = result.map(row => ({
|
||||
tables = result.map((row) => ({
|
||||
table_name: row.table_name,
|
||||
columns: []
|
||||
columns: [],
|
||||
}));
|
||||
} else if (connectionType === 'external' && connectionId) {
|
||||
} else if (connectionType === "external" && connectionId) {
|
||||
// 외부 DB 테이블 조회
|
||||
const tablesResult = await this.getExternalTables(connectionId);
|
||||
if (tablesResult.success && tablesResult.data) {
|
||||
@@ -123,14 +125,14 @@ export class BatchManagementService {
|
||||
return {
|
||||
success: true,
|
||||
data: tables,
|
||||
message: `${tables.length}개의 테이블을 조회했습니다.`
|
||||
message: `${tables.length}개의 테이블을 조회했습니다.`,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("배치관리 테이블 목록 조회 실패:", error);
|
||||
return {
|
||||
success: false,
|
||||
message: "테이블 목록 조회 중 오류가 발생했습니다.",
|
||||
error: error instanceof Error ? error.message : "알 수 없는 오류"
|
||||
error: error instanceof Error ? error.message : "알 수 없는 오류",
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -139,7 +141,7 @@ export class BatchManagementService {
|
||||
* 배치관리용 테이블 컬럼 정보 조회
|
||||
*/
|
||||
static async getTableColumns(
|
||||
connectionType: 'internal' | 'external',
|
||||
connectionType: "internal" | "external",
|
||||
connectionId: number | undefined,
|
||||
tableName: string
|
||||
): Promise<BatchApiResponse<BatchColumnInfo[]>> {
|
||||
@@ -147,20 +149,22 @@ export class BatchManagementService {
|
||||
console.log(`[BatchManagementService] getTableColumns 호출:`, {
|
||||
connectionType,
|
||||
connectionId,
|
||||
tableName
|
||||
tableName,
|
||||
});
|
||||
|
||||
let columns: BatchColumnInfo[] = [];
|
||||
|
||||
if (connectionType === 'internal') {
|
||||
if (connectionType === "internal") {
|
||||
// 내부 DB 컬럼 조회
|
||||
console.log(`[BatchManagementService] 내부 DB 컬럼 조회 시작: ${tableName}`);
|
||||
console.log(
|
||||
`[BatchManagementService] 내부 DB 컬럼 조회 시작: ${tableName}`
|
||||
);
|
||||
|
||||
const result = await query<{
|
||||
column_name: string;
|
||||
data_type: string;
|
||||
is_nullable: string;
|
||||
column_default: string | null
|
||||
const result = await query<{
|
||||
column_name: string;
|
||||
data_type: string;
|
||||
is_nullable: string;
|
||||
column_default: string | null;
|
||||
}>(
|
||||
`SELECT
|
||||
column_name,
|
||||
@@ -178,19 +182,27 @@ export class BatchManagementService {
|
||||
|
||||
console.log(`[BatchManagementService] 내부 DB 컬럼 조회 결과:`, result);
|
||||
|
||||
columns = result.map(row => ({
|
||||
columns = result.map((row) => ({
|
||||
column_name: row.column_name,
|
||||
data_type: row.data_type,
|
||||
is_nullable: row.is_nullable,
|
||||
column_default: row.column_default,
|
||||
}));
|
||||
} else if (connectionType === 'external' && connectionId) {
|
||||
} else if (connectionType === "external" && connectionId) {
|
||||
// 외부 DB 컬럼 조회
|
||||
console.log(`[BatchManagementService] 외부 DB 컬럼 조회 시작: connectionId=${connectionId}, tableName=${tableName}`);
|
||||
console.log(
|
||||
`[BatchManagementService] 외부 DB 컬럼 조회 시작: connectionId=${connectionId}, tableName=${tableName}`
|
||||
);
|
||||
|
||||
const columnsResult = await this.getExternalTableColumns(connectionId, tableName);
|
||||
|
||||
console.log(`[BatchManagementService] 외부 DB 컬럼 조회 결과:`, columnsResult);
|
||||
const columnsResult = await this.getExternalTableColumns(
|
||||
connectionId,
|
||||
tableName
|
||||
);
|
||||
|
||||
console.log(
|
||||
`[BatchManagementService] 외부 DB 컬럼 조회 결과:`,
|
||||
columnsResult
|
||||
);
|
||||
|
||||
if (columnsResult.success && columnsResult.data) {
|
||||
columns = columnsResult.data;
|
||||
@@ -201,14 +213,14 @@ export class BatchManagementService {
|
||||
return {
|
||||
success: true,
|
||||
data: columns,
|
||||
message: `${columns.length}개의 컬럼을 조회했습니다.`
|
||||
message: `${columns.length}개의 컬럼을 조회했습니다.`,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("[BatchManagementService] 컬럼 정보 조회 오류:", error);
|
||||
return {
|
||||
success: false,
|
||||
message: "컬럼 정보 조회 중 오류가 발생했습니다.",
|
||||
error: error instanceof Error ? error.message : "알 수 없는 오류"
|
||||
error: error instanceof Error ? error.message : "알 수 없는 오류",
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -216,7 +228,9 @@ export class BatchManagementService {
|
||||
/**
|
||||
* 외부 DB 테이블 목록 조회 (내부 구현)
|
||||
*/
|
||||
private static async getExternalTables(connectionId: number): Promise<BatchApiResponse<BatchTableInfo[]>> {
|
||||
private static async getExternalTables(
|
||||
connectionId: number
|
||||
): Promise<BatchApiResponse<BatchTableInfo[]>> {
|
||||
try {
|
||||
// 연결 정보 조회
|
||||
const connection = await queryOne<any>(
|
||||
@@ -227,7 +241,7 @@ export class BatchManagementService {
|
||||
if (!connection) {
|
||||
return {
|
||||
success: false,
|
||||
message: "연결 정보를 찾을 수 없습니다."
|
||||
message: "연결 정보를 찾을 수 없습니다.",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -236,7 +250,7 @@ export class BatchManagementService {
|
||||
if (!decryptedPassword) {
|
||||
return {
|
||||
success: false,
|
||||
message: "비밀번호 복호화에 실패했습니다."
|
||||
message: "비밀번호 복호화에 실패했습니다.",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -247,26 +261,39 @@ export class BatchManagementService {
|
||||
database: connection.database_name,
|
||||
user: connection.username,
|
||||
password: decryptedPassword,
|
||||
connectionTimeoutMillis: connection.connection_timeout != null ? connection.connection_timeout * 1000 : undefined,
|
||||
queryTimeoutMillis: connection.query_timeout != null ? connection.query_timeout * 1000 : undefined,
|
||||
ssl: connection.ssl_enabled === "Y" ? { rejectUnauthorized: false } : false
|
||||
connectionTimeoutMillis:
|
||||
connection.connection_timeout != null
|
||||
? connection.connection_timeout * 1000
|
||||
: undefined,
|
||||
queryTimeoutMillis:
|
||||
connection.query_timeout != null
|
||||
? connection.query_timeout * 1000
|
||||
: undefined,
|
||||
ssl:
|
||||
connection.ssl_enabled === "Y"
|
||||
? { rejectUnauthorized: false }
|
||||
: false,
|
||||
};
|
||||
|
||||
// DatabaseConnectorFactory를 통한 테이블 목록 조회
|
||||
const connector = await DatabaseConnectorFactory.createConnector(connection.db_type, config, connectionId);
|
||||
const connector = await DatabaseConnectorFactory.createConnector(
|
||||
connection.db_type,
|
||||
config,
|
||||
connectionId
|
||||
);
|
||||
const tables = await connector.getTables();
|
||||
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: "테이블 목록을 조회했습니다.",
|
||||
data: tables
|
||||
data: tables,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("외부 DB 테이블 목록 조회 오류:", error);
|
||||
return {
|
||||
success: false,
|
||||
message: "테이블 목록 조회 중 오류가 발생했습니다.",
|
||||
error: error instanceof Error ? error.message : "알 수 없는 오류"
|
||||
error: error instanceof Error ? error.message : "알 수 없는 오류",
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -274,10 +301,15 @@ export class BatchManagementService {
|
||||
/**
|
||||
* 외부 DB 테이블 컬럼 정보 조회 (내부 구현)
|
||||
*/
|
||||
private static async getExternalTableColumns(connectionId: number, tableName: string): Promise<BatchApiResponse<BatchColumnInfo[]>> {
|
||||
private static async getExternalTableColumns(
|
||||
connectionId: number,
|
||||
tableName: string
|
||||
): Promise<BatchApiResponse<BatchColumnInfo[]>> {
|
||||
try {
|
||||
console.log(`[BatchManagementService] getExternalTableColumns 호출: connectionId=${connectionId}, tableName=${tableName}`);
|
||||
|
||||
console.log(
|
||||
`[BatchManagementService] getExternalTableColumns 호출: connectionId=${connectionId}, tableName=${tableName}`
|
||||
);
|
||||
|
||||
// 연결 정보 조회
|
||||
const connection = await queryOne<any>(
|
||||
`SELECT * FROM external_db_connections WHERE id = $1`,
|
||||
@@ -285,10 +317,12 @@ export class BatchManagementService {
|
||||
);
|
||||
|
||||
if (!connection) {
|
||||
console.log(`[BatchManagementService] 연결 정보를 찾을 수 없음: connectionId=${connectionId}`);
|
||||
console.log(
|
||||
`[BatchManagementService] 연결 정보를 찾을 수 없음: connectionId=${connectionId}`
|
||||
);
|
||||
return {
|
||||
success: false,
|
||||
message: "연결 정보를 찾을 수 없습니다."
|
||||
message: "연결 정보를 찾을 수 없습니다.",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -298,12 +332,12 @@ export class BatchManagementService {
|
||||
db_type: connection.db_type,
|
||||
host: connection.host,
|
||||
port: connection.port,
|
||||
database_name: connection.database_name
|
||||
database_name: connection.database_name,
|
||||
});
|
||||
|
||||
|
||||
// 비밀번호 복호화
|
||||
const decryptedPassword = PasswordEncryption.decrypt(connection.password);
|
||||
|
||||
|
||||
// 연결 설정 준비
|
||||
const config = {
|
||||
host: connection.host,
|
||||
@@ -311,38 +345,61 @@ export class BatchManagementService {
|
||||
database: connection.database_name,
|
||||
user: connection.username,
|
||||
password: decryptedPassword,
|
||||
connectionTimeoutMillis: connection.connection_timeout != null ? connection.connection_timeout * 1000 : undefined,
|
||||
queryTimeoutMillis: connection.query_timeout != null ? connection.query_timeout * 1000 : undefined,
|
||||
ssl: connection.ssl_enabled === "Y" ? { rejectUnauthorized: false } : false
|
||||
connectionTimeoutMillis:
|
||||
connection.connection_timeout != null
|
||||
? connection.connection_timeout * 1000
|
||||
: undefined,
|
||||
queryTimeoutMillis:
|
||||
connection.query_timeout != null
|
||||
? connection.query_timeout * 1000
|
||||
: undefined,
|
||||
ssl:
|
||||
connection.ssl_enabled === "Y"
|
||||
? { rejectUnauthorized: false }
|
||||
: false,
|
||||
};
|
||||
|
||||
console.log(`[BatchManagementService] 커넥터 생성 시작: db_type=${connection.db_type}`);
|
||||
|
||||
|
||||
console.log(
|
||||
`[BatchManagementService] 커넥터 생성 시작: db_type=${connection.db_type}`
|
||||
);
|
||||
|
||||
// 데이터베이스 타입에 따른 커넥터 생성
|
||||
const connector = await DatabaseConnectorFactory.createConnector(connection.db_type, config, connectionId);
|
||||
|
||||
console.log(`[BatchManagementService] 커넥터 생성 완료, 컬럼 조회 시작: tableName=${tableName}`);
|
||||
|
||||
const connector = await DatabaseConnectorFactory.createConnector(
|
||||
connection.db_type,
|
||||
config,
|
||||
connectionId
|
||||
);
|
||||
|
||||
console.log(
|
||||
`[BatchManagementService] 커넥터 생성 완료, 컬럼 조회 시작: tableName=${tableName}`
|
||||
);
|
||||
|
||||
// 컬럼 정보 조회
|
||||
console.log(`[BatchManagementService] connector.getColumns 호출 전`);
|
||||
const columns = await connector.getColumns(tableName);
|
||||
|
||||
|
||||
console.log(`[BatchManagementService] 원본 컬럼 조회 결과:`, columns);
|
||||
console.log(`[BatchManagementService] 원본 컬럼 개수:`, columns ? columns.length : 'null/undefined');
|
||||
|
||||
console.log(
|
||||
`[BatchManagementService] 원본 컬럼 개수:`,
|
||||
columns ? columns.length : "null/undefined"
|
||||
);
|
||||
|
||||
// 각 데이터베이스 커넥터의 반환 구조가 다르므로 통일된 구조로 변환
|
||||
const standardizedColumns: BatchColumnInfo[] = columns.map((col: any) => {
|
||||
console.log(`[BatchManagementService] 컬럼 변환 중:`, col);
|
||||
|
||||
|
||||
// MySQL/MariaDB 구조: {name, dataType, isNullable, defaultValue} (MySQLConnector만)
|
||||
if (col.name && col.dataType !== undefined) {
|
||||
const result = {
|
||||
column_name: col.name,
|
||||
data_type: col.dataType,
|
||||
is_nullable: col.isNullable ? 'YES' : 'NO',
|
||||
is_nullable: col.isNullable ? "YES" : "NO",
|
||||
column_default: col.defaultValue || null,
|
||||
};
|
||||
console.log(`[BatchManagementService] MySQL/MariaDB 구조로 변환:`, result);
|
||||
console.log(
|
||||
`[BatchManagementService] MySQL/MariaDB 구조로 변환:`,
|
||||
result
|
||||
);
|
||||
return result;
|
||||
}
|
||||
// PostgreSQL/Oracle/MSSQL/MariaDB 구조: {column_name, data_type, is_nullable, column_default}
|
||||
@@ -350,30 +407,41 @@ export class BatchManagementService {
|
||||
const result = {
|
||||
column_name: col.column_name || col.COLUMN_NAME,
|
||||
data_type: col.data_type || col.DATA_TYPE,
|
||||
is_nullable: col.is_nullable || col.IS_NULLABLE || (col.nullable === 'Y' ? 'YES' : 'NO'),
|
||||
is_nullable:
|
||||
col.is_nullable ||
|
||||
col.IS_NULLABLE ||
|
||||
(col.nullable === "Y" ? "YES" : "NO"),
|
||||
column_default: col.column_default || col.COLUMN_DEFAULT || null,
|
||||
};
|
||||
console.log(`[BatchManagementService] 표준 구조로 변환:`, result);
|
||||
return result;
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`[BatchManagementService] 표준화된 컬럼 목록:`, standardizedColumns);
|
||||
|
||||
|
||||
console.log(
|
||||
`[BatchManagementService] 표준화된 컬럼 목록:`,
|
||||
standardizedColumns
|
||||
);
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: standardizedColumns,
|
||||
message: "컬럼 정보를 조회했습니다."
|
||||
message: "컬럼 정보를 조회했습니다.",
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("[BatchManagementService] 외부 DB 컬럼 정보 조회 오류:", error);
|
||||
console.error("[BatchManagementService] 오류 스택:", error instanceof Error ? error.stack : 'No stack trace');
|
||||
console.error(
|
||||
"[BatchManagementService] 외부 DB 컬럼 정보 조회 오류:",
|
||||
error
|
||||
);
|
||||
console.error(
|
||||
"[BatchManagementService] 오류 스택:",
|
||||
error instanceof Error ? error.stack : "No stack trace"
|
||||
);
|
||||
return {
|
||||
success: false,
|
||||
message: "컬럼 정보 조회 중 오류가 발생했습니다.",
|
||||
error: error instanceof Error ? error.message : "알 수 없는 오류"
|
||||
error: error instanceof Error ? error.message : "알 수 없는 오류",
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user