ERP-node/docs/다국어_관리_시스템_개선_계획서.md

30 KiB

다국어 관리 시스템 개선 계획서

1. 개요

1.1 현재 시스템 분석

현재 ERP 시스템의 다국어 관리 시스템은 기본적인 기능은 갖추고 있으나 다음과 같은 한계점이 있습니다.

항목 현재 상태 문제점
회사별 다국어 company_code 컬럼 존재하나 *(공통)만 사용 회사별 커스텀 번역 불가
언어 키 입력 수동 입력 (button.add 등) 명명 규칙 불일치, 오타, 중복 위험
카테고리 분류 없음 (menu_name 텍스트만 존재) 체계적 분류/검색 불가
권한 관리 없음 모든 사용자가 모든 키 수정 가능
조회 우선순위 없음 회사별 오버라이드 불가

1.2 개선 목표

  1. 회사별 다국어 오버라이드 시스템: 공통 키를 기본으로 사용하되, 회사별 커스텀 번역 지원
  2. 권한 기반 접근 제어: 공통 키는 최고 관리자만, 회사 키는 해당 회사만 수정
  3. 카테고리 기반 분류: 2단계 계층 구조로 체계적 분류
  4. 자동 키 생성: 카테고리 선택 + 의미 입력으로 규칙화된 키 자동 생성
  5. 실시간 중복 체크: 키 생성 시 중복 여부 즉시 확인

2. 데이터베이스 스키마 설계

2.1 신규 테이블: multi_lang_category (카테고리 마스터)

CREATE TABLE multi_lang_category (
  category_id SERIAL PRIMARY KEY,
  category_code VARCHAR(50) NOT NULL,           -- BUTTON, FORM, MESSAGE 등
  category_name VARCHAR(100) NOT NULL,          -- 버튼, 폼, 메시지 등
  parent_id INT4 REFERENCES multi_lang_category(category_id),
  level INT4 DEFAULT 1,                         -- 1=대분류, 2=세부분류
  key_prefix VARCHAR(50) NOT NULL,              -- 키 생성용 prefix
  description TEXT,
  sort_order INT4 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),
  UNIQUE(category_code, COALESCE(parent_id, 0))
);

-- 인덱스
CREATE INDEX idx_lang_category_parent ON multi_lang_category(parent_id);
CREATE INDEX idx_lang_category_level ON multi_lang_category(level);

2.2 기존 테이블 수정: multi_lang_key_master

-- 카테고리 연결 컬럼 추가
ALTER TABLE multi_lang_key_master 
ADD COLUMN category_id INT4 REFERENCES multi_lang_category(category_id);

-- 키 의미 컬럼 추가 (자동 생성 시 사용자 입력값)
ALTER TABLE multi_lang_key_master 
ADD COLUMN key_meaning VARCHAR(100);

-- 원본 키 참조 (오버라이드 시 원본 추적)
ALTER TABLE multi_lang_key_master 
ADD COLUMN base_key_id INT4 REFERENCES multi_lang_key_master(key_id);

-- menu_name을 usage_note로 변경 (사용 위치 메모)
ALTER TABLE multi_lang_key_master 
RENAME COLUMN menu_name TO usage_note;

-- 인덱스 추가
CREATE INDEX idx_lang_key_category ON multi_lang_key_master(category_id);
CREATE INDEX idx_lang_key_company_category ON multi_lang_key_master(company_code, category_id);
CREATE INDEX idx_lang_key_base ON multi_lang_key_master(base_key_id);

2.3 테이블 관계도

multi_lang_category (1) ◀────────┐
  ├── category_id (PK)            │
  ├── category_code               │
  ├── parent_id (자기참조)         │
  └── key_prefix                  │
                                  │
multi_lang_key_master (N) ────────┘
  ├── key_id (PK)
  ├── company_code ('*' = 공통)
  ├── category_id (FK)
  ├── lang_key (자동 생성)
  ├── key_meaning (사용자 입력)
  ├── base_key_id (오버라이드 시 원본)
  └── usage_note (사용 위치 메모)
              │
              ▼
multi_lang_text (N)
  ├── text_id (PK)
  ├── key_id (FK)
  ├── lang_code (FK → language_master)
  └── lang_text

3. 카테고리 체계

3.1 대분류 (Level 1)

