채번 컴포넌트 생성
This commit is contained in:
374
docs/채번규칙_컴포넌트_구현_완료.md
Normal file
374
docs/채번규칙_컴포넌트_구현_완료.md
Normal file
@@ -0,0 +1,374 @@
|
||||
# 채번규칙 컴포넌트 구현 완료
|
||||
|
||||
> **작성일**: 2025-11-04
|
||||
> **상태**: 백엔드 및 프론트엔드 핵심 구현 완료 (화면관리 통합 대기)
|
||||
|
||||
---
|
||||
|
||||
## 구현 개요
|
||||
|
||||
채번규칙(Numbering Rule) 컴포넌트는 시스템에서 자동으로 코드를 생성하는 규칙을 설정하고 관리하는 관리자 전용 컴포넌트입니다.
|
||||
|
||||
**생성 코드 예시**:
|
||||
- 제품 코드: `PROD-20251104-0001`
|
||||
- 프로젝트 코드: `PRJ-2025-001`
|
||||
- 거래처 코드: `CUST-A-0001`
|
||||
|
||||
---
|
||||
|
||||
## 완료된 구현 항목
|
||||
|
||||
### 1. 데이터베이스 레이어 ✅
|
||||
|
||||
**파일**: `db/migrations/034_create_numbering_rules.sql`
|
||||
|
||||
- [x] `numbering_rules` 마스터 테이블 생성
|
||||
- [x] `numbering_rule_parts` 파트 테이블 생성
|
||||
- [x] 멀티테넌시 지원 (company_code 필드)
|
||||
- [x] 인덱스 생성 (성능 최적화)
|
||||
- [x] 샘플 데이터 삽입
|
||||
|
||||
**주요 기능**:
|
||||
- 규칙 ID, 규칙명, 구분자, 초기화 주기
|
||||
- 현재 시퀀스 번호 관리
|
||||
- 적용 대상 테이블/컬럼 지정
|
||||
- 최대 6개 파트 지원
|
||||
|
||||
---
|
||||
|
||||
### 2. 백엔드 레이어 ✅
|
||||
|
||||
#### 2.1 서비스 레이어
|
||||
|
||||
**파일**: `backend-node/src/services/numberingRuleService.ts`
|
||||
|
||||
**구현된 메서드**:
|
||||
- [x] `getRuleList(companyCode)` - 규칙 목록 조회
|
||||
- [x] `getRuleById(ruleId, companyCode)` - 특정 규칙 조회
|
||||
- [x] `createRule(config, companyCode, userId)` - 규칙 생성
|
||||
- [x] `updateRule(ruleId, updates, companyCode)` - 규칙 수정
|
||||
- [x] `deleteRule(ruleId, companyCode)` - 규칙 삭제
|
||||
- [x] `generateCode(ruleId, companyCode)` - 코드 생성
|
||||
- [x] `resetSequence(ruleId, companyCode)` - 시퀀스 초기화
|
||||
|
||||
**핵심 로직**:
|
||||
- 트랜잭션 관리 (BEGIN/COMMIT/ROLLBACK)
|
||||
- 멀티테넌시 필터링 (company_code 기반)
|
||||
- JSON 설정 직렬화/역직렬화
|
||||
- 날짜 형식 변환 (YYYY, YYYYMMDD 등)
|
||||
- 순번 자동 증가 및 제로 패딩
|
||||
|
||||
#### 2.2 컨트롤러 레이어
|
||||
|
||||
**파일**: `backend-node/src/controllers/numberingRuleController.ts`
|
||||
|
||||
**구현된 엔드포인트**:
|
||||
- [x] `GET /api/numbering-rules` - 규칙 목록 조회
|
||||
- [x] `GET /api/numbering-rules/:ruleId` - 특정 규칙 조회
|
||||
- [x] `POST /api/numbering-rules` - 규칙 생성
|
||||
- [x] `PUT /api/numbering-rules/:ruleId` - 규칙 수정
|
||||
- [x] `DELETE /api/numbering-rules/:ruleId` - 규칙 삭제
|
||||
- [x] `POST /api/numbering-rules/:ruleId/generate` - 코드 생성
|
||||
- [x] `POST /api/numbering-rules/:ruleId/reset` - 시퀀스 초기화
|
||||
|
||||
**보안 및 검증**:
|
||||
- `authenticateToken` 미들웨어로 인증 확인
|
||||
- 입력값 검증 (필수 필드, 파트 최소 개수)
|
||||
- 에러 핸들링 및 적절한 HTTP 상태 코드 반환
|
||||
|
||||
#### 2.3 라우터 등록
|
||||
|
||||
**파일**: `backend-node/src/app.ts`
|
||||
|
||||
```typescript
|
||||
import numberingRuleController from "./controllers/numberingRuleController";
|
||||
app.use("/api/numbering-rules", numberingRuleController);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. 프론트엔드 레이어 ✅
|
||||
|
||||
#### 3.1 타입 정의
|
||||
|
||||
**파일**: `frontend/types/numbering-rule.ts`
|
||||
|
||||
**정의된 타입**:
|
||||
- [x] `CodePartType` - 파트 유형 (prefix/sequence/date/year/month/custom)
|
||||
- [x] `GenerationMethod` - 생성 방식 (auto/manual)
|
||||
- [x] `DateFormat` - 날짜 형식 (YYYY/YYYYMMDD 등)
|
||||
- [x] `NumberingRulePart` - 단일 파트 인터페이스
|
||||
- [x] `NumberingRuleConfig` - 전체 규칙 인터페이스
|
||||
- [x] 상수 옵션 배열 (UI용)
|
||||
|
||||
#### 3.2 API 클라이언트
|
||||
|
||||
**파일**: `frontend/lib/api/numberingRule.ts`
|
||||
|
||||
**구현된 함수**:
|
||||
- [x] `getNumberingRules()` - 규칙 목록 조회
|
||||
- [x] `getNumberingRuleById(ruleId)` - 특정 규칙 조회
|
||||
- [x] `createNumberingRule(config)` - 규칙 생성
|
||||
- [x] `updateNumberingRule(ruleId, config)` - 규칙 수정
|
||||
- [x] `deleteNumberingRule(ruleId)` - 규칙 삭제
|
||||
- [x] `generateCode(ruleId)` - 코드 생성
|
||||
- [x] `resetSequence(ruleId)` - 시퀀스 초기화
|
||||
|
||||
**기술 스택**:
|
||||
- Axios 기반 API 클라이언트
|
||||
- 에러 핸들링 및 응답 타입 정의
|
||||
|
||||
#### 3.3 컴포넌트 구조
|
||||
|
||||
```
|
||||
frontend/components/numbering-rule/
|
||||
├── NumberingRuleDesigner.tsx # 메인 디자이너 (좌우 분할)
|
||||
├── NumberingRulePreview.tsx # 실시간 미리보기
|
||||
├── NumberingRuleCard.tsx # 단일 파트 카드
|
||||
├── AutoConfigPanel.tsx # 자동 생성 설정
|
||||
└── ManualConfigPanel.tsx # 직접 입력 설정
|
||||
```
|
||||
|
||||
#### 3.4 주요 컴포넌트 기능
|
||||
|
||||
**NumberingRuleDesigner** (메인 컴포넌트):
|
||||
- [x] 좌측: 저장된 규칙 목록 (카드 리스트)
|
||||
- [x] 우측: 규칙 편집 영역 (파트 추가/수정/삭제)
|
||||
- [x] 실시간 미리보기
|
||||
- [x] 규칙 저장/불러오기/삭제
|
||||
- [x] 타이틀 편집 기능
|
||||
- [x] 로딩 상태 관리
|
||||
|
||||
**NumberingRulePreview**:
|
||||
- [x] 설정된 규칙에 따라 실시간 코드 생성
|
||||
- [x] 컴팩트 모드 지원
|
||||
- [x] useMemo로 성능 최적화
|
||||
|
||||
**NumberingRuleCard**:
|
||||
- [x] 파트 유형 선택 (Select)
|
||||
- [x] 생성 방식 선택 (자동/수동)
|
||||
- [x] 동적 설정 패널 표시
|
||||
- [x] 삭제 버튼
|
||||
|
||||
**AutoConfigPanel**:
|
||||
- [x] 파트 유형별 설정 UI
|
||||
- [x] 접두사, 순번, 날짜, 연도, 월, 커스텀
|
||||
- [x] 입력값 검증 및 가이드 텍스트
|
||||
|
||||
**ManualConfigPanel**:
|
||||
- [x] 직접 입력값 설정
|
||||
- [x] 플레이스홀더 설정
|
||||
|
||||
---
|
||||
|
||||
## 기술적 특징
|
||||
|
||||
### Shadcn/ui 스타일 가이드 준수
|
||||
|
||||
- 반응형 크기: `h-8 sm:h-10`, `text-xs sm:text-sm`
|
||||
- 색상 토큰: `bg-muted`, `text-muted-foreground`, `border-border`
|
||||
- 간격: `space-y-3 sm:space-y-4`, `gap-4`
|
||||
- 상태: `hover:bg-accent`, `disabled:opacity-50`
|
||||
|
||||
### 실시간 속성 편집 패턴
|
||||
|
||||
```typescript
|
||||
const [currentRule, setCurrentRule] = useState<NumberingRuleConfig | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (currentRule) {
|
||||
onChange?.(currentRule); // 상위 컴포넌트로 실시간 전파
|
||||
}
|
||||
}, [currentRule, onChange]);
|
||||
|
||||
const handleUpdatePart = useCallback((partId: string, updates: Partial<NumberingRulePart>) => {
|
||||
setCurrentRule((prev) => {
|
||||
if (!prev) return null;
|
||||
return {
|
||||
...prev,
|
||||
parts: prev.parts.map((part) => (part.id === partId ? { ...part, ...updates } : part)),
|
||||
};
|
||||
});
|
||||
}, []);
|
||||
```
|
||||
|
||||
### 멀티테넌시 지원
|
||||
|
||||
```typescript
|
||||
// 백엔드 쿼리
|
||||
WHERE company_code = $1 OR company_code = '*'
|
||||
|
||||
// 일반 회사는 자신의 데이터만 조회
|
||||
// company_code = "*"는 최고 관리자 전용 데이터
|
||||
```
|
||||
|
||||
### 에러 처리 및 사용자 피드백
|
||||
|
||||
```typescript
|
||||
try {
|
||||
const response = await createNumberingRule(config);
|
||||
if (response.success) {
|
||||
toast.success("채번 규칙이 저장되었습니다");
|
||||
} else {
|
||||
toast.error(response.error || "저장 실패");
|
||||
}
|
||||
} catch (error: any) {
|
||||
toast.error(`저장 실패: ${error.message}`);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 남은 작업
|
||||
|
||||
### 화면관리 시스템 통합 (TODO)
|
||||
|
||||
다음 파일들을 생성하여 화면관리 시스템에 컴포넌트를 등록해야 합니다:
|
||||
|
||||
```
|
||||
frontend/lib/registry/components/numbering-rule/
|
||||
├── index.ts # 컴포넌트 정의 및 등록
|
||||
├── NumberingRuleComponent.tsx # 래퍼 컴포넌트
|
||||
├── NumberingRuleConfigPanel.tsx # 속성 설정 패널
|
||||
└── types.ts # 컴포넌트 설정 타입
|
||||
```
|
||||
|
||||
**등록 예시**:
|
||||
```typescript
|
||||
export const NumberingRuleDefinition = createComponentDefinition({
|
||||
id: "numbering-rule",
|
||||
name: "코드 채번 규칙",
|
||||
category: ComponentCategory.ADMIN,
|
||||
component: NumberingRuleWrapper,
|
||||
configPanel: NumberingRuleConfigPanel,
|
||||
defaultSize: { width: 1200, height: 800 },
|
||||
icon: "Hash",
|
||||
tags: ["코드", "채번", "규칙", "관리자"],
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 테스트 가이드
|
||||
|
||||
### 백엔드 API 테스트 (Postman/Thunder Client)
|
||||
|
||||
#### 1. 규칙 목록 조회
|
||||
```bash
|
||||
GET http://localhost:8080/api/numbering-rules
|
||||
Authorization: Bearer {token}
|
||||
```
|
||||
|
||||
#### 2. 규칙 생성
|
||||
```bash
|
||||
POST http://localhost:8080/api/numbering-rules
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer {token}
|
||||
|
||||
{
|
||||
"ruleId": "PROD_CODE",
|
||||
"ruleName": "제품 코드 규칙",
|
||||
"separator": "-",
|
||||
"parts": [
|
||||
{
|
||||
"order": 1,
|
||||
"partType": "prefix",
|
||||
"generationMethod": "auto",
|
||||
"autoConfig": { "prefix": "PROD" }
|
||||
},
|
||||
{
|
||||
"order": 2,
|
||||
"partType": "date",
|
||||
"generationMethod": "auto",
|
||||
"autoConfig": { "dateFormat": "YYYYMMDD" }
|
||||
},
|
||||
{
|
||||
"order": 3,
|
||||
"partType": "sequence",
|
||||
"generationMethod": "auto",
|
||||
"autoConfig": { "sequenceLength": 4, "startFrom": 1 }
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. 코드 생성
|
||||
```bash
|
||||
POST http://localhost:8080/api/numbering-rules/PROD_CODE/generate
|
||||
Authorization: Bearer {token}
|
||||
|
||||
Response:
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"code": "PROD-20251104-0001"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 프론트엔드 테스트
|
||||
|
||||
1. **새 규칙 생성**:
|
||||
- "새 규칙 생성" 버튼 클릭
|
||||
- 규칙명 입력
|
||||
- "규칙 추가" 버튼으로 파트 추가
|
||||
- 각 파트의 설정 변경
|
||||
- "저장" 버튼 클릭
|
||||
|
||||
2. **미리보기 확인**:
|
||||
- 파트 추가/수정 시 실시간으로 코드 미리보기 업데이트 확인
|
||||
- 구분자 변경 시 반영 확인
|
||||
|
||||
3. **규칙 편집**:
|
||||
- 좌측 목록에서 규칙 선택
|
||||
- 우측 편집 영역에서 수정
|
||||
- 저장 후 목록에 반영 확인
|
||||
|
||||
4. **규칙 삭제**:
|
||||
- 목록 카드의 삭제 버튼 클릭
|
||||
- 목록에서 제거 확인
|
||||
|
||||
---
|
||||
|
||||
## 파일 목록
|
||||
|
||||
### 백엔드
|
||||
- `db/migrations/034_create_numbering_rules.sql` (마이그레이션)
|
||||
- `backend-node/src/services/numberingRuleService.ts` (서비스)
|
||||
- `backend-node/src/controllers/numberingRuleController.ts` (컨트롤러)
|
||||
- `backend-node/src/app.ts` (라우터 등록)
|
||||
|
||||
### 프론트엔드
|
||||
- `frontend/types/numbering-rule.ts` (타입 정의)
|
||||
- `frontend/lib/api/numberingRule.ts` (API 클라이언트)
|
||||
- `frontend/components/numbering-rule/NumberingRuleDesigner.tsx`
|
||||
- `frontend/components/numbering-rule/NumberingRulePreview.tsx`
|
||||
- `frontend/components/numbering-rule/NumberingRuleCard.tsx`
|
||||
- `frontend/components/numbering-rule/AutoConfigPanel.tsx`
|
||||
- `frontend/components/numbering-rule/ManualConfigPanel.tsx`
|
||||
|
||||
---
|
||||
|
||||
## 다음 단계
|
||||
|
||||
1. **마이그레이션 실행**:
|
||||
```sql
|
||||
psql -U postgres -d ilshin -f db/migrations/034_create_numbering_rules.sql
|
||||
```
|
||||
|
||||
2. **백엔드 서버 확인** (이미 실행 중이면 자동 반영)
|
||||
|
||||
3. **화면관리 통합**:
|
||||
- 레지스트리 컴포넌트 파일 생성
|
||||
- 컴포넌트 등록 및 화면 디자이너에서 사용 가능하도록 설정
|
||||
|
||||
4. **테스트**:
|
||||
- API 테스트 (Postman)
|
||||
- UI 테스트 (브라우저)
|
||||
- 멀티테넌시 검증
|
||||
|
||||
---
|
||||
|
||||
**작성 완료**: 2025-11-04
|
||||
**문의**: 백엔드 및 프론트엔드 핵심 기능 완료, 화면관리 통합만 남음
|
||||
|
||||
Reference in New Issue
Block a user