# 화면관리 시스템 타입 문제 분석 및 해결방안

## 📋 현재 상황 분석

### 주요 시스템들

1. **화면관리 시스템** (Screen Management)
2. **제어관리 시스템** (Button Dataflow Control)
3. **테이블 타입관리 시스템** (Table Type Management)

### 발견된 문제점들

## 🚨 1. 타입 정의 분산 및 중복 문제

### 1.1 WebType 타입 정의 분산

**문제**: WebType이 여러 파일에서 서로 다르게 정의되어 불일치 발생

#### 현재 상황:

- `frontend/types/screen.ts`: 화면관리용 WebType 정의
- `backend-node/src/types/tableManagement.ts`: 테이블관리용 타입 정의
- `backend-node/prisma/schema.prisma`: DB 스키마의 web_type_standards 모델
- `frontend/lib/registry/types.ts`: 레지스트리용 WebType 정의

#### 구체적 충돌 사례:

```typescript
// frontend/types/screen.ts
export type WebType =
  | "text"
  | "number"
  | "date"
  | "code"
  | "entity"
  | "textarea"
  | "boolean"
  | "decimal"
  | "button"
  | "datetime"
  | "dropdown"
  | "text_area"
  | "checkbox"
  | "radio"
  | "file"
  | "email"
  | "tel"
  | "url";

// 실제 DB에서는 다른 web_type 값들이 존재할 수 있음
// 예: "varchar", "integer", "timestamp" 등
```

### 1.2 ButtonActionType 중복 정의

**문제**: 버튼 액션 타입이 여러 곳에서 다르게 정의됨

#### 충돌 위치:

- `frontend/types/screen.ts`: `"control"` 포함, `"modal"` 포함
- `frontend/lib/utils/buttonActions.ts`: `"cancel"` 포함, `"modal"` 포함
- `frontend/hooks/admin/useButtonActions.ts`: DB 스키마 기반 정의

#### 문제 코드:

```typescript
// frontend/types/screen.ts
export type ButtonActionType =
  | "save"
  | "delete"
  | "edit"
  | "add"
  | "search"
  | "reset"
  | "submit"
  | "close"
  | "popup"
  | "modal"
  | "newWindow"
  | "navigate"
  | "control";

// frontend/lib/utils/buttonActions.ts
export type ButtonActionType =
  | "save"
  | "cancel"
  | "delete"
  | "edit"
  | "add"
  | "search"
  | "reset"
  | "submit"
  | "close"
  | "popup"
  | "navigate"
  | "modal"
  | "newWindow";
```

## 🚨 2. 데이터베이스 스키마와 TypeScript 타입 불일치

### 2.1 web_type_standards 테이블 불일치

**문제**: Prisma 스키마와 TypeScript 인터페이스 간 필드명/타입 차이

#### DB 스키마:

```sql
model web_type_standards {
  web_type         String    @id @db.VarChar(50)
  type_name        String    @db.VarChar(100)
  type_name_eng    String?   @db.VarChar(100)
  description      String?
  category         String?   @default("input") @db.VarChar(50)
  default_config   Json?     -- JSON 타입
  validation_rules Json?     -- JSON 타입
  component_name   String?   @default("TextWidget") @db.VarChar(100)
  config_panel     String?   @db.VarChar(100)
}
```

#### TypeScript 인터페이스:

```typescript
export interface WebTypeDefinition {
  id: string; // web_type와 매핑되지 않음
  name: string; // type_name과 매핑?
  category: string;
  description: string;
  defaultConfig: Record<string, any>; // default_config Json과 타입 불일치
  validationRules?: Record<string, any>; // validation_rules Json과 타입 불일치
  isActive: boolean; // DB에는 is_active String 필드
}
```

### 2.2 ColumnInfo 타입 불일치

**문제**: 테이블 컬럼 정보 타입이 프론트엔드/백엔드에서 다름

#### 백엔드 타입:

```typescript
// backend-node/src/types/tableManagement.ts
export interface ColumnTypeInfo {
  columnName: string;
  displayName: string;
  dataType: string;
  dbType: string;
  webType: string; // string 타입
  inputType?: "direct" | "auto";
  detailSettings: string; // JSON 문자열
  isNullable: string; // "Y" | "N" 문자열
  isPrimaryKey: boolean;
}
```