category_code category_name key_prefix 설명
COMMON 공통 common 범용 텍스트
BUTTON 버튼 button 버튼 텍스트
FORM form 폼 라벨, 플레이스홀더
TABLE 테이블 table 테이블 헤더, 빈 상태
MESSAGE 메시지 message 알림, 경고, 성공 메시지
MENU 메뉴 menu 메뉴명, 네비게이션
MODAL 모달 modal 모달/다이얼로그
VALIDATION 검증 validation 유효성 검사 메시지
STATUS 상태 status 상태 표시 텍스트
TOOLTIP 툴팁 tooltip 툴팁, 도움말

3.2 세부분류 (Level 2)

BUTTON 하위

category_code category_name key_prefix
ACTION 액션 action
NAVIGATION 네비게이션 nav
TOGGLE 토글 toggle

FORM 하위

category_code category_name key_prefix
LABEL 라벨 label
PLACEHOLDER 플레이스홀더 placeholder
HELPER 도움말 helper

MESSAGE 하위

category_code category_name key_prefix
SUCCESS 성공 success
ERROR 에러 error
WARNING 경고 warning
INFO 안내 info
CONFIRM 확인 confirm

TABLE 하위

category_code category_name key_prefix
HEADER 헤더 header
EMPTY 빈 상태 empty
PAGINATION 페이지네이션 pagination

MENU 하위

category_code category_name key_prefix
ADMIN 관리자 admin
USER 사용자 user

MODAL 하위

category_code category_name key_prefix
TITLE 제목 title
DESCRIPTION 설명 description

3.3 키 자동 생성 규칙

형식: {대분류_prefix}.{세부분류_prefix}.{key_meaning}

예시:

대분류 세부분류 의미 입력 생성 키
BUTTON ACTION save button.action.save
BUTTON ACTION delete_selected button.action.delete_selected
FORM LABEL user_name form.label.user_name
FORM PLACEHOLDER search form.placeholder.search
MESSAGE SUCCESS save_complete message.success.save_complete
MESSAGE ERROR network_fail message.error.network_fail
TABLE HEADER created_date table.header.created_date
MENU ADMIN user_management menu.admin.user_management

4. 회사별 다국어 시스템

4.1 조회 우선순위

다국어 텍스트 조회 시 다음 우선순위를 적용합니다:

  1. 회사 전용 키 (company_code = 'COMPANY_A')
  2. 공통 키 (company_code = '*')
-- 조회 쿼리 예시
WITH ranked_keys AS (
  SELECT 
    km.lang_key,
    mt.lang_text,
    km.company_code,
    ROW_NUMBER() OVER (
      PARTITION BY km.lang_key 
      ORDER BY CASE WHEN km.company_code = $1 THEN 1 ELSE 2 END
    ) as priority
  FROM multi_lang_key_master km
  JOIN multi_lang_text mt ON km.key_id = mt.key_id
  WHERE km.lang_key = ANY($2)
    AND mt.lang_code = $3
    AND km.is_active = 'Y'
    AND km.company_code IN ($1, '*')
)
SELECT lang_key, lang_text 
FROM ranked_keys 
WHERE priority = 1;

4.2 오버라이드 프로세스

  1. 회사 관리자가 공통 키에서 "이 회사 전용으로 복사" 클릭
  2. 시스템이 base_key_id에 원본 키를 참조하는 새 키 생성
  3. 기존 번역 텍스트 복사
  4. 회사 관리자가 번역 수정
  5. 이후 해당 회사 사용자는 회사 전용 번역 사용

4.3 권한 매트릭스

작업 최고 관리자 (*) 회사 관리자 일반 사용자
공통 키 조회 O O O
공통 키 생성 O X X
공통 키 수정 O X X
공통 키 삭제 O X X
회사 키 조회 O 자사만 자사만
회사 키 생성 (오버라이드) O O X
회사 키 수정 O 자사만 X
회사 키 삭제 O 자사만 X
카테고리 관리 O X X

5. API 설계

5.1 카테고리 API

엔드포인트 메서드 설명 권한
/multilang/categories GET 카테고리 목록 조회 인증 필요
/multilang/categories/tree GET 계층 구조로 조회 인증 필요
/multilang/categories POST 카테고리 생성 최고 관리자
/multilang/categories/:id PUT 카테고리 수정 최고 관리자
/multilang/categories/:id DELETE 카테고리 삭제 최고 관리자

5.2 다국어 키 API (개선)

