ERP-node/docs/공통코드_관리_시스템_설계.md

763 lines
24 KiB
Markdown
Raw Normal View History

# 공통코드 관리 시스템 설계 문서
## 📋 목차
1. [시스템 개요](#🎯-시스템-개요)
2. [아키텍처 구조](#🏗️-아키텍처-구조)
3. [핵심 기능](#🚀-핵심-기능)
4. [데이터베이스 설계](#🗄️-데이터베이스-설계)
5. [화면 구성 요소](#🎨-화면-구성-요소)
6. [API 설계](#🌐-api-설계)
7. [프론트엔드 구현](#🎭-프론트엔드-구현)
8. [백엔드 구현](#⚙️-백엔드-구현)
9. [사용 시나리오](#🎬-사용-시나리오)
10. [개발 계획](#📅-개발-계획-및-진행상황)
## 🎯 시스템 개요
### 공통코드 관리 시스템이란?
공통코드 관리 시스템은 **시스템에서 사용하는 공통적인 코드값들을 중앙에서 관리하는 기능**입니다. 드롭다운, 선택박스 등에서 반복적으로 사용되는 코드-값 쌍을 체계적으로 관리하여 데이터 일관성을 보장하고 개발 효율성을 높입니다.
### 주요 특징
- **중앙 집중 관리**: 모든 공통코드를 한 곳에서 통합 관리
- **카테고리 기반 분류**: 코드를 카테고리별로 체계적 분류
- **다국어 지원**: 한국어/영어 코드명 지원
- **화면관리 시스템 연계**: 웹 타입 'code'와 완벽 연동
- **실시간 반영**: 코드 변경사항 즉시 시스템 전체 반영
- **관리자 전용**: 관리자 메뉴에서만 접근 가능
### 🎯 **필수 요구사항**
-**관리자 메뉴 접근**: 관리자 메뉴에서만 접근 가능
-**코드 카테고리 관리**: 카테고리 생성/수정/삭제
-**코드 상세 관리**: 코드값과 코드명 매핑 관리
-**정렬 순서 관리**: 코드 표시 순서 조정
-**활성/비활성 관리**: 코드 사용 여부 제어
-**검색 및 필터링**: 대량 코드 효율적 관리
-**화면관리 연계**: column_labels.code_category와 연동
## 🏗️ 아키텍처 구조
### 전체 구조도
```
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Frontend │ │ Backend │ │ Database │
│ │ │ │ │ │
│ ┌─────────────┐ │ │ ┌─────────────┐ │ │ ┌─────────────┐ │
│ │ CodeCategory│ │ │ │ CommonCode │ │ │ │ code_ │ │
│ │ Management │ │ │ │ Controller │ │ │ │ category │ │
│ │ (React) │ │ │ │ │ │ │ │ Table │ │
│ └─────────────┘ │ │ └─────────────┘ │ │ └─────────────┘ │
│ │ │ │ │ │
│ ┌─────────────┐ │ │ ┌─────────────┐ │ │ ┌─────────────┐ │
│ │ CodeDetail │ │ │ │ CommonCode │ │ │ │ code_info │ │
│ │ Management │ │ │ │ Service │ │ │ │ Table │ │
│ │ (React) │ │ │ │ │ │ │ │ │ │
│ └─────────────┘ │ │ └─────────────┘ │ │ └─────────────┘ │
└─────────────────┘ └─────────────────┘ └─────────────────┘
```
### 화면관리 시스템 연계
```
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 화면관리 시스템 │ │ 공통코드 관리 │ │ 실제 화면 │
│ │ │ │ │ │
│ column_labels │───▶│ code_category │───▶│ Select Widget │
│ web_type='code' │ │ code_info │ │ <option>값 │
│ code_category │ │ │ │ │
└─────────────────┘ └─────────────────┘ └─────────────────┘
```
## 🚀 핵심 기능
### 1. 코드 카테고리 관리
- **카테고리 생성**: 새로운 코드 카테고리 추가
- **카테고리 수정**: 카테고리명, 설명 수정
- **카테고리 삭제**: 사용하지 않는 카테고리 삭제 (CASCADE)
- **카테고리 활성화**: 카테고리 사용 여부 제어
- **카테고리 검색**: 카테고리명으로 빠른 검색
### 2. 코드 상세 관리
- **코드 생성**: 카테고리 내 새로운 코드 추가
- **코드 수정**: 코드값, 코드명, 영문명 수정
- **코드 삭제**: 불필요한 코드 삭제
- **정렬 순서**: 드래그앤드롭으로 순서 변경
- **일괄 업로드**: CSV/Excel 파일로 대량 등록
- **일괄 다운로드**: 현재 코드 데이터 내보내기
### 3. 화면관리 연계
- **자동 옵션 생성**: code_category 기반 select 옵션 자동 생성
- **실시간 반영**: 코드 변경 시 관련 화면 즉시 업데이트
- **참조 관계 표시**: 어떤 화면에서 사용 중인지 표시
### 4. 검색 및 필터링
- **통합 검색**: 카테고리명, 코드값, 코드명 통합 검색
- **상태 필터**: 활성/비활성 코드 필터링
- **카테고리 필터**: 특정 카테고리만 표시
- **페이징**: 대량 데이터 효율적 표시
## 🗄️ 데이터베이스 설계
### 1. 코드 카테고리 테이블
```sql
-- 공통코드 카테고리 테이블
CREATE TABLE code_category (
category_code VARCHAR(50) PRIMARY KEY,
category_name VARCHAR(100) NOT NULL,
category_name_eng VARCHAR(100),
description TEXT,
sort_order INTEGER DEFAULT 0,
is_active CHAR(1) DEFAULT 'Y',
created_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
created_by VARCHAR(50),
updated_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_by VARCHAR(50)
);
-- 인덱스 추가
CREATE INDEX idx_code_category_active ON code_category(is_active);
CREATE INDEX idx_code_category_sort ON code_category(sort_order);
```
### 2. 코드 상세 정보 테이블
```sql
-- 공통코드 상세 정보 테이블
CREATE TABLE code_info (
code_category VARCHAR(50) NOT NULL,
code_value VARCHAR(50) NOT NULL,
code_name VARCHAR(100) NOT NULL,
code_name_eng VARCHAR(100),
description TEXT,
sort_order INTEGER DEFAULT 0,
is_active CHAR(1) DEFAULT 'Y',
created_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
created_by VARCHAR(50),
updated_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_by VARCHAR(50),
-- 복합 기본키
PRIMARY KEY (code_category, code_value),
-- 외래키 제약조건
CONSTRAINT fk_code_info_category
FOREIGN KEY (code_category) REFERENCES code_category(category_code)
ON DELETE CASCADE
ON UPDATE CASCADE
);
-- 성능을 위한 인덱스
CREATE INDEX idx_code_info_category ON code_info(code_category);
CREATE INDEX idx_code_info_active ON code_info(is_active);
CREATE INDEX idx_code_info_sort ON code_info(code_category, sort_order);
```
### 3. 기본 데이터 삽입
```sql
-- 시스템 필수 공통코드 카테고리
INSERT INTO code_category VALUES
('USER_STATUS', '사용자 상태', 'User Status', '사용자의 활성화 상태', 1, 'Y', now(), 'SYSTEM', now(), 'SYSTEM'),
('USER_TYPE', '사용자 타입', 'User Type', '사용자 권한 타입', 2, 'Y', now(), 'SYSTEM', now(), 'SYSTEM'),
('DEPT_TYPE', '부서 타입', 'Department Type', '부서 분류', 3, 'Y', now(), 'SYSTEM', now(), 'SYSTEM'),
('LANGUAGE', '언어 코드', 'Language Code', '시스템 지원 언어', 4, 'Y', now(), 'SYSTEM', now(), 'SYSTEM'),
('CURRENCY', '통화 코드', 'Currency Code', '시스템 지원 통화', 5, 'Y', now(), 'SYSTEM', now(), 'SYSTEM');
-- 사용자 상태 코드
INSERT INTO code_info VALUES
('USER_STATUS', 'A', '활성', 'Active', '활성 사용자', 1, 'Y', now(), 'SYSTEM', now(), 'SYSTEM'),
('USER_STATUS', 'I', '비활성', 'Inactive', '비활성 사용자', 2, 'Y', now(), 'SYSTEM', now(), 'SYSTEM'),
('USER_STATUS', 'S', '휴면', 'Sleep', '휴면 사용자', 3, 'Y', now(), 'SYSTEM', now(), 'SYSTEM'),
('USER_STATUS', 'D', '삭제', 'Deleted', '삭제된 사용자', 4, 'Y', now(), 'SYSTEM', now(), 'SYSTEM');
-- 사용자 타입 코드
INSERT INTO code_info VALUES
('USER_TYPE', 'ADMIN', '관리자', 'Administrator', '시스템 관리자', 1, 'Y', now(), 'SYSTEM', now(), 'SYSTEM'),
('USER_TYPE', 'USER', '일반사용자', 'User', '일반 사용자', 2, 'Y', now(), 'SYSTEM', now(), 'SYSTEM'),
('USER_TYPE', 'GUEST', '게스트', 'Guest', '게스트 사용자', 3, 'Y', now(), 'SYSTEM', now(), 'SYSTEM'),
('USER_TYPE', 'PARTNER', '협력업체', 'Partner', '협력업체 사용자', 4, 'Y', now(), 'SYSTEM', now(), 'SYSTEM');
```
## 🎨 화면 구성 요소
### 1. 전체 레이아웃
```
┌─────────────────────────────────────────────────────────────┐
│ 공통코드 관리 시스템 │
├─────────────────────────────────────────────────────────────┤
│ [새 카테고리] [🔍 검색박스] │
├─────────────────┬───────────────────────────────────────────┤
│ 코드 카테고리 │ 코드 상세 정보 │
│ │ │
│ ┌─────────────┐ │ ┌─────────────────────────────────────────┐ │
│ │ USER_STATUS │ │ │ 코드값 │ 코드명 │ 영문명 │ 순서 │ 상태 │ │
│ │ 사용자 상태 │ │ │ A │ 활성 │ Active │ 1 │ ✓ │ │
│ │ │ │ │ I │ 비활성 │ Inactive │ 2 │ ✓ │ │
│ │ USER_TYPE │ │ │ S │ 휴면 │ Sleep │ 3 │ ✓ │ │
│ │ 사용자 타입 │ │ │ D │ 삭제 │ Deleted │ 4 │ ✓ │ │
│ │ │ │ └─────────────────────────────────────────┘ │
│ │ DEPT_TYPE │ │ │
│ │ 부서 타입 │ │ [+ 새 코드 추가] [정렬] │
│ └─────────────┘ │ │
└─────────────────┴───────────────────────────────────────────┘
```
### 2. 주요 컴포넌트
#### CodeCategoryList (좌측 패널)
```typescript
interface CodeCategoryListProps {
categories: CodeCategory[];
selectedCategory: string | null;
onCategorySelect: (categoryCode: string) => void;
onCategoryCreate: () => void;
onCategoryEdit: (category: CodeCategory) => void;
onCategoryDelete: (categoryCode: string) => void;
}
```
#### CodeDetailTable (우측 패널)
```typescript
interface CodeDetailTableProps {
categoryCode: string;
codes: CodeInfo[];
onCodeCreate: () => void;
onCodeEdit: (code: CodeInfo) => void;
onCodeDelete: (codeValue: string) => void;
onSortOrderChange: (codes: CodeInfo[]) => void;
}
```
#### CodeEditModal (편집 모달)
```typescript
interface CodeEditModalProps {
isOpen: boolean;
mode: "create" | "edit";
categoryCode?: string;
codeData?: CodeInfo;
onSave: (data: CodeInfo) => void;
onClose: () => void;
}
```
## 🌐 API 설계
### 1. 코드 카테고리 API
#### 카테고리 목록 조회
```typescript
GET /api/common-codes/categories
Query: {
search?: string;
isActive?: boolean;
page?: number;
size?: number;
}
Response: {
success: boolean;
data: CodeCategory[];
total: number;
}
```
#### 카테고리 생성
```typescript
POST /api/common-codes/categories
Body: {
categoryCode: string;
categoryName: string;
categoryNameEng?: string;
description?: string;
sortOrder?: number;
}
```
#### 카테고리 수정
```typescript
PUT /api/common-codes/categories/:categoryCode
Body: {
categoryName?: string;
categoryNameEng?: string;
description?: string;
sortOrder?: number;
isActive?: boolean;
}
```
#### 카테고리 삭제
```typescript
DELETE /api/common-codes/categories/:categoryCode
```
### 2. 코드 상세 API
#### 카테고리별 코드 목록 조회
```typescript
GET /api/common-codes/categories/:categoryCode/codes
Query: {
search?: string;
isActive?: boolean;
}
Response: {
success: boolean;
data: CodeInfo[];
}
```
#### 코드 생성
```typescript
POST /api/common-codes/categories/:categoryCode/codes
Body: {
codeValue: string;
codeName: string;
codeNameEng?: string;
description?: string;
sortOrder?: number;
}
```
#### 코드 수정
```typescript
PUT /api/common-codes/categories/:categoryCode/codes/:codeValue
Body: {
codeName?: string;
codeNameEng?: string;
description?: string;
sortOrder?: number;
isActive?: boolean;
}
```
#### 코드 삭제
```typescript
DELETE /api/common-codes/categories/:categoryCode/codes/:codeValue
```
#### 코드 순서 변경
```typescript
PUT /api/common-codes/categories/:categoryCode/codes/reorder
Body: {
codes: Array<{
codeValue: string;
sortOrder: number;
}>;
}
```
### 3. 화면관리 연계 API
#### 카테고리별 옵션 조회 (화면관리용)
```typescript
GET /api/common-codes/categories/:categoryCode/options
Response: {
success: boolean;
data: Array<{
value: string;
label: string;
labelEng?: string;
}>;
}
```
## 🎭 프론트엔드 구현
### 1. 페이지 구조
```typescript
// app/(main)/admin/commonCode/page.tsx
export default function CommonCodeManagementPage() {
const [selectedCategory, setSelectedCategory] = useState<string | null>(null);
const [categories, setCategories] = useState<CodeCategory[]>([]);
const [codes, setCodes] = useState<CodeInfo[]>([]);
return (
<div className="flex h-full">
<CodeCategoryPanel
categories={categories}
selectedCategory={selectedCategory}
onCategorySelect={setSelectedCategory}
/>
<CodeDetailPanel categoryCode={selectedCategory} codes={codes} />
</div>
);
}
```
### 2. 주요 컴포넌트
#### CodeCategoryPanel
```typescript
// components/admin/commonCode/CodeCategoryPanel.tsx
export function CodeCategoryPanel({
categories,
selectedCategory,
onCategorySelect,
}: CodeCategoryPanelProps) {
return (
<div className="w-80 border-r bg-white">
<div className="p-4 border-b">
<h2 className="font-semibold">코드 카테고리</h2>
<Button onClick={onCreateCategory}>
<Plus className="w-4 h-4 mr-2" />새 카테고리
</Button>
</div>
<div className="p-2">
{categories.map((category) => (
<CategoryItem
key={category.categoryCode}
category={category}
isSelected={selectedCategory === category.categoryCode}
onClick={() => onCategorySelect(category.categoryCode)}
/>
))}
</div>
</div>
);
}
```
#### CodeDetailPanel
```typescript
// components/admin/commonCode/CodeDetailPanel.tsx
export function CodeDetailPanel({ categoryCode, codes }: CodeDetailPanelProps) {
if (!categoryCode) {
return (
<div className="flex-1 flex items-center justify-center">
<p className="text-gray-500">카테고리를 선택하세요</p>
</div>
);
}
return (
<div className="flex-1 p-6">
<div className="flex justify-between items-center mb-4">
<h2 className="text-xl font-semibold">코드 상세 정보</h2>
<Button onClick={onCreateCode}>
<Plus className="w-4 h-4 mr-2" />새 코드
</Button>
</div>
<CodeTable
codes={codes}
onEdit={handleEditCode}
onDelete={handleDeleteCode}
onReorder={handleReorderCodes}
/>
</div>
);
}
```
## ⚙️ 백엔드 구현
### 1. Controller
```typescript
// backend-node/src/controllers/commonCodeController.ts
export class CommonCodeController {
// 카테고리 목록 조회
async getCategories(req: Request, res: Response) {
try {
const { search, isActive, page = 1, size = 20 } = req.query;
const categories = await this.commonCodeService.getCategories({
search: search as string,
isActive: isActive === "true",
page: Number(page),
size: Number(size),
});
res.json({
success: true,
data: categories.data,
total: categories.total,
});
} catch (error) {
res.status(500).json({
success: false,
message: error.message,
});
}
}
// 카테고리별 코드 목록 조회
async getCodes(req: Request, res: Response) {
try {
const { categoryCode } = req.params;
const { search, isActive } = req.query;
const codes = await this.commonCodeService.getCodes(categoryCode, {
search: search as string,
isActive: isActive === "true",
});
res.json({
success: true,
data: codes,
});
} catch (error) {
res.status(500).json({
success: false,
message: error.message,
});
}
}
}
```
### 2. Service
```typescript
// backend-node/src/services/commonCodeService.ts
export class CommonCodeService {
// 카테고리 목록 조회
async getCategories(params: GetCategoriesParams) {
const { search, isActive, page, size } = params;
let whereClause = "";
const queryParams: any[] = [];
if (search) {
whereClause +=
" AND (category_name ILIKE $" +
(queryParams.length + 1) +
" OR category_code ILIKE $" +
(queryParams.length + 1) +
")";
queryParams.push(`%${search}%`);
}
if (isActive !== undefined) {
whereClause += " AND is_active = $" + (queryParams.length + 1);
queryParams.push(isActive ? "Y" : "N");
}
const offset = (page - 1) * size;
const [categories, total] = await Promise.all([
this.db.query(
`
SELECT * FROM code_category
WHERE 1=1 ${whereClause}
ORDER BY sort_order, category_code
LIMIT $${queryParams.length + 1} OFFSET $${queryParams.length + 2}
`,
[...queryParams, size, offset]
),
this.db.query(
`
SELECT COUNT(*) as count FROM code_category
WHERE 1=1 ${whereClause}
`,
queryParams
),
]);
return {
data: categories.rows,
total: parseInt(total.rows[0].count),
};
}
// 코드 목록 조회
async getCodes(categoryCode: string, params: GetCodesParams) {
const { search, isActive } = params;
let whereClause = "WHERE code_category = $1";
const queryParams: any[] = [categoryCode];
if (search) {
whereClause +=
" AND (code_name ILIKE $" +
(queryParams.length + 1) +
" OR code_value ILIKE $" +
(queryParams.length + 1) +
")";
queryParams.push(`%${search}%`);
}
if (isActive !== undefined) {
whereClause += " AND is_active = $" + (queryParams.length + 1);
queryParams.push(isActive ? "Y" : "N");
}
const result = await this.db.query(
`
SELECT * FROM code_info
${whereClause}
ORDER BY sort_order, code_value
`,
queryParams
);
return result.rows;
}
}
```
## 🎬 사용 시나리오
### 1. 새로운 공통코드 카테고리 생성
1. **관리자 메뉴 접근**: 관리자가 공통코드 관리 메뉴 클릭
2. **카테고리 생성**: "새 카테고리" 버튼 클릭
3. **정보 입력**: 카테고리 코드, 이름, 설명 입력
4. **저장**: 카테고리 생성 완료
5. **코드 추가**: 생성된 카테고리에 코드 상세 정보 추가
### 2. 기존 공통코드 수정
1. **카테고리 선택**: 좌측 패널에서 수정할 카테고리 선택
2. **코드 선택**: 우측 테이블에서 수정할 코드 클릭
3. **정보 수정**: 코드명, 영문명, 설명 등 수정
4. **순서 변경**: 드래그앤드롭으로 표시 순서 조정
5. **저장**: 변경사항 저장
### 3. 화면관리 시스템 연계
1. **테이블 타입 관리**: column_labels에서 web_type을 'code'로 설정
2. **카테고리 선택**: code_category에 공통코드 카테고리 지정
3. **화면 설계**: 화면관리에서 해당 컬럼을 드래그하여 위젯 생성
4. **자동 옵션**: select 위젯에 공통코드 옵션 자동 생성
5. **실시간 반영**: 공통코드 변경 시 화면에 즉시 반영
## 📅 개발 계획 및 진행상황
2025-09-02 11:30:19 +09:00
### ✅ Phase 1: (완료)
- [x] 데이터베이스 스키마 설계 및 생성
- [x] Prisma 스키마에 공통코드 모델 추가
- [x] code_category, code_info 테이블 생성
- [x] 기본 데이터 삽입 스크립트 작성 및 실행
**완료 내용:**
- Prisma schema.prisma에 공통코드 모델 추가
- Docker 컨테이너에서 테이블 생성 스크립트 실행
- 5개 카테고리, 22개 기본 코드 데이터 삽입 완료
2025-09-02 11:30:19 +09:00
### ✅ Phase 2: 백엔드 API 구현 (완료)
2025-09-02 11:30:19 +09:00
- [x] CommonCodeController 구현
- [x] CommonCodeService 구현
- [x] 카테고리 CRUD API 구현
- [x] 코드 상세 CRUD API 구현
- [x] 정렬 순서 변경 API 구현
2025-09-02 11:30:19 +09:00
**완료 내용:**
- 모든 CRUD API 정상 작동 확인
- JWT 인증 연동 완료
- 검색, 정렬, 페이징 기능 구현
- Prisma ORM 연동 완료
- TypeScript 타입 정의 완료
2025-09-02 13:18:46 +09:00
### ✅ Phase 3: 프론트엔드 기본 구현 (완료)
2025-09-02 13:18:46 +09:00
- [x] 공통코드 관리 페이지 생성
- [x] CodeCategoryPanel 컴포넌트 구현
- [x] CodeDetailPanel 컴포넌트 구현
- [x] CodeFormModal, CodeCategoryFormModal 구현
- [x] 기본 CRUD 기능 구현
- [x] 관리자 메뉴 통합
- [x] 실시간 데이터 조회 및 표시
- [x] 무한 루프 문제 해결
2025-09-02 13:18:46 +09:00
**완료 내용:**
- 공통코드 관리 페이지 (/admin/commonCode) 완전 구현
- 4개 주요 컴포넌트 구현 완료
- 카테고리 선택 시 실시간 코드 조회 기능
- useCommonCode 커스텀 훅 구현
- API 응답 처리 최적화 완료
- 사용자 인터페이스 완성
### ⏳ Phase 4: 고급 기능 구현 (예정)
- [ ] 드래그앤드롭 정렬 기능
- [ ] 검색 및 필터링 기능
- [ ] 일괄 업로드/다운로드 기능
- [ ] 코드 편집 모달 구현
**목표 기간**: 2일
### ⏳ Phase 5: 화면관리 연계 (예정)
- [ ] column_labels와 연동 확인
- [ ] 화면관리에서 code 타입 위젯 테스트
- [ ] 공통코드 변경 시 화면 반영 테스트
- [ ] 옵션 조회 API 구현
**목표 기간**: 1일
### ⏳ Phase 6: 테스트 및 최적화 (예정)
- [ ] 전체 기능 통합 테스트
- [ ] 성능 최적화
- [ ] 사용자 경험 개선
- [ ] 문서화 및 사용자 가이드
**목표 기간**: 1일
## 🎯 현재 구현 상태
2025-09-02 13:18:46 +09:00
### 📊 **전체 진행률: 50%** 🎉
2025-09-02 13:18:46 +09:00
-**Phase 1**: 기본 구조 및 데이터베이스 (100%) - **완료!**
-**Phase 2**: 백엔드 API 구현 (100%) - **완료!**
-**Phase 3**: 프론트엔드 기본 구현 (100%) - **완료!**
-**Phase 4**: 고급 기능 구현 (0%)
-**Phase 5**: 화면관리 연계 (0%)
-**Phase 6**: 테스트 및 최적화 (0%)
## 🚀 기대 효과
### 1. 개발 효율성 향상
- 공통코드 중앙 관리로 중복 작업 제거
- 화면관리 시스템과 연계로 자동 위젯 생성
### 2. 데이터 일관성 보장
- 모든 시스템에서 동일한 코드값 사용
- 코드 변경 시 전체 시스템 일괄 반영
### 3. 유지보수성 향상
- 코드 변경이 필요할 때 한 곳에서만 수정
- 체계적인 코드 분류 및 관리
### 4. 사용자 경험 개선
- 일관된 선택 옵션 제공
- 다국어 지원으로 글로벌 대응
**공통코드 관리 시스템을 통해 전체 ERP 시스템의 품질과 효율성을 크게 향상시킬 수 있습니다!** 🎉