302 lines
7.7 KiB
Markdown
302 lines
7.7 KiB
Markdown
|
|
# 테이블 타입 관리 개선 사용 가이드
|
||
|
|
|
||
|
|
## 🎯 개선 내용 요약
|
||
|
|
|
||
|
|
테이블 타입 관리 시스템이 다음과 같이 개선되었습니다:
|
||
|
|
|
||
|
|
### 주요 변경사항
|
||
|
|
|
||
|
|
- **용어 통일**: 웹 타입 → **입력 타입**
|
||
|
|
- **타입 단순화**: 20개 → **8개 핵심 타입**
|
||
|
|
- **DB 타입 제거**: dbType 필드 완전 삭제
|
||
|
|
- **저장 방식**: 모든 사용자 정의 컬럼을 **VARCHAR(500)로 통일**
|
||
|
|
- **형변환**: 애플리케이션 레벨에서 입력 타입별 처리
|
||
|
|
|
||
|
|
## 📋 8개 핵심 입력 타입
|
||
|
|
|
||
|
|
| 번호 | 입력 타입 | 설명 | 예시 | 저장 형태 |
|
||
|
|
| ---- | ---------- | ---------- | -------------------- | ------------ |
|
||
|
|
| 1 | `text` | 텍스트 | 이름, 제목, 설명 | "홍길동" |
|
||
|
|
| 2 | `number` | 숫자 | 수량, 건수, 순번 | "15000.50" |
|
||
|
|
| 3 | `date` | 날짜 | 생성일, 완료일, 기한 | "2024-03-15" |
|
||
|
|
| 4 | `code` | 코드 | 상태코드, 유형코드 | "ACTIVE" |
|
||
|
|
| 5 | `entity` | 엔티티 | 고객선택, 제품선택 | "123" |
|
||
|
|
| 6 | `select` | 선택박스 | 드롭다운 목록 | "option1" |
|
||
|
|
| 7 | `checkbox` | 체크박스 | Y/N, 사용여부 | "Y" / "N" |
|
||
|
|
| 8 | `radio` | 라디오버튼 | 단일선택 옵션 | "high" |
|
||
|
|
|
||
|
|
## 🚀 마이그레이션 실행
|
||
|
|
|
||
|
|
### 1. 데이터베이스 마이그레이션
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# 백엔드 디렉토리에서 실행
|
||
|
|
cd backend-node
|
||
|
|
node scripts/migrate-to-input-types.js
|
||
|
|
```
|
||
|
|
|
||
|
|
**실행 결과:**
|
||
|
|
|
||
|
|
- `web_type` → `input_type` 컬럼명 변경
|
||
|
|
- `db_type` 컬럼 제거
|
||
|
|
- 기존 웹 타입을 8개 입력 타입으로 자동 변환
|
||
|
|
- 기존 데이터 백업 (`table_type_columns_backup`)
|
||
|
|
|
||
|
|
### 2. 서비스 재시작
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# 백엔드 서비스 재시작
|
||
|
|
npm run dev
|
||
|
|
|
||
|
|
# 프론트엔드 서비스 재시작 (별도 터미널)
|
||
|
|
cd ../frontend
|
||
|
|
npm run dev
|
||
|
|
```
|
||
|
|
|
||
|
|
## 💻 사용법
|
||
|
|
|
||
|
|
### 1. 테이블 생성
|
||
|
|
|
||
|
|
새로운 테이블 생성 시 자동으로 기본 컬럼이 추가됩니다:
|
||
|
|
|
||
|
|
```sql
|
||
|
|
CREATE TABLE "products" (
|
||
|
|
-- 기본 컬럼 (자동 추가)
|
||
|
|
"id" serial PRIMARY KEY,
|
||
|
|
"created_date" timestamp DEFAULT now(),
|
||
|
|
"updated_date" timestamp DEFAULT now(),
|
||
|
|
"writer" varchar(100),
|
||
|
|
"company_code" varchar(50) DEFAULT '*',
|
||
|
|
|
||
|
|
-- 사용자 정의 컬럼 (모두 VARCHAR(500))
|
||
|
|
"product_name" varchar(500), -- 입력타입: text
|
||
|
|
"price" varchar(500), -- 입력타입: number
|
||
|
|
"launch_date" varchar(500), -- 입력타입: date
|
||
|
|
"is_active" varchar(500) -- 입력타입: checkbox
|
||
|
|
);
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2. 데이터 입력/조회
|
||
|
|
|
||
|
|
#### 백엔드에서 데이터 처리
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
import { InputTypeService } from "./services/inputTypeService";
|
||
|
|
|
||
|
|
// 데이터 저장 시
|
||
|
|
const inputData = {
|
||
|
|
product_name: "테스트 제품",
|
||
|
|
price: 15000.5,
|
||
|
|
launch_date: new Date("2024-03-15"),
|
||
|
|
is_active: true,
|
||
|
|
};
|
||
|
|
|
||
|
|
const columnTypes = {
|
||
|
|
product_name: "text",
|
||
|
|
price: "number",
|
||
|
|
launch_date: "date",
|
||
|
|
is_active: "checkbox",
|
||
|
|
};
|
||
|
|
|
||
|
|
// 저장용 변환 (모든 값을 문자열로)
|
||
|
|
const convertedData = InputTypeService.convertBatchForStorage(
|
||
|
|
inputData,
|
||
|
|
columnTypes
|
||
|
|
);
|
||
|
|
// 결과: { product_name: "테스트 제품", price: "15000.5", launch_date: "2024-03-15", is_active: "Y" }
|
||
|
|
|
||
|
|
// 데이터베이스에 저장
|
||
|
|
await prisma.products.create({ data: convertedData });
|
||
|
|
```
|
||
|
|
|
||
|
|
#### 데이터 조회 시
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
// 데이터베이스에서 조회 (모든 값이 문자열)
|
||
|
|
const rawData = await prisma.products.findFirst();
|
||
|
|
// 결과: { product_name: "테스트 제품", price: "15000.5", launch_date: "2024-03-15", is_active: "Y" }
|
||
|
|
|
||
|
|
// 표시용 변환 (적절한 타입으로)
|
||
|
|
const displayData = InputTypeService.convertBatchForDisplay(
|
||
|
|
rawData,
|
||
|
|
columnTypes
|
||
|
|
);
|
||
|
|
// 결과: { product_name: "테스트 제품", price: 15000.5, launch_date: "2024-03-15", is_active: true }
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3. 프론트엔드에서 사용
|
||
|
|
|
||
|
|
#### 테이블 관리 화면
|
||
|
|
|
||
|
|
1. **관리자 > 테이블 관리** 메뉴 접속
|
||
|
|
2. 테이블 선택 후 컬럼 목록 확인
|
||
|
|
3. **입력 타입** 컬럼에서 8개 타입 중 선택
|
||
|
|
4. **DB 타입** 컬럼은 제거됨 (더 이상 표시되지 않음)
|
||
|
|
|
||
|
|
#### 화면 관리 시스템 연동
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
import { INPUT_TYPE_OPTIONS } from "@/types/input-types";
|
||
|
|
|
||
|
|
// 입력 타입 옵션 사용
|
||
|
|
const inputTypeSelect = (
|
||
|
|
<Select>
|
||
|
|
{INPUT_TYPE_OPTIONS.map((option) => (
|
||
|
|
<SelectItem key={option.value} value={option.value}>
|
||
|
|
{option.label} - {option.description}
|
||
|
|
</SelectItem>
|
||
|
|
))}
|
||
|
|
</Select>
|
||
|
|
);
|
||
|
|
```
|
||
|
|
|
||
|
|
## 🧪 테스트
|
||
|
|
|
||
|
|
### 전체 시스템 테스트
|
||
|
|
|
||
|
|
```bash
|
||
|
|
cd backend-node
|
||
|
|
node scripts/test-input-type-system.js
|
||
|
|
```
|
||
|
|
|
||
|
|
**테스트 내용:**
|
||
|
|
|
||
|
|
- ✅ 테이블 생성 (기본 컬럼 자동 추가)
|
||
|
|
- ✅ VARCHAR(500) 통일 저장
|
||
|
|
- ✅ 입력 타입별 형변환
|
||
|
|
- ✅ 배치 데이터 처리
|
||
|
|
- ✅ 입력값 검증
|
||
|
|
- ✅ 성능 테스트
|
||
|
|
|
||
|
|
## 🔧 개발자 가이드
|
||
|
|
|
||
|
|
### 새로운 입력 타입 추가
|
||
|
|
|
||
|
|
1. **타입 정의 업데이트**
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
// frontend/types/input-types.ts & backend-node/src/types/input-types.ts
|
||
|
|
export type InputType =
|
||
|
|
| "text"
|
||
|
|
| "number"
|
||
|
|
| "date"
|
||
|
|
| "code"
|
||
|
|
| "entity"
|
||
|
|
| "select"
|
||
|
|
| "checkbox"
|
||
|
|
| "radio"
|
||
|
|
| "new_type"; // 새 타입 추가
|
||
|
|
```
|
||
|
|
|
||
|
|
2. **변환 로직 추가**
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
// backend-node/src/services/inputTypeService.ts
|
||
|
|
case "new_type":
|
||
|
|
return processNewType(value);
|
||
|
|
```
|
||
|
|
|
||
|
|
3. **UI 옵션 추가**
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
// frontend/types/input-types.ts
|
||
|
|
export const INPUT_TYPE_OPTIONS = [
|
||
|
|
// ... 기존 옵션들
|
||
|
|
{
|
||
|
|
value: "new_type",
|
||
|
|
label: "새 타입",
|
||
|
|
description: "새로운 입력 타입",
|
||
|
|
category: "basic",
|
||
|
|
},
|
||
|
|
];
|
||
|
|
```
|
||
|
|
|
||
|
|
### API 엔드포인트
|
||
|
|
|
||
|
|
#### 입력 타입 변경
|
||
|
|
|
||
|
|
```http
|
||
|
|
PUT /api/table-management/tables/{tableName}/columns/{columnName}/input-type
|
||
|
|
Content-Type: application/json
|
||
|
|
|
||
|
|
{
|
||
|
|
"inputType": "number",
|
||
|
|
"detailSettings": "{}"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
#### 컬럼 입력 타입 조회
|
||
|
|
|
||
|
|
```http
|
||
|
|
GET /api/table-management/tables/{tableName}/input-types
|
||
|
|
```
|
||
|
|
|
||
|
|
## ⚠️ 주의사항
|
||
|
|
|
||
|
|
### 1. 데이터 검증 강화 필요
|
||
|
|
|
||
|
|
VARCHAR 통일 방식에서는 애플리케이션 레벨 검증이 중요합니다:
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
// 반드시 검증 후 저장
|
||
|
|
const validation = InputTypeService.validate(value, inputType);
|
||
|
|
if (!validation.isValid) {
|
||
|
|
throw new Error(validation.message);
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2. 기존 데이터 호환성
|
||
|
|
|
||
|
|
- **기존 테이블**: 현재 타입 구조 유지
|
||
|
|
- **신규 테이블**: 새로운 입력 타입 체계 적용
|
||
|
|
- **점진적 전환**: 필요에 따라 기존 테이블도 단계적 전환
|
||
|
|
|
||
|
|
### 3. 성능 고려사항
|
||
|
|
|
||
|
|
- 대용량 데이터 처리 시 배치 변환 사용
|
||
|
|
- 자주 사용되는 변환 결과는 캐싱 고려
|
||
|
|
- 복잡한 검증 로직은 비동기 처리
|
||
|
|
|
||
|
|
## 🆘 문제 해결
|
||
|
|
|
||
|
|
### 마이그레이션 실패 시 롤백
|
||
|
|
|
||
|
|
```sql
|
||
|
|
-- 1. 기존 테이블 삭제
|
||
|
|
DROP TABLE table_type_columns;
|
||
|
|
|
||
|
|
-- 2. 백업에서 복원
|
||
|
|
ALTER TABLE table_type_columns_backup RENAME TO table_type_columns;
|
||
|
|
```
|
||
|
|
|
||
|
|
### 입력 타입 변환 오류
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
// 안전한 변환을 위한 try-catch 사용
|
||
|
|
try {
|
||
|
|
const converted = InputTypeService.convertForStorage(value, inputType);
|
||
|
|
return converted;
|
||
|
|
} catch (error) {
|
||
|
|
logger.error("변환 실패", { value, inputType, error });
|
||
|
|
return String(value); // 기본값으로 문자열 반환
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### UI에서 입력 타입이 표시되지 않는 경우
|
||
|
|
|
||
|
|
1. 브라우저 캐시 클리어
|
||
|
|
2. 프론트엔드 서비스 재시작
|
||
|
|
3. `INPUT_TYPE_OPTIONS` import 확인
|
||
|
|
|
||
|
|
## 📞 지원
|
||
|
|
|
||
|
|
문제가 발생하거나 추가 기능이 필요한 경우:
|
||
|
|
|
||
|
|
1. **로그 확인**: 백엔드 콘솔에서 상세 로그 확인
|
||
|
|
2. **테스트 실행**: `test-input-type-system.js`로 시스템 상태 점검
|
||
|
|
3. **데이터 백업**: 중요한 변경 전 항상 백업 실행
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
**🎉 테이블 타입 관리 개선으로 더욱 유연하고 안정적인 시스템을 경험하세요!**
|