# 코드 채번 규칙 컴포넌트 구현 계획서

## 문서 정보
- **작성일**: 2025-11-03
- **목적**: Shadcn/ui 가이드라인 기반 코드 채번 규칙 컴포넌트 구현
- **우선순위**: 중간
- **디자인 원칙**: 심플하고 깔끔한 UI, 중첩 박스 금지, 일관된 컬러 시스템

---

## 1. 기능 요구사항

### 1.1 핵심 기능
- 코드 채번 규칙 생성/수정/삭제
- 동적 규칙 파트 추가/삭제 (최대 6개)
- 실시간 코드 미리보기
- 규칙 순서 조정
- 데이터베이스 저장 및 불러오기

### 1.2 UI 요구사항
- 좌측: 코드 목록 (선택적)
- 우측: 규칙 설정 영역
- 상단: 코드 미리보기 + 규칙명
- 중앙: 규칙 카드 리스트
- 하단: 규칙 추가 + 저장 버튼

---

## 2. 디자인 시스템 (Shadcn/ui 기반)

### 2.1 색상 사용 규칙

```tsx
// 배경
bg-background          // 페이지 배경
bg-card                // 카드 배경
bg-muted               // 약한 배경 (미리보기 등)

// 텍스트
text-foreground        // 기본 텍스트
text-muted-foreground  // 보조 텍스트
text-primary           // 강조 텍스트

// 테두리
border-border          // 기본 테두리
border-input           // 입력 필드 테두리

// 버튼
bg-primary             // 주요 버튼 (저장, 추가)
bg-destructive         // 삭제 버튼
variant="outline"      // 보조 버튼 (취소)
variant="ghost"        // 아이콘 버튼
```

### 2.2 간격 시스템

```tsx
// 카드 간 간격
gap-6                  // 24px (카드 사이)

// 카드 내부 패딩
p-6                    // 24px (CardContent)

// 폼 필드 간격
space-y-4              // 16px (입력 필드들)
space-y-3              // 12px (모바일)

// 섹션 간격
space-y-6              // 24px (큰 섹션)
```

### 2.3 타이포그래피

```tsx
// 페이지 제목
text-2xl font-semibold

// 섹션 제목
text-lg font-semibold

// 카드 제목
text-base font-semibold

// 라벨
text-sm font-medium

// 본문 텍스트
text-sm text-muted-foreground

// 작은 텍스트
text-xs text-muted-foreground
```

### 2.4 반응형 설정

```tsx
// 모바일 우선 + 데스크톱 최적화
className="text-xs sm:text-sm"           // 폰트 크기
className="h-8 sm:h-10"                  // 입력 필드 높이
className="flex-col md:flex-row"         // 레이아웃
className="gap-2 sm:gap-4"               // 간격
```

### 2.5 중첩 박스 금지 원칙

**❌ 잘못된 예시**:
```tsx
<Card>
  <CardContent>
    <div className="border rounded-lg p-4">  {/* 중첩 박스! */}
      <div className="border rounded p-2">  {/* 또 중첩! */}
        내용
      </div>
    </div>
  </CardContent>
</Card>
```

**✅ 올바른 예시**:
```tsx
<Card>
  <CardHeader>
    <CardTitle>제목</CardTitle>
  </CardHeader>
  <CardContent className="space-y-4">
    {/* 직접 컨텐츠 배치 */}
    <div>내용 1</div>
    <div>내용 2</div>
  </CardContent>
</Card>
```

---

## 3. 데이터 구조

### 3.1 타입 정의