엔드포인트 메서드 설명 권한
/multilang/keys GET 키 목록 조회 (카테고리/회사 필터) 인증 필요
/multilang/keys POST 키 생성 공통: 최고관리자, 회사: 회사관리자
/multilang/keys/:keyId PUT 키 수정 공통: 최고관리자, 회사: 해당회사
/multilang/keys/:keyId DELETE 키 삭제 공통: 최고관리자, 회사: 해당회사
/multilang/keys/:keyId/override POST 공통 키를 회사 전용으로 복사 회사 관리자
/multilang/keys/check GET 키 중복 체크 인증 필요
/multilang/keys/generate-preview POST 키 자동 생성 미리보기 인증 필요

5.3 API 요청/응답 예시

키 생성 요청

POST /multilang/keys
{
  "categoryId": 11,           // 세부분류 ID (BUTTON > ACTION)
  "keyMeaning": "save_changes",
  "description": "변경사항 저장 버튼",
  "usageNote": "사용자 관리, 설정 화면",
  "texts": [
    { "langCode": "KR", "langText": "저장하기" },
    { "langCode": "US", "langText": "Save Changes" },
    { "langCode": "JP", "langText": "保存する" }
  ]
}

키 생성 응답

{
  "success": true,
  "message": "다국어 키가 생성되었습니다.",
  "data": {
    "keyId": 175,
    "langKey": "button.action.save_changes",
    "companyCode": "*",
    "categoryId": 11
  }
}

오버라이드 요청

POST /multilang/keys/123/override
{
  "texts": [
    { "langCode": "KR", "langText": "등록하기" },
    { "langCode": "US", "langText": "Register" }
  ]
}

6. 프론트엔드 UI 설계

6.1 다국어 관리 페이지 리뉴얼

┌─────────────────────────────────────────────────────────────────────────┐
│ 다국어 관리                                                              │
│ 다국어 키와 번역 텍스트를 관리합니다                                       │
├─────────────────────────────────────────────────────────────────────────┤
│ [언어 관리] [다국어 키 관리] [카테고리 관리]                               │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│ ┌────────────────────┐  ┌───────────────────────────────────────────────┤
│ │ 카테고리 필터       │  │                                               │
│ │                    │  │ 검색: [________________] 회사: [전체 ▼]        │
│ │ ▼ 버튼 (45)        │  │                           [초기화] [+ 키 등록] │
│ │   ├ 액션 (30)      │  │───────────────────────────────────────────────│
│ │   ├ 네비게이션 (10)│  │ ☐ │ 키           │ 카테고리   │ 회사 │ 상태   │
│ │   └ 토글 (5)       │  │───────────────────────────────────────────────│
│ │ ▼ 폼 (60)          │  │ ☐ │ button.action.save      │ 버튼>액션  │ 공통 │ 활성 │
│ │   ├ 라벨 (35)      │  │ ☐ │ button.action.save      │ 버튼>액션  │ A사  │ 활성 │
│ │   ├ 플레이스홀더(15)│  │ ☐ │ button.action.delete    │ 버튼>액션  │ 공통 │ 활성 │
│ │   └ 도움말 (10)    │  │ ☐ │ form.label.user_name    │ 폼>라벨    │ 공통 │ 활성 │
│ │ ▶ 메시지 (40)      │  │───────────────────────────────────────────────│
│ │ ▶ 테이블 (20)      │  │ 페이지: [1] [2] [3] ... [10]                  │
│ │ ▶ 메뉴 (9)         │  │                                               │
│ └────────────────────┘  └───────────────────────────────────────────────┤
└─────────────────────────────────────────────────────────────────────────┘

6.2 키 등록 모달