#### 프론트엔드 타입:

```typescript
// frontend/types/screen.ts
export interface ColumnInfo {
  tableName: string;
  columnName: string;
  columnLabel?: string;
  dataType: string;
  webType?: WebType; // WebType union 타입 (불일치!)
  inputType?: "direct" | "auto";
  isNullable: string;
  detailSettings?: string; // optional vs required 차이
}
```

## 🚨 3. 컴포넌트 인터페이스 타입 안전성 문제

### 3.1 ComponentData 타입 캐스팅 문제

**문제**: 런타임에 타입 안전성이 보장되지 않는 강제 캐스팅

#### 문제 코드:

```typescript
// frontend/components/screen/RealtimePreview.tsx
const widget = component as WidgetComponent; // 위험한 강제 캐스팅

// frontend/components/screen/InteractiveScreenViewer.tsx
component: any; // any 타입으로 타입 안전성 상실
```

### 3.2 DynamicWebTypeRenderer Props 불일치

**문제**: 동적 렌더링 시 props 타입이 일관되지 않음

#### 문제 위치:

```typescript
// frontend/lib/registry/DynamicWebTypeRenderer.tsx
export interface DynamicComponentProps {
  webType: string;          // WebType이 아닌 string
  props?: Record<string, any>;  // any 타입 사용
  config?: Record<string, any>; // any 타입 사용
  onEvent?: (event: string, data: any) => void; // any 타입
}

// 실제 사용 시
<DynamicWebTypeRenderer
  webType={component.webType || "text"}  // WebType | undefined 전달
  config={component.webTypeConfig}       // WebTypeConfig 타입 전달
  props={{
    component: component,               // ComponentData 타입
    value: formData[component.columnName || component.id] || "",
    onChange: (value: any) => {...}    // any 타입 콜백
  }}
/>
```

## 🚨 4. 제어관리 시스템 타입 문제

### 4.1 ButtonDataflowConfig 타입 복잡성

**문제**: 제어관리 설정이 복잡하고 타입 안전성 부족

#### 현재 타입:

```typescript
export interface ButtonDataflowConfig {
  controlMode: "simple" | "advanced";
  selectedDiagramId?: number;
  selectedRelationshipId?: number;
  directControl?: {
    conditions: DataflowCondition[]; // 복잡한 중첩 타입
    actions: any[]; // any 타입 사용
  };
}
```

### 4.2 OptimizedButtonDataflowService 타입 문제

**문제**: 서비스 클래스에서 any 타입 남용으로 타입 안전성 상실

#### Linter 오류 (57개):

- `Unexpected any` 경고 26개
- `unknown` 타입 오류 2개
- 사용되지 않는 변수 경고 29개

## 🎯 해결방안 및 구현 계획

## Phase 1: 중앙집중식 타입 정의 통합 (우선순위: 높음)

### 1.1 통합 타입 파일 생성

```
frontend/types/
├── v2-core.ts          # 핵심 공통 타입들
├── screen-management.ts     # 화면관리 전용 타입
├── control-management.ts    # 제어관리 전용 타입
├── table-management.ts      # 테이블관리 전용 타입
└── index.ts                # 모든 타입 re-export
```

### 1.2 WebType 통합 정의

```typescript
// frontend/types/v2-core.ts
export type WebType =
  | "text"
  | "number"
  | "decimal"
  | "date"
  | "datetime"
  | "select"
  | "dropdown"
  | "radio"
  | "checkbox"
  | "boolean"
  | "textarea"
  | "code"
  | "entity"
  | "file"
  | "email"
  | "tel"
  | "url"
  | "button";

// DB에서 동적으로 로드되는 웹타입도 지원
export type DynamicWebType = WebType | string;
```

### 1.3 ButtonActionType 통합 정의

```typescript
// frontend/types/v2-core.ts
export type ButtonActionType =
  | "save"
  | "cancel"
  | "delete"
  | "edit"
  | "add"
  | "search"
  | "reset"
  | "submit"
  | "close"
  | "popup"
  | "modal"
  | "navigate"
  | "control";
```

## Phase 2: 데이터베이스 타입 매핑 표준화 (우선순위: 높음)

### 2.1 Prisma 스키마 기반 타입 생성