```typescript
// frontend/types/numbering-rule.ts

import { BaseComponent } from "./screen-management";

/**
 * 코드 파트 유형
 */
export type CodePartType =
  | "prefix"           // 접두사 (고정 문자열)
  | "sequence"         // 순번 (자동 증가)
  | "date"             // 날짜 (YYYYMMDD 등)
  | "year"             // 연도 (YYYY)
  | "month"            // 월 (MM)
  | "custom";          // 사용자 정의

/**
 * 생성 방식
 */
export type GenerationMethod =
  | "auto"             // 자동 생성
  | "manual";          // 직접 입력

/**
 * 날짜 형식
 */
export type DateFormat =
  | "YYYY"             // 2025
  | "YY"               // 25
  | "YYYYMM"           // 202511
  | "YYMM"             // 2511
  | "YYYYMMDD"         // 20251103
  | "YYMMDD";          // 251103

/**
 * 단일 규칙 파트
 */
export interface NumberingRulePart {
  id: string;                       // 고유 ID
  order: number;                    // 순서 (1-6)
  partType: CodePartType;           // 파트 유형
  generationMethod: GenerationMethod; // 생성 방식
  
  // 자동 생성 설정
  autoConfig?: {
    // 접두사 설정
    prefix?: string;                // 예: "ITM"
    
    // 순번 설정
    sequenceLength?: number;        // 자릿수 (예: 4 → 0001)
    startFrom?: number;             // 시작 번호 (기본: 1)
    
    // 날짜 설정
    dateFormat?: DateFormat;        // 날짜 형식
  };
  
  // 직접 입력 설정
  manualConfig?: {
    value: string;                  // 입력값
    placeholder?: string;           // 플레이스홀더
  };
  
  // 생성된 값 (미리보기용)
  generatedValue?: string;
}

/**
 * 전체 채번 규칙
 */
export interface NumberingRuleConfig {
  ruleId: string;                   // 규칙 ID
  ruleName: string;                 // 규칙명
  description?: string;             // 설명
  parts: NumberingRulePart[];       // 규칙 파트 배열 (최대 6개)
  
  // 설정
  separator?: string;               // 구분자 (기본: "-")
  resetPeriod?: "none" | "daily" | "monthly" | "yearly"; // 초기화 주기
  currentSequence?: number;         // 현재 시퀀스
  
  // 적용 대상
  tableName?: string;               // 적용할 테이블명
  columnName?: string;              // 적용할 컬럼명
  
  // 메타 정보
  companyCode?: string;
  createdAt?: string;
  updatedAt?: string;
  createdBy?: string;
}

/**
 * 화면관리 컴포넌트 인터페이스
 */
export interface NumberingRuleComponent extends BaseComponent {
  type: "numbering-rule";
  
  // 채번 규칙 설정
  ruleConfig: NumberingRuleConfig;
  
  // UI 설정
  showRuleList?: boolean;           // 좌측 목록 표시 여부
  maxRules?: number;                // 최대 규칙 개수 (기본: 6)
  enableReorder?: boolean;          // 순서 변경 허용 여부
  
  // 스타일
  cardLayout?: "vertical" | "horizontal"; // 카드 레이아웃
}
```

### 3.2 데이터베이스 스키마