┌─────────────────────────────────────────────────────────────────┐
│ 다국어 키 등록                                                   │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│ ① 카테고리 선택                                                  │
│ ┌───────────────────────────────────────────────────────────────┤
│ │ 대분류 *                      │ 세부 분류 *                    │
│ │ ┌─────────────────────────┐   │ ┌─────────────────────────┐   │
│ │ │ 공통                    │   │ │ (대분류 먼저 선택)       │   │
│ │ │ ● 버튼                  │   │ │ ● 액션                  │   │
│ │ │ 폼                      │   │ │ 네비게이션               │   │
│ │ │ 테이블                  │   │ │ 토글                    │   │
│ │ │ 메시지                  │   │ │                         │   │
│ │ └─────────────────────────┘   │ └─────────────────────────┘   │
│ └───────────────────────────────────────────────────────────────┤
│                                                                 │
│ ② 키 정보 입력                                                   │
│ ┌───────────────────────────────────────────────────────────────┤
│ │ 키 의미 (영문) *                                               │
│ │ [ save_changes                                         ]      │
│ │ 영문 소문자, 밑줄(_) 사용. 예: save, add_new, delete_all       │
│ │                                                               │
│ │ ─────────────────────────────────────────────────────────     │
│ │ 자동 생성 키:                                                  │
│ │ ┌─────────────────────────────────────────────────────────┐   │
│ │ │ button.action.save_changes                              │   │
│ │ └─────────────────────────────────────────────────────────┘   │
│ │ ✓ 사용 가능한 키입니다                                         │
│ └───────────────────────────────────────────────────────────────┤
│                                                                 │
│ ③ 설명 및 번역                                                   │
│ ┌───────────────────────────────────────────────────────────────┤
│ │ 설명 (선택)                                                    │
│ │ [ 변경사항을 저장하는 버튼                              ]      │
│ │                                                               │
│ │ 사용 위치 메모 (선택)                                          │
│ │ [ 사용자 관리, 설정 화면                                ]      │
│ │                                                               │
│ │ ─────────────────────────────────────────────────────────     │
│ │ 번역 텍스트                                                    │
│ │                                                               │
│ │ 한국어 (KR) *           [ 저장하기                      ]      │
│ │ English (US)            [ Save Changes                  ]      │
│ │ 日本語 (JP)             [ 保存する                      ]      │
│ └───────────────────────────────────────────────────────────────┤
│                                                                 │
├─────────────────────────────────────────────────────────────────┤
│                                         [취소]  [등록]           │
└─────────────────────────────────────────────────────────────────┘

6.3 공통 키 편집 모달 (회사 관리자용)

┌─────────────────────────────────────────────────────────────────┐
│ 다국어 키 상세                                                   │
│ button.action.save (공통)                                       │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│ 카테고리: 버튼 > 액션                                            │
│ 설명: 저장 버튼                                                  │
│                                                                 │
│ ─────────────────────────────────────────────────────────────   │
│ 번역 텍스트 (읽기 전용)                                          │
│                                                                 │
│ 한국어 (KR)          저장                                        │
│ English (US)         Save                                        │
│ 日本語 (JP)          保存                                        │
│                                                                 │
├─────────────────────────────────────────────────────────────────┤
│ 공통 키는 수정할 수 없습니다.                                     │
│ 이 회사만의 번역이 필요하시면 아래 버튼을 클릭하세요.              │
│                                                                 │
│                    [이 회사 전용으로 복사]                        │
├─────────────────────────────────────────────────────────────────┤
│                                               [닫기]             │
└─────────────────────────────────────────────────────────────────┘

6.4 회사 전용 키 생성 모달 (오버라이드)

┌─────────────────────────────────────────────────────────────────┐
│ 회사 전용 키 생성                                                │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│ 원본 키: button.action.save (공통)                               │
│                                                                 │
│ 원본 번역:                                                       │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 한국어: 저장                                                 │ │
│ │ English: Save                                                │ │
│ │ 日本語: 保存                                                 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│                                                                 │
│ ─────────────────────────────────────────────────────────────   │
│                                                                 │
│ 이 회사 전용 번역 텍스트:                                        │
│                                                                 │
│ 한국어 (KR) *           [ 등록하기                        ]      │
│ English (US)            [ Register                        ]      │
│ 日本語 (JP)             [ 登録                            ]      │
│                                                                 │
├─────────────────────────────────────────────────────────────────┤
│ 회사 전용 키를 생성하면 공통 키 대신 사용됩니다.                   │
│ 원본 키가 변경되어도 회사 전용 키는 영향받지 않습니다.             │
├─────────────────────────────────────────────────────────────────┤
│                                         [취소]  [생성]           │
└─────────────────────────────────────────────────────────────────┘

7. 구현 계획

7.1 Phase 1: 데이터베이스 마이그레이션

예상 소요 시간: 2시간

  1. 카테고리 테이블 생성
  2. 기본 카테고리 데이터 삽입 (대분류 10개, 세부분류 약 20개)
  3. multi_lang_key_master 스키마 변경
  4. 기존 174개 키 카테고리 자동 분류 (패턴 매칭)

마이그레이션 파일: db/migrations/075_multilang_category_system.sql

7.2 Phase 2: 백엔드 API 개발