```typescript
// frontend/types/database-mappings.ts
import { web_type_standards, button_action_standards } from "@prisma/client";

// Prisma 타입을 프론트엔드 타입으로 변환하는 매퍼
export type WebTypeStandard = web_type_standards;

export interface WebTypeDefinition {
  webType: string; // web_type 필드
  typeName: string; // type_name 필드
  typeNameEng?: string; // type_name_eng 필드
  description?: string;
  category: string;
  defaultConfig: Record<string, any>; // Json 타입 매핑
  validationRules?: Record<string, any>; // Json 타입 매핑
  componentName?: string; // component_name 필드
  configPanel?: string; // config_panel 필드
  isActive: boolean; // is_active "Y"/"N" → boolean 변환
}

// 변환 함수
export const mapWebTypeStandardToDefinition = (
  standard: WebTypeStandard
): WebTypeDefinition => ({
  webType: standard.web_type,
  typeName: standard.type_name,
  typeNameEng: standard.type_name_eng || undefined,
  description: standard.description || undefined,
  category: standard.category || "input",
  defaultConfig: (standard.default_config as any) || {},
  validationRules: (standard.validation_rules as any) || undefined,
  componentName: standard.component_name || undefined,
  configPanel: standard.config_panel || undefined,
  isActive: standard.is_active === "Y",
});
```

### 2.2 ColumnInfo 타입 통합

```typescript
// frontend/types/table-management.ts
export interface V2ColumnInfo {
  // 공통 필드
  tableName: string;
  columnName: string;
  displayName: string;
  dataType: string; // DB 데이터 타입
  webType: DynamicWebType; // 웹 타입 (동적 지원)

  // 상세 정보
  inputType: "direct" | "auto";
  detailSettings?: Record<string, any>; // JSON 파싱된 객체
  description?: string;
  isNullable: boolean; // "Y"/"N" → boolean 변환
  isPrimaryKey: boolean;

  // 표시 옵션
  isVisible?: boolean;
  displayOrder?: number;

  // 메타데이터
  maxLength?: number;
  numericPrecision?: number;
  numericScale?: number;
  defaultValue?: string;

  // 참조 관계
  codeCategory?: string;
  referenceTable?: string;
  referenceColumn?: string;
  displayColumn?: string;
}
```

## Phase 3: 컴포넌트 타입 안전성 강화 (우선순위: 중간)

### 3.1 ComponentData 타입 가드 구현

```typescript
// frontend/types/screen-management.ts
export type ComponentData =
  | ContainerComponent
  | WidgetComponent
  | GroupComponent
  | DataTableComponent;

// 타입 가드 함수들
export const isWidgetComponent = (
  component: ComponentData
): component is WidgetComponent => {
  return component.type === "widget";
};

export const isContainerComponent = (
  component: ComponentData
): component is ContainerComponent => {
  return component.type === "container";
};

// 안전한 타입 캐스팅 유틸리티
export const asWidgetComponent = (
  component: ComponentData
): WidgetComponent => {
  if (!isWidgetComponent(component)) {
    throw new Error(`Expected WidgetComponent, got ${component.type}`);
  }
  return component;
};
```

### 3.2 DynamicWebTypeRenderer Props 타입 강화

```typescript
// frontend/lib/registry/types.ts
export interface StrictDynamicComponentProps {
  webType: DynamicWebType;
  component: ComponentData;
  config?: WebTypeConfig;
  value?: unknown;
  onChange?: (value: unknown) => void;
  onEvent?: (event: WebTypeEvent) => void;
  readonly?: boolean;
  required?: boolean;
  className?: string;
}

export interface WebTypeEvent {
  type: "change" | "blur" | "focus" | "click";
  value: unknown;
  field?: string;
}

export type WebTypeConfig = Record<string, unknown>;
```

## Phase 4: 제어관리 시스템 타입 정리 (우선순위: 중간)

### 4.1 ButtonDataflowConfig 타입 명확화

