테이블 추가기능 수정사항

This commit is contained in:
kjs
2025-09-23 10:40:21 +09:00
parent 474cc33aee
commit e653effac0
19 changed files with 1931 additions and 201 deletions

View File

@@ -342,14 +342,11 @@ export class DDLExecutionService {
tableName: string,
columns: CreateColumnDefinition[]
): string {
// 사용자 정의 컬럼들
// 사용자 정의 컬럼들 - 모두 VARCHAR(500)로 통일
const columnDefinitions = columns
.map((col) => {
const postgresType = this.mapWebTypeToPostgresType(
col.webType,
col.length
);
let definition = `"${col.name}" ${postgresType}`;
// 입력 타입과 관계없이 모든 컬럼을 VARCHAR(500)로 생성
let definition = `"${col.name}" varchar(500)`;
if (!col.nullable) {
definition += " NOT NULL";
@@ -363,13 +360,13 @@ export class DDLExecutionService {
})
.join(",\n ");
// 기본 컬럼들 (시스템 필수 컬럼)
// 기본 컬럼들 (날짜는 TIMESTAMP, 나머지는 VARCHAR)
const baseColumns = `
"id" serial PRIMARY KEY,
"id" varchar(500) PRIMARY KEY DEFAULT gen_random_uuid()::text,
"created_date" timestamp DEFAULT now(),
"updated_date" timestamp DEFAULT now(),
"writer" varchar(100),
"company_code" varchar(50) DEFAULT '*'`;
"writer" varchar(500),
"company_code" varchar(500)`;
// 최종 CREATE TABLE 쿼리
return `
@@ -385,11 +382,8 @@ CREATE TABLE "${tableName}" (${baseColumns},
tableName: string,
column: CreateColumnDefinition
): string {
const postgresType = this.mapWebTypeToPostgresType(
column.webType,
column.length
);
let definition = `"${column.name}" ${postgresType}`;
// 새로 추가되는 컬럼도 VARCHAR(500)로 통일
let definition = `"${column.name}" varchar(500)`;
if (!column.nullable) {
definition += " NOT NULL";
@@ -403,23 +397,27 @@ CREATE TABLE "${tableName}" (${baseColumns},
}
/**
* 타입을 PostgreSQL 타입으로 매핑
* 입력타입을 PostgreSQL 타입으로 매핑 (날짜는 TIMESTAMP, 나머지는 VARCHAR)
* 날짜 타입만 TIMESTAMP로, 나머지는 VARCHAR(500)로 통일
*/
private mapInputTypeToPostgresType(inputType?: string): string {
switch (inputType) {
case "date":
return "timestamp";
default:
// 날짜 외의 모든 타입은 VARCHAR(500)로 통일
return "varchar(500)";
}
}
/**
* 레거시 지원: 웹타입을 PostgreSQL 타입으로 매핑
* @deprecated 새로운 시스템에서는 mapInputTypeToPostgresType 사용
*/
private mapWebTypeToPostgresType(webType: WebType, length?: number): string {
const mapping = WEB_TYPE_TO_POSTGRES_MAP[webType];
if (!mapping) {
logger.warn(`알 수 없는 웹타입: ${webType}, text로 대체`);
return "text";
}
if (mapping.supportsLength && length && length > 0) {
if (mapping.postgresType === "varchar") {
return `varchar(${length})`;
}
}
return mapping.postgresType;
// 레거시 지원을 위해 유지하되, VARCHAR(500)로 통일
logger.info(`레거시 웹타입 사용: ${webType} → varchar(500)로 변환`);
return "varchar(500)";
}
/**
@@ -472,6 +470,127 @@ CREATE TABLE "${tableName}" (${baseColumns},
},
});
// 기본 컬럼들 정의 (모든 테이블에 자동으로 추가되는 시스템 컬럼)
const defaultColumns = [
{
name: "id",
label: "ID",
inputType: "text",
description: "기본키 (자동생성)",
order: -5,
isVisible: true,
},
{
name: "created_date",
label: "생성일시",
inputType: "date",
description: "레코드 생성일시",
order: -4,
isVisible: true,
},
{
name: "updated_date",
label: "수정일시",
inputType: "date",
description: "레코드 수정일시",
order: -3,
isVisible: true,
},
{
name: "writer",
label: "작성자",
inputType: "text",
description: "레코드 작성자",
order: -2,
isVisible: true,
},
{
name: "company_code",
label: "회사코드",
inputType: "text",
description: "회사 구분 코드",
order: -1,
isVisible: true,
},
];
// 기본 컬럼들을 table_type_columns에 등록
for (const defaultCol of defaultColumns) {
await tx.$executeRaw`
INSERT INTO table_type_columns (
table_name, column_name, input_type, detail_settings,
is_nullable, display_order, created_date, updated_date
) VALUES (
${tableName}, ${defaultCol.name}, ${defaultCol.inputType}, '{}',
'Y', ${defaultCol.order}, now(), now()
)
ON CONFLICT (table_name, column_name)
DO UPDATE SET
input_type = ${defaultCol.inputType},
display_order = ${defaultCol.order},
updated_date = now();
`;
}
// 사용자 정의 컬럼들을 table_type_columns에 등록
for (let i = 0; i < columns.length; i++) {
const column = columns[i];
const inputType = this.convertWebTypeToInputType(
column.webType || "text"
);
await tx.$executeRaw`
INSERT INTO table_type_columns (
table_name, column_name, input_type, detail_settings,
is_nullable, display_order, created_date, updated_date
) VALUES (
${tableName}, ${column.name}, ${inputType}, ${JSON.stringify(column.detailSettings || {})},
'Y', ${i}, now(), now()
)
ON CONFLICT (table_name, column_name)
DO UPDATE SET
input_type = ${inputType},
detail_settings = ${JSON.stringify(column.detailSettings || {})},
display_order = ${i},
updated_date = now();
`;
}
// 레거시 지원: column_labels 테이블에도 등록 (기존 시스템 호환성)
// 1. 기본 컬럼들을 column_labels에 등록
for (const defaultCol of defaultColumns) {
await tx.column_labels.upsert({
where: {
table_name_column_name: {
table_name: tableName,
column_name: defaultCol.name,
},
},
update: {
column_label: defaultCol.label,
input_type: defaultCol.inputType,
detail_settings: JSON.stringify({}),
description: defaultCol.description,
display_order: defaultCol.order,
is_visible: defaultCol.isVisible,
updated_date: new Date(),
},
create: {
table_name: tableName,
column_name: defaultCol.name,
column_label: defaultCol.label,
input_type: defaultCol.inputType,
detail_settings: JSON.stringify({}),
description: defaultCol.description,
display_order: defaultCol.order,
is_visible: defaultCol.isVisible,
created_date: new Date(),
updated_date: new Date(),
},
});
}
// 2. 사용자 정의 컬럼들을 column_labels에 등록
for (const column of columns) {
await tx.column_labels.upsert({
where: {
@@ -482,7 +601,7 @@ CREATE TABLE "${tableName}" (${baseColumns},
},
update: {
column_label: column.label || column.name,
web_type: column.webType,
input_type: this.convertWebTypeToInputType(column.webType || "text"),
detail_settings: JSON.stringify(column.detailSettings || {}),
description: column.description,
display_order: column.order || 0,
@@ -493,7 +612,7 @@ CREATE TABLE "${tableName}" (${baseColumns},
table_name: tableName,
column_name: column.name,
column_label: column.label || column.name,
web_type: column.webType,
input_type: this.convertWebTypeToInputType(column.webType || "text"),
detail_settings: JSON.stringify(column.detailSettings || {}),
description: column.description,
display_order: column.order || 0,
@@ -505,6 +624,47 @@ CREATE TABLE "${tableName}" (${baseColumns},
}
}
/**
* 웹 타입을 입력 타입으로 변환
*/
private convertWebTypeToInputType(webType: string): string {
const webTypeToInputTypeMap: Record<string, string> = {
// 텍스트 관련
text: "text",
textarea: "text",
email: "text",
tel: "text",
url: "text",
password: "text",
// 숫자 관련
number: "number",
decimal: "number",
// 날짜 관련
date: "date",
datetime: "date",
time: "date",
// 선택 관련
select: "select",
dropdown: "select",
checkbox: "checkbox",
boolean: "checkbox",
radio: "radio",
// 참조 관련
code: "code",
entity: "entity",
// 기타
file: "text",
button: "text",
};
return webTypeToInputTypeMap[webType] || "text";
}
/**
* 권한 검증 (슈퍼관리자 확인)
*/