예상 소요 시간: 4시간

  1. 카테고리 CRUD API
  2. 키 조회 로직 수정 (우선순위 적용)
  3. 권한 검사 미들웨어
  4. 오버라이드 API
  5. 키 중복 체크 API
  6. 키 자동 생성 미리보기 API

관련 파일:

  • backend-node/src/controllers/multilangController.ts
  • backend-node/src/services/multilangService.ts
  • backend-node/src/routes/multilangRoutes.ts

7.3 Phase 3: 프론트엔드 UI 개발

예상 소요 시간: 6시간

  1. 카테고리 트리 컴포넌트
  2. 키 등록 모달 리뉴얼 (단계별 입력)
  3. 키 편집 모달 (권한별 UI 분기)
  4. 오버라이드 모달
  5. 카테고리 관리 탭 추가

관련 파일:

  • frontend/app/(main)/admin/systemMng/i18nList/page.tsx
  • frontend/components/multilang/LangKeyModal.tsx (리뉴얼)
  • frontend/components/multilang/CategoryTree.tsx (신규)
  • frontend/components/multilang/OverrideModal.tsx (신규)

7.4 Phase 4: 테스트 및 마이그레이션

예상 소요 시간: 2시간

  1. API 테스트
  2. UI 테스트
  3. 기존 데이터 마이그레이션 검증
  4. 권한 테스트 (최고 관리자, 회사 관리자)

8. 상세 구현 일정

단계 작업 예상 시간 의존성
1.1 마이그레이션 SQL 작성 30분 -
1.2 카테고리 기본 데이터 삽입 30분 1.1
1.3 기존 키 카테고리 자동 분류 30분 1.2
1.4 스키마 변경 검증 30분 1.3
2.1 카테고리 API 개발 1시간 1.4
2.2 키 조회 로직 수정 (우선순위) 1시간 2.1
2.3 권한 검사 로직 추가 30분 2.2
2.4 오버라이드 API 개발 1시간 2.3
2.5 키 생성 API 개선 (자동 생성) 30분 2.4
3.1 카테고리 트리 컴포넌트 1시간 2.5
3.2 키 등록 모달 리뉴얼 2시간 3.1
3.3 키 편집/상세 모달 1시간 3.2
3.4 오버라이드 모달 1시간 3.3
3.5 카테고리 관리 탭 1시간 3.4
4.1 통합 테스트 1시간 3.5
4.2 버그 수정 및 마무리 1시간 4.1

총 예상 시간: 약 14시간


9. 기대 효과

9.1 개선 전후 비교

항목 현재 개선 후
키 명명 규칙 불규칙 (수동 입력) 규칙화 (자동 생성)
카테고리 분류 없음 2단계 계층 구조
회사별 다국어 미활용 오버라이드 지원
조회 우선순위 없음 회사 전용 > 공통
권한 관리 없음 역할별 접근 제어
중복 체크 저장 시에만 실시간 검증
검색/필터 키 이름만 카테고리 + 회사 + 키

9.2 사용자 경험 개선

  1. 일관된 키 명명: 자동 생성으로 규칙 준수
  2. 빠른 검색: 카테고리 기반 필터링
  3. 회사별 커스터마이징: 브랜드에 맞는 번역 사용
  4. 안전한 수정: 권한 기반 보호

9.3 유지보수 개선

  1. 체계적 분류: 어떤 텍스트가 어디에 사용되는지 명확
  2. 변경 영향 파악: 오버라이드 추적으로 영향 범위 확인
  3. 권한 분리: 공통 키 보호, 회사별 자율성 보장

10. 참고 자료

10.1 관련 파일

파일 설명
frontend/hooks/useMultiLang.ts 다국어 훅
frontend/lib/utils/multilang.ts 다국어 유틸리티
frontend/app/(main)/admin/systemMng/i18nList/page.tsx 다국어 관리 페이지
backend-node/src/controllers/multilangController.ts API 컨트롤러
backend-node/src/services/multilangService.ts 비즈니스 로직
docs/다국어_시스템_가이드.md 기존 시스템 가이드

10.2 데이터베이스 테이블

테이블 설명
language_master 언어 마스터 (KR, US, JP)
multi_lang_key_master 다국어 키 마스터
multi_lang_text 다국어 번역 텍스트
multi_lang_category 다국어 카테고리 (신규)

11. 변경 이력

버전 날짜 작성자 변경 내용
1.0 2026-01-13 AI 최초 작성