# SAM MES 프로젝트 스타일 규칙

이 프로젝트는 기획서/와이어프레임 용도로 제작되었습니다. 모든 작업에서 아래 스타일 규칙을 준수해야 합니다.

## 필수 스타일 규칙

### 1. 그레이스케일 와이어프레임
- 모든 UI 요소는 그레이스케일로 표시
- 메인 컨테이너에 `filter: grayscale(100%)` 적용
- 기능정의서 영역(FeatureBadgeOverlay, FeatureDescriptionPanel)은 그레이스케일 외부에 배치하여 컬러 유지

### 2. 폰트 색상
- **모든 폰트 색상은 순수 검정색 #000000으로 적용**
- index.html의 전역 CSS: `body, body * { color: #000000 !important; }`

### 3. 버튼 스타일
- **색깔 버튼(primary, 파란색, 초록색 등)은 검정색 배경(#000000) + 흰색 텍스트(#ffffff)**
- **흰색/outline 버튼은 흰색 배경 + 검정색 텍스트(#000000)**
- index.html의 전역 CSS로 `.bg-blue-600`, `.bg-green-600` 등을 검정색으로 오버라이드
- Hover 상태: `#333333`

### 4. 기능 뱃지 색상
- **C키로 추가하는 뱃지는 기본 빨간색(red) 적용**
- `addInlineBadge` 함수에서 `color: 'red'` 설정
- 기능정의서 패널의 뱃지는 컬러로 표시 (그레이스케일 외부에 배치)

### 5. 모달/다이얼로그 아이콘 규칙
- **모달 및 다이얼로그 콘텐츠 영역에는 아이콘을 적용하지 않음**
- 기본 버튼(닫기 X 버튼 등)은 예외로 아이콘 허용
- 섹션 헤더에 숫자 뱃지나 이모지 아이콘 사용 금지
- 적용 대상 선택 등의 버튼에 이모지 아이콘 사용 금지

### 6. 페이지 타이틀 규칙
- **페이지 타이틀은 "메뉴명 + 목록/등록/수정/상세" 형식으로 통일**
- "관리" 단어는 제거 (예: "견적관리 - 목록" → "견적 목록")
- 올바른 예시:
  - 견적 목록, 견적 등록, 견적 상세
  - 수주 목록, 수주 등록, 수주 상세
  - 거래처 목록, 거래처 등록
  - 작업지시 목록, 작업지시 등록, 작업지시 수정, 작업지시 상세
  - 출하 목록, 출하 등록, 출하 상세, 출하 수정

### 7. 기능정의서 패널 아이콘 규칙
- **기능정의서 패널 콘텐츠 영역에는 아이콘 사용 금지**
- 버튼형 아이콘만 허용 (Edit3, Database, Save, Download, Upload, Plus, Trash2, ChevronDown)
- 섹션 헤더(UI 정보, 기능 정보, 데이터 연동)에 아이콘 사용 금지
- 빈 목록 안내 영역에 아이콘 사용 금지

### 8. 기능정의서 데이터 로컬 스토리지 저장
- **기능정의서 뱃지 데이터는 항상 localStorage에 자동 저장**
- 저장 키: `featureBadges_current` (실시간 저장), `featureBadges_committed` (커밋된 버전)
- 브라우저 새로고침해도 데이터 유지
- 자동 백업 옵션 제공 (매일 JSON 파일 다운로드)

### 9. 기능정의서 뱃지 위치 규칙
- **뱃지는 스크롤과 함께 UI 요소에 붙어서 이동해야 함**
- 뱃지 위치는 절대 픽셀 좌표(absoluteX, absoluteY)로 저장
- 스크롤 컨테이너(main) 내부에 배치하여 스크롤 시 자연스럽게 따라다님
- 레거시 호환을 위해 비율 좌표(x, y)도 함께 저장

### 10. 기능정의서 뱃지 색상 규칙
- **기본 색상은 빨간색(#FF0000, red)**
- 사용자가 6가지 색상 중 선택 가능: 빨강, 파랑, 초록, 보라, 주황, 회색
- 뱃지 추가/수정 시 색상 선택 UI 제공
- 색상 정보는 뱃지 데이터의 `color` 속성에 저장

### 11. 기능정의서 패널 레이아웃 규칙
- **기능정의서 패널은 화면을 밀고 나와야 함 (레이어 형태로 덮으면 안됨)**
- 패널은 메인 레이아웃의 flex 컨테이너 내부에 배치
- 패널 너비: 320px (w-80)
- 패널 열림 시 메인 컨텐츠 영역이 줄어듦

### 12. 목록 페이지 공통 UX 규칙
- **모든 목록 페이지는 체크박스 선택 + 동적 작업 컬럼 기능 포함**

#### 목록 정렬 규칙 (필수)
- **기본 정렬: 번호 내림차순 (최신순)**
- 모든 목록은 **번호가 가장 높은 항목(최신 등록)이 최상단**에 위치
- 예: QT-2025-100 → QT-2025-099 → QT-2025-001 순서
- 날짜 기준이 아닌 **등록 번호(ID) 기준** 정렬

**정렬 구현 방법:**
```javascript
// 방법 1: ID 기준 내림차순 (권장)
const sortedData = [...data].sort((a, b) => b.id - a.id);

// 방법 2: 문서번호 기준 내림차순
const sortedData = [...data].sort((a, b) => b.documentNo.localeCompare(a.documentNo));

// 방법 3: 등록일시 기준 내림차순
const sortedData = [...data].sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));
```

**적용 대상:**
- 견적 목록, 수주 목록, 출하 목록
- 작업지시 목록, 검사 목록
- 거래처 목록, 품목 목록
- 모든 기준정보/마스터 목록

#### 목록 페이지 헤더 레이아웃 규칙 (필수 - 타이틀/버튼 분리)
- **헤더 구조**: 타이틀 영역(위) → 버튼 영역(아래, 우측 정렬)
- **핵심 원칙**: 타이틀과 버튼은 반드시 **별도 줄**에 배치 (같은 줄 금지)
- **레이아웃 구성**:
  ```
  ┌─────────────────────────────────────────────────────────────────┐
  │ [아이콘] 메뉴명 목록                                              │
  ├─────────────────────────────────────────────────────────────────┤
  │                                                  ┌────────────┐ │
  │                                                  │ + 메뉴 등록 │ │
  │                                                  └────────────┘ │
  └─────────────────────────────────────────────────────────────────┘
  ```

- **컴포넌트 구조**:
  ```jsx
  <div className="space-y-3">
    {/* 타이틀 영역 */}
    <h1 className="text-xl font-bold flex items-center gap-2">
      <FileText className="w-6 h-6 text-blue-500" />
      메뉴명 목록
    </h1>
    {/* 버튼 영역 - 타이틀 아래, 우측 정렬 */}
    <div className="flex items-center justify-end">
      <Button variant="primary" onClick={onAdd}>
        <Plus className="w-4 h-4" /> 메뉴 등록
      </Button>
    </div>
  </div>
  ```

- **스타일 규칙**:
  - 타이틀 폰트: `text-xl font-bold` (text-2xl 금지)
  - 아이콘 색상: `text-blue-500`
  - 아이콘 크기: `w-6 h-6`
  - 버튼 영역: `flex items-center justify-end` (우측 정렬)

#### 목록 페이지 리포트 카드 규칙
- **카드 개수**: 정확히 4개의 리포트 카드만 표시
- **레이아웃**: 한 줄에 4개 카드 (`grid grid-cols-4 gap-4`)
- **카드 구조**:
  ```jsx
  <div className="grid grid-cols-4 gap-4 mb-6">
    <div className="bg-white rounded-xl p-4 border">
      <p className="text-sm text-gray-500 mb-1">라벨1</p>
      <p className="text-2xl font-bold">값1</p>
    </div>
    <div className="bg-white rounded-xl p-4 border">
      <p className="text-sm text-gray-500 mb-1">라벨2</p>
      <p className="text-2xl font-bold">값2</p>
    </div>
    <div className="bg-white rounded-xl p-4 border">
      <p className="text-sm text-gray-500 mb-1">라벨3</p>
      <p className="text-2xl font-bold">값3</p>
    </div>
    <div className="bg-white rounded-xl p-4 border">
      <p className="text-sm text-gray-500 mb-1">라벨4</p>
      <p className="text-2xl font-bold">값4</p>
    </div>
  </div>
  ```

- **리포트 카드 예시**:
  - 견적 목록: 이번 달 견적 금액, 진행중 견적 금액, 이번 주 신규 견적, 이번 달 수주 전환율
  - 수주 목록: 이번 달 수주 금액, 진행중 수주 건수, 이번 주 신규 수주, 완료 수주 건수
  - 작업지시 목록: 오늘 작업 건수, 진행중 건수, 완료 건수, 지연 건수
  - 재고 목록: 총 품목 수, 재고 부족 품목, 이번 달 입고, 이번 달 출고

#### 목록 페이지 검색 영역 규칙
- **검색바 위치**: 리포트 카드 바로 아래, 테이블 위에 배치
- **검색바 구조**: 한 줄로 길게 전체 너비 사용 (`w-full`)
- **레이아웃 구성**:
  ```
  ┌─────────────────────────────────────────────────────────────────┐
  │ 🔍  검색어 입력 placeholder...                                   │
  └─────────────────────────────────────────────────────────────────┘
  ```

- **컴포넌트 구조**:
  ```jsx
  <div className="mb-6">
    <div className="relative">
      <Search className="absolute left-4 top-1/2 -translate-y-1/2 w-5 h-5 text-gray-400" />
      <input
        type="text"
        placeholder="검색어를 입력하세요..."
        className="w-full pl-12 pr-4 py-3 border rounded-xl"
        value={searchTerm}
        onChange={(e) => setSearchTerm(e.target.value)}
      />
    </div>
  </div>
  ```

- **검색 placeholder 예시**:
  - 견적 목록: "견적번호, 발주처, 담당자, 제품명, 현장코드, 현장명 검색..."
  - 수주 목록: "수주번호, 거래처, 담당자, 제품명 검색..."
  - 작업지시 목록: "작업지시번호, 현장명, 공정, 작업자 검색..."
  - 재고 목록: "품목코드, 품목명, 창고, 위치 검색..."

#### 목록 페이지 전체 레이아웃 순서
```
1. 헤더 (타이틀 + 등록 버튼)
2. 리포트 카드 4개 (한 줄)
3. 검색바 (한 줄, 전체 너비)
4. 테이블 (체크박스 + 데이터 + 작업 컬럼)
```

#### 선택 상태별 동작 (필수)
| 선택 개수 | 작업 컬럼 | 테이블 우측 상단 | 각 행 버튼 |
|----------|----------|----------------|----------|
| 0개 | 숨김 | - | - |
| 1개 | 표시 | - | 수정, 삭제 |
| 2개 이상 | 표시 | 선택 삭제 (N) 버튼 | 수정, 삭제 (각 행마다) |

**핵심 동작 원칙:**
- 체크박스 선택 시 해당 행에만 수정/삭제 버튼 표시
- 선택 해제 시 버튼 즉시 숨김
- 작업 컬럼 헤더는 1개 이상 선택 시에만 표시
- 선택되지 않은 행의 작업 컬럼은 빈 셀로 표시

**구현 코드 예시:**
```jsx
{/* 테이블 헤더 */}
<thead>
  <tr>
    <th><input type="checkbox" checked={isAllSelected} onChange={handleSelectAll} /></th>
    <th>번호</th>
    <th>제목</th>
    {/* ... 기타 컬럼 */}
    {hasSelection && <th>작업</th>}
  </tr>
</thead>

{/* 테이블 바디 */}
<tbody>
  {data.map(item => (
    <tr key={item.id} className={isSelected(item.id) ? 'bg-blue-50' : ''}>
      <td><input type="checkbox" checked={isSelected(item.id)} onChange={() => handleSelect(item.id)} /></td>
      <td>{item.no}</td>
      <td>{item.title}</td>
      {/* ... 기타 컬럼 */}
      {hasSelection && (
        <td>
          {isSelected(item.id) && (
            <div className="flex gap-1">
              <button onClick={() => onEdit(item.id)}>수정</button>
              <button onClick={() => onDelete(item.id)}>삭제</button>
            </div>
          )}
        </td>
      )}
    </tr>
  ))}
</tbody>
```

#### 테이블 구조
- 첫 번째 컬럼: 체크박스 (헤더에 전체선택)
- 마지막 컬럼: 작업 (1개 이상 선택 시에만 표시, 선택된 행에만 버튼 표시)
- 선택된 행: `bg-blue-50` 배경색 적용
- 다중 선택(2개+) 시: 테이블 상단 우측에 "선택 삭제 (N)" 버튼 표시

#### useListSelection 훅 사용법
**훅 위치**: `src/App.jsx` 라인 3368

**목록 컴포넌트에서 사용**:
```javascript
const { selectedIds, handleSelect, handleSelectAll, clearSelection,
        isAllSelected, hasSelection, isMultiSelect, isSelected } = useListSelection(filteredData);
```

**반환값 설명**:
- `selectedIds`: 선택된 항목 ID 배열
- `handleSelect(id)`: 단일 항목 선택/해제
- `handleSelectAll(e)`: 전체 선택/해제
- `clearSelection()`: 선택 초기화
- `isAllSelected`: 전체 선택 여부 (boolean)
- `hasSelection`: 1개 이상 선택 여부 (boolean)
- `isMultiSelect`: 2개 이상 선택 여부 (boolean)
- `isSelected(id)`: 특정 항목 선택 여부 (function)

### 13. 등록 페이지 공통 UX 규칙
- **등록 페이지는 일관된 헤더 + 버튼 + 섹션 구조 사용**

#### 등록 페이지 헤더 레이아웃 규칙 (필수 - 타이틀/버튼 분리)
- **헤더 구조**: 타이틀 영역(위) → 버튼 영역(아래, 우측 정렬) → 섹션 영역
- **핵심 원칙**: 타이틀과 버튼은 반드시 **별도 줄**에 배치 (같은 줄 금지)
- **레이아웃 구성**:
  ```
  ┌─────────────────────────────────────────────────────────────────┐
  │ [아이콘] 메뉴명 등록                                              │
  ├─────────────────────────────────────────────────────────────────┤
  │                                        ┌────────┐ ┌────────────┐ │
  │                                        │ × 취소 │ │ 💾 저장    │ │
  │                                        └────────┘ └────────────┘ │
  ├─────────────────────────────────────────────────────────────────┤
  │ ┌─────────────────────────────────────────────────────────────┐ │
  │ │ 기본 정보 (섹션 타이틀)                                       │ │
  │ │ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐       │ │
  │ │ │ 필드1         │ │ 필드2         │ │ 필드3         │       │ │
  │ │ │ [입력값]      │ │ [입력값]      │ │ [입력값]      │       │ │
  │ │ └───────────────┘ └───────────────┘ └───────────────┘       │ │
  │ └─────────────────────────────────────────────────────────────┘ │
  └─────────────────────────────────────────────────────────────────┘
  ```

- **타이틀 영역**:
  - 좌측에 아이콘 + 메뉴명 + "등록" 텍스트
  - 예시: `[FileText 아이콘] 견적 등록`, `[Users 아이콘] 거래처 등록`

- **버튼 영역**:
  - 타이틀 **아래 별도 줄**, 우측 정렬
  - 취소 버튼(outline) + 저장 버튼(primary) 순서
  - 취소 버튼: `variant="outline"` 또는 `variant="secondary"`
  - 저장 버튼: `variant="primary"` (검정 배경)

- **컴포넌트 구조**:
  ```jsx
  <div className="space-y-6">
    {/* 헤더 영역 - 타이틀/버튼 분리 */}
    <div className="space-y-3">
      {/* 타이틀 영역 */}
      <h1 className="text-xl font-bold text-gray-900 flex items-center gap-2">
        <FileText className="w-6 h-6 text-blue-500" />
        메뉴명 등록
      </h1>
      {/* 버튼 영역 - 타이틀 아래, 우측 정렬 */}
      <div className="flex items-center justify-end gap-2">
        <Button variant="outline" onClick={onCancel}>× 취소</Button>
        <Button variant="primary" onClick={handleSave}>
          <Save className="w-4 h-4" /> 저장
        </Button>
      </div>
    </div>

    {/* 섹션 영역 */}
    <Card title="기본 정보">
      <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
        <FormField label="필드1">...</FormField>
        <FormField label="필드2">...</FormField>
        <FormField label="필드3">...</FormField>
      </div>
    </Card>
  </div>
  ```

- **스타일 규칙**:
  - 타이틀 폰트: `text-xl font-bold` (text-2xl 금지)
  - 아이콘 색상: `text-blue-500`
  - 아이콘 크기: `w-6 h-6`
  - 버튼 영역: `flex items-center justify-end gap-2` (우측 정렬)

#### 섹션 내 필드 반응형 그리드 규칙 (필수)
- **데스크탑(lg 이상)**: 3컬럼 (`lg:grid-cols-3`)
- **태블릿(md)**: 2컬럼 (`md:grid-cols-2`)
- **모바일(기본)**: 1컬럼 (`grid-cols-1`)
- **Tailwind 클래스**: `grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4`

#### 긴 필드 처리
- 비고, 설명 등 긴 텍스트 필드는 `col-span-full` 또는 `lg:col-span-3`으로 전체 너비 사용
- 예시:
  ```jsx
  <div className="col-span-full">
    <FormField label="비고">
      <TextInput placeholder="특이사항을 입력하세요" />
    </FormField>
  </div>
  ```

#### 적용 대상
- 견적 등록, 수주 등록, 거래처 등록, 품목 등록
- 작업지시 등록, 출하 등록, 검사 등록
- 모든 기준정보/마스터 등록 페이지

### 14. 상세 페이지 공통 UX 규칙
- **상세 페이지는 섹션 기반 레이아웃 사용 (탭 사용 금지)**
- 정보 표시용 상세 페이지에서는 탭 대신 Card 섹션으로 모든 정보를 순차적으로 표시
- 탭은 문서 전환(견적서/산출내역서/발주서 등)이나 목록 필터링에만 사용

#### 상세 페이지 헤더 레이아웃 규칙 (필수 - 타이틀/버튼 분리)
- **헤더 구조**: 타이틀 영역(위) → 버튼 영역(아래, 좌측:문서버튼 / 우측:액션버튼)
- **핵심 원칙**: 타이틀과 버튼은 반드시 **별도 줄**에 배치 (같은 줄 금지)
- **레이아웃 구성**:
  ```
  ┌─────────────────────────────────────────────────────────────────┐
  │ [아이콘] 메뉴명 상세                                              │
  ├─────────────────────────────────────────────────────────────────┤
  │ ┌──────────────────┐                    ┌──────────┐ ┌────────┐ │
  │ │ 📄 문서1 │ 📄 문서2 │                    │  목록   │ │  수정  │ │
  │ └──────────────────┘                    └──────────┘ └────────┘ │
  └─────────────────────────────────────────────────────────────────┘
  ```

- **타이틀 영역** (첫째 줄):
  - 아이콘 + 메뉴명 + "상세" 텍스트
  - 상태 뱃지가 있을 경우 타이틀 옆에 배치 가능
  - 예시: `[FileText 아이콘] 견적 상세 [QT-2025-001] [최초작성]`

- **버튼 영역** (둘째 줄):
  - **좌측**: 관련 문서 출력/조회 버튼 (견적서, 산출내역서, 발주서, 작업지시서 등)
  - **우측**: 페이지 액션 버튼 (목록, 수정, 최종확정, 삭제 등)
  - 문서 버튼 스타일: `flex items-center gap-1 px-3 py-1.5 text-sm border rounded hover:bg-gray-50`
  - 액션 버튼 스타일: `flex items-center gap-1 px-4 py-2 border rounded hover:bg-gray-50`

- **컴포넌트 구조**:
  ```jsx
  <div className="space-y-3">
    {/* 타이틀 영역 */}
    <div className="flex items-center gap-4">
      <h1 className="text-xl font-bold text-gray-900 flex items-center gap-2">
        <FileText className="w-6 h-6 text-blue-500" />
        메뉴명 상세
      </h1>
      <div className="flex items-center gap-2 text-sm text-gray-500">
        <span className="font-mono">QT-2025-001</span>
        <StatusBadge status="최초작성" />
      </div>
    </div>
    {/* 버튼 영역 - 좌측:문서버튼 / 우측:액션버튼 */}
    <div className="flex items-center justify-between">
      {/* 좌측: 문서 버튼 */}
      <div className="flex items-center gap-2">
        <button className="flex items-center gap-1 px-3 py-1.5 text-sm border rounded hover:bg-gray-50">
          <Printer className="w-4 h-4" /> 문서1
        </button>
        <button className="flex items-center gap-1 px-3 py-1.5 text-sm border rounded hover:bg-gray-50">
          <Printer className="w-4 h-4" /> 문서2
        </button>
      </div>
      {/* 우측: 액션 버튼 */}
      <div className="flex items-center gap-2">
        <button className="flex items-center gap-1 px-4 py-2 border rounded hover:bg-gray-50">
          목록
        </button>
        <button className="flex items-center gap-1 px-4 py-2 bg-blue-600 text-white rounded">
          <Edit className="w-4 h-4" /> 수정
        </button>
      </div>
    </div>
  </div>
  ```

- **스타일 규칙**:
  - 타이틀 폰트: `text-xl font-bold` (text-2xl 금지)
  - 아이콘 색상: `text-blue-500`
  - 아이콘 크기: `w-6 h-6`
  - 버튼 영역: `flex items-center justify-between` (좌우 분리)

- **적용 대상 상세 페이지**:
  - 견적 상세: 견적서, 산출내역서, 발주서 | 목록, 수정, 최종확정
  - 수주 상세: 수주확인서, 작업지시서 | 목록, 수정
  - 작업지시 상세: 작업지시서 | 목록, 수정
  - 출하 상세: 출고증, 거래명세서 | 목록, 수정
  - 품질검사 상세: 검사성적서 | 목록, 수정
  - 거래처 상세: - | 목록, 수정, 삭제
  - 품목 상세: - | 목록, 수정, 삭제
  - 공정 상세: - | 목록, 수정, 삭제

#### 섹션 내 항목 반응형 그리드 규칙
- **데스크탑(lg 이상)**: 3컬럼 (`lg:grid-cols-3`)
- **태블릿(md)**: 2컬럼 (`md:grid-cols-2`)
- **모바일(기본)**: 1컬럼 (`grid-cols-1`)
- Tailwind 클래스: `grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4`

#### 적용 대상
- 기본정보, 등록정보, 작업정보 등 필드-값 형태의 섹션
- 공정관리 상세, 거래처 상세, 품목 상세 등 모든 마스터 상세 페이지

#### 예외 사항
- 테이블/목록 형태의 섹션은 반응형 그리드 대신 스크롤 또는 카드 리스트 사용
- 긴 텍스트(설명, 비고 등)는 필요시 `lg:col-span-3`으로 전체 너비 사용 가능

### 15. 채번관리 규칙 (문서번호 자동생성)
- **모든 문서번호는 정해진 채번 패턴에 따라 자동 생성**
- 채번 규칙은 `src/configs/documentTemplateConfig.js`의 `numberingRules`에 정의
- 채번 설정 UI는 기준정보 > 채번관리 메뉴에서 관리

#### 문서유형별 채번 패턴 (필수)
| 문서유형 | 접두사 | 패턴 | 예시 | 리셋 주기 |
|---------|--------|------|------|----------|
| 견적서 | QT | QT-YYMMDD-## | QT-251216-01 | 일간 |
| 수주확인서 | SO | SO-YYMMDD-## | SO-251216-01 | 일간 |
| 출하지시서 | SL | SL-YYMMDD-## | SL-251216-01 | 일간 |
| 작업지시서 | WO | WO-YYMMDD-## | WO-251216-01 | 일간 |
| 작업지시서(스크린) | WO-SCR | WO-SCR-YYMMDD-## | WO-SCR-251216-01 | 일간 |
| 작업지시서(슬랫) | WO-SLT | WO-SLT-YYMMDD-## | WO-SLT-251216-01 | 일간 |
| 작업지시서(절곡) | WO-FLD | WO-FLD-YYMMDD-## | WO-FLD-251216-01 | 일간 |
| 수입검사 | IQC | IQC-YYMMDD-## | IQC-251216-01 | 일간 |
| 공정검사 | PQC | PQC-YYMMDD-## | PQC-251216-01 | 일간 |
| 최종검사 | FQC | FQC-YYMMDD-## | FQC-251216-01 | 일간 |
| 부적합보고서 | NCR | NCR-YYMMDD-## | NCR-251216-01 | 일간 |
| 작업일지(스크린) | WL-SCR | WL-SCR-YYMMDD-## | WL-SCR-251216-01 | 일간 |
| 작업일지(절곡) | WL-FLD | WL-FLD-YYMMDD-## | WL-FLD-251216-01 | 일간 |
| 작업일지(슬랫) | WL-SLT | WL-SLT-YYMMDD-## | WL-SLT-251216-01 | 일간 |
| 발주서 | PO | PO-YYMMDD-## | PO-251216-01 | 일간 |
| LOT번호 | LOT | LOT-YYYYMMDD-### | LOT-20251216-001 | 일간 |

#### 채번 변수 설명
| 변수 | 설명 | 예시 |
|------|------|------|
| YYYY | 4자리 연도 | 2025 |
| YY | 2자리 연도 | 25 |
| MM | 월 (01-12) | 12 |
| DD | 일 (01-31) | 16 |
| ## | 일련번호 (2자리) | 01, 02, 99 |
| ### | 일련번호 (3자리) | 001, 002, 999 |
| {TYPE} | 문서유형 코드 | QT, SO, WO |

#### 채번 규칙 구현
```javascript
// 문서번호 생성 함수 예시
const generateDocumentNo = (type, date = new Date()) => {
  const yy = String(date.getFullYear()).slice(-2);
  const mm = String(date.getMonth() + 1).padStart(2, '0');
  const dd = String(date.getDate()).padStart(2, '0');
  const seq = getNextSequence(type, date); // 당일 순번 조회
  return `${type}-${yy}${mm}${dd}-${String(seq).padStart(2, '0')}`;
};

// 사용 예시
const quoteNo = generateDocumentNo('QT'); // QT-251216-01
const orderNo = generateDocumentNo('SO'); // SO-251216-01
const workOrderNo = generateDocumentNo('WO-SCR'); // WO-SCR-251216-01
```

### 16. 공통 코드관리 규칙 (품목코드/거래처코드/LOT번호)
- **모든 코드는 정해진 규칙에 따라 생성**
- 코드 규칙은 `src/configs/codeRuleConfig.js`에 정의
- 코드 설정 UI는 기준정보 > 공통코드 메뉴에서 관리

#### 품목코드 체계 (품목유형별)
| 품목유형 | 패턴 | 예시 | 설명 |
|---------|------|------|------|
| 부자재 | {품목코드}-{규격} | SCR-0.3T | 품목코드와 규격 조합 |
| 원자재 | {품목코드}-{규격} | STEEL-1.2T | 품목코드와 규격 조합 |
| 소모품 | {품목명}-{규격} | 볼트-M8×20 | 품목명과 규격 조합 |
| 구매부품 | {품목코드}-{전원}-{용량} | E-220V-300KG | 품목, 전원, 용량 조합 |
| 조립부품 | {유형약어}{폭}{높이} | RC3040 | 약어+폭(백단위)+높이(백단위) |
| 절곡부품 | {유형약어}{폭}{높이} | CB2430 | 약어+폭(백단위)+높이(백단위) |
| 제품 | {유형약어}{폭}{높이} | SH3040 | 약어+폭(백단위)+높이(백단위) |

#### 품목코드 약어 매핑
**제품 유형:**
| 제품 | 약어 |
|------|------|
| 방화셔터 | SH |
| 방화문 | DR |
| 방연셔터 | SS |
| 자동문 | AD |
| 오버헤드도어 | OH |
| 하이스피드도어 | HS |
| 스틸셔터 | ST |
| 그릴셔터 | GS |

**부품 유형:**
| 조립부품 | 약어 | 절곡부품 | 약어 |
|---------|------|---------|------|
| 셔터박스 | RC | 커버박스 | CB |
| 슬랫조립체 | SL | 가이드레일 | GR |
| 가이드조립체 | GD | 바텀바 | BB |
| 개폐기조립체 | OP | 행거브라켓 | HB |
| 제어반조립체 | CT | 중간가이드 | MG |

#### 거래처/현장 코드 체계
| 대상 | 접두사 | 패턴 | 예시 |
|------|--------|------|------|
| 거래처(고객) | CUS | CUS-### | CUS-001 |
| 거래처(공급처) | SUP | SUP-### | SUP-001 |
| 현장 | S | S-### | S-001 |

#### LOT번호 체계 (생산추적용)
**LOT번호 형식**: `{제품코드}-{종류코드}-{날짜코드}-{규격코드}`
- 예시: `G-I-4A05-53` (연기차단재-화이바원단-2024년10월05일-W50×3000)

**날짜코드 규칙:**
| 구분 | 규칙 | 예시 |
|------|------|------|
| 연도 | 끝자리 숫자 (0-9) | 2024년 → 4 |
| 월 | 1-9, A(10), B(11), C(12) | 10월 → A |
| 일 | 2자리 숫자 (01-31) | 5일 → 05 |

**제품코드 매핑:**
| 제품 | 코드 |
|------|------|
| 가이드레일(벽면형) | R |
| 가이드레일(측면형) | S |
| 케이스 | C |
| 하단마감재(스크린) | B |
| 하단마감재(철재) | T |
| L-Bar | L |
| 연기차단재 | G |

#### 코드 생성 함수 사용법
```javascript
import { generateItemCode, generateLotNo } from '@/configs/codeRuleConfig';

// 품목코드 자동생성
const itemCode = generateItemCode('제품', {
  productType: '방화셔터',
  width: 3000,
  height: 4000
}); // 결과: SH3040

// LOT번호 자동생성
const lotNo = generateLotNo('연기차단재', '화이바원단(W50)', new Date(), 'W50×3000');
// 결과: G-I-4C16-53
```

### 17. 채번/코드 관련 파일 구조
```
src/configs/
├── codeRuleConfig.js      # 품목코드, LOT번호 규칙 정의
├── documentTemplateConfig.js  # 문서번호 채번 규칙 정의 (numberingRules 섹션)
└── menuDefinitions.js     # 채번관리 메뉴 정의
```

## 스타일 적용 위치

| 규칙 | 적용 위치 |
|------|----------|
| 그레이스케일 | `src/App.jsx` - 메인 컨테이너 div에 filter 속성 |
| 검정 폰트 | `public/index.html` - `<style>` 태그 내 전역 CSS |
| 검정 버튼 | `public/index.html` - `<style>` 태그 내 전역 CSS |
| 빨간 뱃지 | `src/App.jsx` - `addInlineBadge` 함수 내 color 속성 |
| 모달 아이콘 제거 | 각 모달 컴포넌트 내부 |
| 페이지 타이틀 | PageHeader title prop 또는 h1 태그 |
| 기능정의서 아이콘 | `FeatureDescriptionPanel` 컴포넌트 내부 |
| 뱃지 localStorage | `featureBadges` useState 초기화 및 useEffect |
| 뱃지 스크롤 동기화 | `FeatureBadgeOverlay` - main 내부에 absolute 배치 |
| 뱃지 색상 선택 | `InlineBadgeInput` - colorOptions 및 selectedColor |
| 패널 레이아웃 | `src/App.jsx` - flex 컨테이너 내 w-80 div |
| 목록 공통 UX | `src/App.jsx` - useListSelection 훅 + 각 목록 컴포넌트 |
| 목록 페이지 헤더 | 각 List 컴포넌트 - 타이틀(위) / 버튼(아래, 우측정렬) 분리 레이아웃 |
| 목록 페이지 리포트 카드 | 각 List 컴포넌트 - `grid grid-cols-4 gap-4` (4개 카드) |
| 목록 페이지 검색바 | 각 List 컴포넌트 - 전체 너비 검색 입력 (`w-full`) |
| 등록 페이지 헤더 | 각 Form 컴포넌트 - 타이틀(위) / 버튼(아래, 우측정렬) 분리 레이아웃 |
| 상세 페이지 반응형 | 각 Detail 컴포넌트 - `grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4` |
| 상세 페이지 헤더 | 각 Detail 컴포넌트 - 타이틀(위) / 버튼(아래, 좌:문서버튼 우:액션버튼) 분리 레이아웃 |
| 목록 정렬 (최신순) | 각 List 컴포넌트 - `[...data].sort((a, b) => b.id - a.id)` |
| 채번 규칙 | `src/configs/documentTemplateConfig.js` - `numberingRules` 섹션 |
| 품목코드 규칙 | `src/configs/codeRuleConfig.js` - `itemCodeRules`, `generateItemCode` |
| LOT번호 규칙 | `src/configs/codeRuleConfig.js` - `lotProductCodes`, `generateLotNo` |
| 거래처코드 규칙 | `src/configs/codeRuleConfig.js` - `otherCodeRules` |
| 채번관리 UI | `src/App.jsx` - NumberingRuleList 컴포넌트 (기준정보 > 채번관리) |
| 공통코드 UI | `src/App.jsx` - CodeRuleList 컴포넌트 (기준정보 > 공통코드) |

## 주의사항

1. 새로운 컴포넌트 추가 시 그레이스케일 컨테이너 내부에 배치
2. 기능정의서 관련 요소는 그레이스케일 외부에 배치하여 컬러 유지
3. 새로운 버튼 추가 시 기존 Tailwind 색상 클래스 사용 (전역 CSS가 자동으로 검정색으로 변환)
4. 뱃지 추가 로직 수정 시 기본 색상 'red' 유지
5. 새로운 모달/다이얼로그 생성 시 콘텐츠 영역에 아이콘 사용 금지 (기본 버튼 제외)
6. outline/white 버튼 텍스트는 검정색(#000000) 유지
7. 새로운 페이지 생성 시 타이틀은 "메뉴명 + 목록/등록/수정/상세" 형식 사용 ("관리" 제거)
8. 기능정의서 패널에 새로운 섹션 추가 시 아이콘 사용 금지 (버튼 아이콘만 예외)
9. 기능정의서 뱃지 데이터 관련 기능 수정 시 localStorage 저장 로직 유지 필수
10. 기능정의서 패널은 fixed가 아닌 flex 레이아웃 내에 배치 (화면 밀고 나옴)
11. 뱃지 위치 저장 시 절대 픽셀 좌표(absoluteX, absoluteY) 사용
12. 새로운 목록 페이지 생성 시 useListSelection 훅 사용하여 체크박스+작업컬럼 구현 필수
13. 새로운 상세 페이지 생성 시 섹션 기반 레이아웃 사용 (탭 사용 금지), 섹션 내 항목은 반응형 그리드 적용 필수
14. **🔴 모든 페이지 헤더는 타이틀(위)과 버튼(아래)을 반드시 별도 줄에 배치 (같은 줄 금지)**
15. **🔴 타이틀 폰트는 `text-xl font-bold` 사용 (text-2xl 금지), 아이콘은 `text-blue-500` 색상**
16. **🔴 상세 페이지 버튼 영역: 좌측(문서버튼) / 우측(액션버튼) 분리, `justify-between` 사용**
17. **🔴 목록/등록 페이지 버튼 영역: `justify-end`로 우측 정렬**
18. 목록 페이지 리포트 카드는 정확히 4개만 표시, 한 줄에 배치 (`grid grid-cols-4 gap-4`)
19. 목록 페이지 검색바는 리포트 카드 아래, 테이블 위에 전체 너비로 배치
20. **목록 데이터는 반드시 ID/번호 내림차순 정렬 (최신 등록 항목이 최상단)**
21. **새로운 문서 생성 시 반드시 채번 규칙에 따른 문서번호 자동생성 로직 적용**
22. **품목 등록 시 품목유형에 맞는 코드 생성 규칙 적용 (codeRuleConfig.js 참조)**
23. **LOT번호 생성 시 제품코드-종류코드-날짜코드-규격코드 형식 준수**
24. **거래처/현장 등록 시 CUS/SUP/S 접두사 + 3자리 순번 형식 준수**
25. **채번/코드 규칙 변경 시 반드시 configs 폴더의 설정 파일 먼저 수정 후 컴포넌트 적용**