```typescript
// frontend/types/control-management.ts
export interface ButtonDataflowConfig {
  // 기본 설정
  controlMode: "simple" | "advanced";

  // 관계도 방식
  selectedDiagramId?: number;
  selectedRelationshipId?: number;

  // 직접 설정 방식
  directControl?: DirectControlConfig;
}

export interface DirectControlConfig {
  conditions: DataflowCondition[];
  actions: DataflowAction[];
  logic?: "AND" | "OR";
}

export interface DataflowCondition {
  id: string;
  type: "condition" | "group";
  field?: string;
  operator?: ConditionOperator;
  value?: unknown;
  dataSource?: "form" | "table-selection" | "both";
}

export interface DataflowAction {
  id: string;
  type: ActionType;
  tableName?: string;
  operation?: "INSERT" | "UPDATE" | "DELETE" | "SELECT";
  fields?: ActionField[];
  conditions?: DataflowCondition[];
}

export type ConditionOperator =
  | "="
  | "!="
  | ">"
  | "<"
  | ">="
  | "<="
  | "LIKE"
  | "IN"
  | "NOT IN";
export type ActionType = "database" | "api" | "notification" | "redirect";
```

### 4.2 OptimizedButtonDataflowService 타입 정리

```typescript
// frontend/lib/services/optimizedButtonDataflowService.ts

// any 타입 제거 및 구체적 타입 정의
export interface ExecutionContext {
  formData: Record<string, unknown>;
  selectedRows?: unknown[];
  selectedRowsData?: Record<string, unknown>[];
  controlDataSource: ControlDataSource;
  buttonId: string;
  componentData?: ComponentData;
  timestamp: string;
  clickCount?: number;
}

export interface ActionResult {
  success: boolean;
  message: string;
  data?: Record<string, unknown>;
  error?: string;
}

export interface ValidationResult {
  success: boolean;
  message?: string;
  canExecuteImmediately: boolean;
  actions?: DataflowAction[];
}
```

## Phase 5: 마이그레이션 및 검증 (우선순위: 낮음)

### 5.1 점진적 마이그레이션 계획

1. **Step 1**: 새로운 통합 타입 파일들 생성
2. **Step 2**: 기존 파일들에서 새 타입 import로 변경
3. **Step 3**: 타입 가드 및 유틸리티 함수 적용
4. **Step 4**: any 타입 제거 및 구체적 타입 적용
5. **Step 5**: 기존 타입 정의 파일들 제거

### 5.2 검증 도구 구축

```typescript
// scripts/type-validation.ts
// 타입 일관성 검증 스크립트 작성
// DB 스키마와 TypeScript 타입 간 일치성 검증
// 컴포넌트 Props 타입 검증
```

## 📋 구현 우선순위

### 🔥 즉시 해결 필요 (Critical)

1. **WebType 통합** - 가장 많이 사용되는 기본 타입
2. **ButtonActionType 통합** - 제어관리 시스템 안정성 확보
3. **ColumnInfo 타입 표준화** - 테이블 관리 기능 정상화

### ⚡ 단기간 해결 (High)

4. **ComponentData 타입 가드** - 런타임 안전성 확보
5. **DB 타입 매핑** - 프론트엔드/백엔드 연동 안정화
6. **DynamicWebTypeRenderer Props 정리** - 동적 렌더링 안정성

### 📅 중장기 해결 (Medium)

7. **OptimizedButtonDataflowService any 타입 제거** - 코드 품질 향상
8. **ButtonDataflowConfig 구조 개선** - 제어관리 시스템 고도화
9. **타입 검증 도구 구축** - 지속적인 품질 관리

## 💡 기대 효과

### 개발 경험 개선

- 타입 자동완성 정확도 향상
- 컴파일 타임 오류 감소
- IDE 지원 기능 활용도 증대

### 시스템 안정성 향상

- 런타임 타입 오류 방지
- API 연동 안정성 확보
- 데이터 일관성 보장

### 유지보수성 향상

- 코드 가독성 개선
- 리팩토링 안정성 확보
- 새 기능 추가 시 사이드 이펙트 최소화

---

## 🚀 다음 단계

이 분석을 바탕으로 다음과 같은 단계로 진행하는 것을 권장합니다:

1. **우선순위 검토**: 위의 우선순위가 프로젝트 상황에 적합한지 검토
2. **Phase 1 착수**: 통합 타입 파일 생성부터 시작
3. **점진적 적용**: 한 번에 모든 것을 바꾸지 말고 단계적으로 적용
4. **테스트 강화**: 타입 변경 시마다 충분한 테스트 수행

이 계획에 대한 의견이나 수정사항이 있으시면 말씀해 주세요.