```sql
-- db/migrations/034_create_numbering_rules.sql

-- 채번 규칙 마스터 테이블
CREATE TABLE IF NOT EXISTS numbering_rules (
  rule_id VARCHAR(50) PRIMARY KEY,
  rule_name VARCHAR(100) NOT NULL,
  description TEXT,
  separator VARCHAR(10) DEFAULT '-',
  reset_period VARCHAR(20) DEFAULT 'none',
  current_sequence INTEGER DEFAULT 1,
  table_name VARCHAR(100),
  column_name VARCHAR(100),
  company_code VARCHAR(20) NOT NULL,
  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW(),
  created_by VARCHAR(50),
  
  CONSTRAINT fk_company FOREIGN KEY (company_code) 
    REFERENCES company_info(company_code)
);

-- 채번 규칙 상세 테이블
CREATE TABLE IF NOT EXISTS numbering_rule_parts (
  id SERIAL PRIMARY KEY,
  rule_id VARCHAR(50) NOT NULL,
  part_order INTEGER NOT NULL,
  part_type VARCHAR(50) NOT NULL,
  generation_method VARCHAR(20) NOT NULL,
  auto_config JSONB,
  manual_config JSONB,
  company_code VARCHAR(20) NOT NULL,
  created_at TIMESTAMPTZ DEFAULT NOW(),
  
  CONSTRAINT fk_numbering_rule FOREIGN KEY (rule_id) 
    REFERENCES numbering_rules(rule_id) ON DELETE CASCADE,
  CONSTRAINT fk_company FOREIGN KEY (company_code) 
    REFERENCES company_info(company_code),
  CONSTRAINT unique_rule_order UNIQUE (rule_id, part_order, company_code)
);

-- 인덱스
CREATE INDEX idx_numbering_rules_company ON numbering_rules(company_code);
CREATE INDEX idx_numbering_rule_parts_rule ON numbering_rule_parts(rule_id);
CREATE INDEX idx_numbering_rules_table ON numbering_rules(table_name, column_name);

-- 샘플 데이터
INSERT INTO numbering_rules (rule_id, rule_name, description, company_code, created_by) 
VALUES ('SAMPLE_RULE', '샘플 채번 규칙', '제품 코드 자동 생성', '*', 'system')
ON CONFLICT (rule_id) DO NOTHING;

INSERT INTO numbering_rule_parts (rule_id, part_order, part_type, generation_method, auto_config, company_code)
VALUES 
  ('SAMPLE_RULE', 1, 'prefix', 'auto', '{"prefix": "PROD"}', '*'),
  ('SAMPLE_RULE', 2, 'date', 'auto', '{"dateFormat": "YYYYMMDD"}', '*'),
  ('SAMPLE_RULE', 3, 'sequence', 'auto', '{"sequenceLength": 4, "startFrom": 1}', '*')
ON CONFLICT (rule_id, part_order, company_code) DO NOTHING;
```

---

## 4. 구현 순서

### Phase 1: 타입 정의 및 스키마 생성 ✅
1. 타입 정의 파일 생성
2. 데이터베이스 마이그레이션 실행
3. 샘플 데이터 삽입

### Phase 2: 백엔드 API 구현
1. Controller 생성
2. Service 레이어 구현
3. API 테스트

### Phase 3: 프론트엔드 기본 컴포넌트
1. NumberingRuleDesigner (메인)
2. NumberingRulePreview (미리보기)
3. NumberingRuleCard (단일 규칙 카드)

### Phase 4: 상세 설정 패널
1. PartTypeSelector (파트 유형 선택)
2. AutoConfigPanel (자동 생성 설정)
3. ManualConfigPanel (직접 입력 설정)

### Phase 5: 화면관리 통합
1. ComponentType에 "numbering-rule" 추가
2. RealtimePreview 렌더링 추가
3. 템플릿 등록
4. 속성 패널 구현

### Phase 6: 테스트 및 최적화
1. 기능 테스트
2. 반응형 테스트
3. 성능 최적화
4. 문서화

---

## 5. 구현 완료 ✅

### Phase 1: 타입 정의 및 스키마 생성 ✅
- ✅ `frontend/types/numbering-rule.ts` 생성
- ✅ `db/migrations/034_create_numbering_rules.sql` 생성 및 실행
- ✅ 샘플 데이터 삽입 완료

### Phase 2: 백엔드 API 구현 ✅
- ✅ `backend-node/src/services/numberingRuleService.ts` 생성
- ✅ `backend-node/src/controllers/numberingRuleController.ts` 생성
- ✅ `app.ts`에 라우터 등록 (`/api/numbering-rules`)
- ✅ 백엔드 재시작 완료

### Phase 3: 프론트엔드 기본 컴포넌트 ✅
- ✅ `NumberingRulePreview.tsx` - 코드 미리보기
- ✅ `NumberingRuleCard.tsx` - 단일 규칙 카드
- ✅ `AutoConfigPanel.tsx` - 자동 생성 설정
- ✅ `ManualConfigPanel.tsx` - 직접 입력 설정
- ✅ `NumberingRuleDesigner.tsx` - 메인 디자이너

