From 3129e3663fb331b479ec6cdd14bb8cdc3bf84c00 Mon Sep 17 00:00:00 2001 From: hyeonsu Date: Tue, 2 Sep 2025 11:11:48 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B8=B0=EB=B3=B8=20=EA=B5=AC=EC=A1=B0=20?= =?UTF-8?q?=EC=84=A4=EA=B3=84=20=EB=B0=8F=20=EB=8D=B0=EC=9D=B4=ED=84=B0?= =?UTF-8?q?=EB=B2=A0=EC=9D=B4=EC=8A=A4=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend-node/create-common-code-tables.js | 74 +++ backend-node/insert-common-code-data.js | 196 ++++++ backend-node/prisma/schema.prisma | 47 ++ docs/공통코드_관리_시스템_설계.md | 745 ++++++++++++++++++++++ 4 files changed, 1062 insertions(+) create mode 100644 backend-node/create-common-code-tables.js create mode 100644 backend-node/insert-common-code-data.js create mode 100644 docs/공통코드_관리_시스템_설계.md diff --git a/backend-node/create-common-code-tables.js b/backend-node/create-common-code-tables.js new file mode 100644 index 00000000..f3bc6daf --- /dev/null +++ b/backend-node/create-common-code-tables.js @@ -0,0 +1,74 @@ +const { PrismaClient } = require("@prisma/client"); +const prisma = new PrismaClient(); + +async function createCommonCodeTables() { + try { + console.log("=== 공통코드 테이블 생성 시작 ==="); + + // 1. code_category 테이블 생성 + await prisma.$executeRaw` + CREATE TABLE IF NOT EXISTS 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) + ) + `; + console.log("✅ code_category 테이블 생성 완료"); + + // 2. code_info 테이블 생성 + await prisma.$executeRaw` + CREATE TABLE IF NOT EXISTS 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 + ) + `; + console.log("✅ code_info 테이블 생성 완료"); + + // 3. 인덱스 생성 + await prisma.$executeRaw` + CREATE INDEX IF NOT EXISTS idx_code_category_active ON code_category(is_active) + `; + await prisma.$executeRaw` + CREATE INDEX IF NOT EXISTS idx_code_category_sort ON code_category(sort_order) + `; + await prisma.$executeRaw` + CREATE INDEX IF NOT EXISTS idx_code_info_category ON code_info(code_category) + `; + await prisma.$executeRaw` + CREATE INDEX IF NOT EXISTS idx_code_info_active ON code_info(is_active) + `; + await prisma.$executeRaw` + CREATE INDEX IF NOT EXISTS idx_code_info_sort ON code_info(code_category, sort_order) + `; + console.log("✅ 인덱스 생성 완료"); + + console.log("🎉 공통코드 테이블 생성 완료!"); + } catch (error) { + console.error("❌ 오류 발생:", error); + } finally { + await prisma.$disconnect(); + } +} + +createCommonCodeTables(); diff --git a/backend-node/insert-common-code-data.js b/backend-node/insert-common-code-data.js new file mode 100644 index 00000000..3a6731b9 --- /dev/null +++ b/backend-node/insert-common-code-data.js @@ -0,0 +1,196 @@ +const { PrismaClient } = require("@prisma/client"); +const prisma = new PrismaClient(); + +async function insertCommonCodeData() { + try { + console.log("=== 공통코드 기본 데이터 삽입 시작 ==="); + + // 기존 데이터 삭제 (재실행 시 중복 방지) + await prisma.$executeRaw`DELETE FROM code_info WHERE code_category IN ('USER_STATUS', 'USER_TYPE', 'DEPT_TYPE', 'LANGUAGE', 'CURRENCY')`; + await prisma.$executeRaw`DELETE FROM code_category WHERE category_code IN ('USER_STATUS', 'USER_TYPE', 'DEPT_TYPE', 'LANGUAGE', 'CURRENCY')`; + console.log("✅ 기존 데이터 정리 완료"); + + // 1. 카테고리 삽입 + const categories = [ + [ + "USER_STATUS", + "사용자 상태", + "User Status", + "사용자의 활성화 상태를 나타내는 코드", + 1, + ], + [ + "USER_TYPE", + "사용자 타입", + "User Type", + "사용자의 권한 타입을 구분하는 코드", + 2, + ], + [ + "DEPT_TYPE", + "부서 타입", + "Department Type", + "부서의 분류를 나타내는 코드", + 3, + ], + [ + "LANGUAGE", + "언어 코드", + "Language Code", + "시스템에서 지원하는 언어 코드", + 4, + ], + [ + "CURRENCY", + "통화 코드", + "Currency Code", + "시스템에서 지원하는 통화 코드", + 5, + ], + ]; + + for (const [code, name, nameEng, desc, order] of categories) { + await prisma.$executeRaw` + INSERT INTO code_category (category_code, category_name, category_name_eng, description, sort_order, is_active, created_date, created_by, updated_date, updated_by) + VALUES (${code}, ${name}, ${nameEng}, ${desc}, ${order}, 'Y', now(), 'SYSTEM', now(), 'SYSTEM') + `; + } + console.log("✅ 카테고리 데이터 삽입 완료"); + + // 2. 코드 정보 삽입 + const codes = [ + // 사용자 상태 + ["USER_STATUS", "A", "활성", "Active", "정상적으로 활동 중인 사용자", 1], + [ + "USER_STATUS", + "I", + "비활성", + "Inactive", + "일시적으로 비활성화된 사용자", + 2, + ], + [ + "USER_STATUS", + "S", + "휴면", + "Sleep", + "장기간 미접속으로 휴면 상태인 사용자", + 3, + ], + ["USER_STATUS", "D", "삭제", "Deleted", "삭제 처리된 사용자", 4], + + // 사용자 타입 + [ + "USER_TYPE", + "ADMIN", + "관리자", + "Administrator", + "시스템 전체를 관리할 수 있는 최고 권한", + 1, + ], + [ + "USER_TYPE", + "USER", + "일반사용자", + "User", + "일반적인 업무 기능을 사용할 수 있는 사용자", + 2, + ], + [ + "USER_TYPE", + "GUEST", + "게스트", + "Guest", + "제한적인 기능만 사용할 수 있는 게스트 사용자", + 3, + ], + [ + "USER_TYPE", + "PARTNER", + "협력업체", + "Partner", + "협력업체 직원으로 특정 기능만 사용 가능", + 4, + ], + + // 부서 타입 + [ + "DEPT_TYPE", + "SALES", + "영업부", + "Sales Department", + "영업 관련 업무를 담당하는 부서", + 1, + ], + [ + "DEPT_TYPE", + "DEV", + "개발부", + "Development Department", + "시스템 개발을 담당하는 부서", + 2, + ], + [ + "DEPT_TYPE", + "HR", + "인사부", + "Human Resources Department", + "인사 관리를 담당하는 부서", + 3, + ], + [ + "DEPT_TYPE", + "FINANCE", + "재무부", + "Finance Department", + "재무 관리를 담당하는 부서", + 4, + ], + [ + "DEPT_TYPE", + "ADMIN", + "관리부", + "Administration Department", + "일반 관리 업무를 담당하는 부서", + 5, + ], + + // 언어 코드 + ["LANGUAGE", "KR", "한국어", "Korean", "한국어 언어 설정", 1], + ["LANGUAGE", "US", "영어", "English", "영어 언어 설정", 2], + ["LANGUAGE", "CN", "중국어", "Chinese", "중국어 언어 설정", 3], + ["LANGUAGE", "JP", "일본어", "Japanese", "일본어 언어 설정", 4], + + // 통화 코드 + ["CURRENCY", "KRW", "원", "Korean Won", "대한민국 원화", 1], + ["CURRENCY", "USD", "달러", "US Dollar", "미국 달러", 2], + ["CURRENCY", "EUR", "유로", "Euro", "유럽 유로", 3], + ["CURRENCY", "JPY", "엔", "Japanese Yen", "일본 엔화", 4], + ["CURRENCY", "CNY", "위안", "Chinese Yuan", "중국 위안화", 5], + ]; + + for (const [category, value, name, nameEng, desc, order] of codes) { + await prisma.$executeRaw` + INSERT INTO code_info (code_category, code_value, code_name, code_name_eng, description, sort_order, is_active, created_date, created_by, updated_date, updated_by) + VALUES (${category}, ${value}, ${name}, ${nameEng}, ${desc}, ${order}, 'Y', now(), 'SYSTEM', now(), 'SYSTEM') + `; + } + console.log("✅ 코드 정보 데이터 삽입 완료"); + + // 3. 삽입 결과 확인 + const categoryCount = + await prisma.$queryRaw`SELECT COUNT(*) as count FROM code_category WHERE created_by = 'SYSTEM'`; + const codeCount = + await prisma.$queryRaw`SELECT COUNT(*) as count FROM code_info WHERE created_by = 'SYSTEM'`; + + console.log(`📊 삽입된 카테고리 수: ${categoryCount[0].count}`); + console.log(`📊 삽입된 코드 수: ${codeCount[0].count}`); + console.log("🎉 공통코드 기본 데이터 삽입 완료!"); + } catch (error) { + console.error("❌ 오류 발생:", error); + } finally { + await prisma.$disconnect(); + } +} + +insertCommonCodeData(); diff --git a/backend-node/prisma/schema.prisma b/backend-node/prisma/schema.prisma index a80080bf..34099936 100644 --- a/backend-node/prisma/schema.prisma +++ b/backend-node/prisma/schema.prisma @@ -5145,3 +5145,50 @@ model screen_menu_assignments { @@unique([screen_id, menu_objid, company_code]) @@index([company_code]) } + +// ===================================================== +// 공통코드 관리 시스템 모델 +// ===================================================== + +/// 공통코드 카테고리 테이블 +model code_category { + category_code String @id @db.VarChar(50) + category_name String @db.VarChar(100) + category_name_eng String? @db.VarChar(100) + description String? @db.Text + sort_order Int @default(0) + is_active String @default("Y") @db.Char(1) + created_date DateTime? @default(now()) @db.Timestamp(6) + created_by String? @db.VarChar(50) + updated_date DateTime? @default(now()) @db.Timestamp(6) + updated_by String? @db.VarChar(50) + + // 관계 - 코드 상세 정보 + codes code_info[] + + @@index([is_active]) + @@index([sort_order]) +} + +/// 공통코드 상세 정보 테이블 +model code_info { + code_category String @db.VarChar(50) + code_value String @db.VarChar(50) + code_name String @db.VarChar(100) + code_name_eng String? @db.VarChar(100) + description String? @db.Text + sort_order Int @default(0) + is_active String @default("Y") @db.Char(1) + created_date DateTime? @default(now()) @db.Timestamp(6) + created_by String? @db.VarChar(50) + updated_date DateTime? @default(now()) @db.Timestamp(6) + updated_by String? @db.VarChar(50) + + // 관계 - 코드 카테고리 + category code_category @relation(fields: [code_category], references: [category_code], onDelete: Cascade, onUpdate: Cascade) + + @@id([code_category, code_value]) + @@index([code_category]) + @@index([is_active]) + @@index([code_category, sort_order]) +} diff --git a/docs/공통코드_관리_시스템_설계.md b/docs/공통코드_관리_시스템_설계.md new file mode 100644 index 00000000..440553e1 --- /dev/null +++ b/docs/공통코드_관리_시스템_설계.md @@ -0,0 +1,745 @@ +# 공통코드 관리 시스템 설계 문서 + +## 📋 목차 + +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 │ │