### Phase 4: 상세 설정 패널 ✅
- ✅ 파트 유형별 설정 UI (접두사, 순번, 날짜, 연도, 월, 커스텀)
- ✅ 자동 생성 / 직접 입력 모드 전환
- ✅ 실시간 미리보기 업데이트

### Phase 5: 화면관리 시스템 통합 ✅
- ✅ `v2-core.ts`에 "numbering-rule" ComponentType 추가
- ✅ `screen-management.ts`에 ComponentData 유니온 타입 추가
- ✅ `RealtimePreview.tsx`에 렌더링 로직 추가
- ✅ `TemplatesPanel.tsx`에 "관리자" 카테고리 및 템플릿 추가
- ✅ `NumberingRuleTemplate.ts` 생성

### Phase 6: 완료 ✅
모든 단계가 성공적으로 완료되었습니다!

---

## 6. 사용 방법

### 6.1 화면관리에서 사용하기

1. **화면관리** 페이지로 이동
2. 좌측 **템플릿 패널**에서 **관리자** 카테고리 선택
3. **코드 채번 규칙** 템플릿을 캔버스로 드래그
4. 규칙 파트 추가 및 설정
5. 저장

### 6.2 API 사용하기

#### 규칙 목록 조회
```bash
GET /api/numbering-rules
```

#### 규칙 생성
```bash
POST /api/numbering-rules
{
  "ruleId": "PROD_CODE",
  "ruleName": "제품 코드 규칙",
  "parts": [
    {
      "id": "part-1",
      "order": 1,
      "partType": "prefix",
      "generationMethod": "auto",
      "autoConfig": { "prefix": "PROD" }
    },
    {
      "id": "part-2",
      "order": 2,
      "partType": "date",
      "generationMethod": "auto",
      "autoConfig": { "dateFormat": "YYYYMMDD" }
    },
    {
      "id": "part-3",
      "order": 3,
      "partType": "sequence",
      "generationMethod": "auto",
      "autoConfig": { "sequenceLength": 4, "startFrom": 1 }
    }
  ],
  "separator": "-"
}
```

#### 코드 생성
```bash
POST /api/numbering-rules/PROD_CODE/generate

응답: { "success": true, "data": { "code": "PROD-20251103-0001" } }
```

---

## 7. 구현된 파일 목록

### 프론트엔드
```
frontend/
├── types/
│   └── numbering-rule.ts ✅
├── components/
│   └── numbering-rule/
│       ├── NumberingRuleDesigner.tsx ✅
│       ├── NumberingRuleCard.tsx ✅
│       ├── NumberingRulePreview.tsx ✅
│       ├── AutoConfigPanel.tsx ✅
│       └── ManualConfigPanel.tsx ✅
└── components/screen/
    ├── RealtimePreview.tsx ✅ (수정됨)
    ├── panels/
    │   └── TemplatesPanel.tsx ✅ (수정됨)
    └── templates/
        └── NumberingRuleTemplate.ts ✅
```

### 백엔드
```
backend-node/
├── src/
│   ├── services/
│   │   └── numberingRuleService.ts ✅
│   ├── controllers/
│   │   └── numberingRuleController.ts ✅
│   └── app.ts ✅ (수정됨)
```

### 데이터베이스
```
db/
└── migrations/
    └── 034_create_numbering_rules.sql ✅
```

---

## 8. 다음 개선 사항 (선택사항)

- [ ] 규칙 순서 드래그앤드롭으로 변경
- [ ] 규칙 복제 기능
- [ ] 규칙 템플릿 제공 (자주 사용하는 패턴)
- [ ] 코드 검증 로직
- [ ] 테이블 생성 시 자동 채번 컬럼 추가 통합
- [ ] 화면관리에서 입력 폼에 자동 코드 생성 버튼 추가

