Files
vexplor/docs/DB_STRUCTURE_DIAGRAM.md
DDD1542 192b678bce fix: 화면 복제 기능 개선 및 관련 버그 수정
- 화면 복제 기능을 개선하여 DB 구조 개편 후의 효율적인 화면 관리를 지원합니다.
- 그룹 복제 시 버튼의 `targetScreenId`가 새 화면으로 매핑되지 않는 버그를 수정하였습니다.
- 관련된 서비스 및 쿼리에서 `table_type_columns`를 사용하여 라벨 정보를 조회하도록 변경하였습니다.
- 여러 컨트롤러 및 서비스에서 `column_labels` 대신 `table_type_columns`를 참조하도록 업데이트하였습니다.
2026-01-28 11:24:25 +09:00

17 KiB

Vexplor 구조 다이어그램

생성일: 2026-01-22 | 총 테이블: 164개 | 코드 기반 관계 분석 완료


1. 테이블 JOIN 관계도 (핵심)

1-1. 사용자/권한 시스템 JOIN 관계

CRUD 테이블 순서 설명
C user_infouser_deptauthority_sub_user 사용자 생성 → 부서 배정 → 권한 부여
R user_info + company_mng + authority_sub_user + authority_master JOIN 로그인/조회 시 회사+권한 JOIN
U user_info / user_dept / authority_sub_user 개별 각 테이블 독립 수정
D 각각 독립 삭제 (별도 API) user_dept, authority_sub_user, user_info 각각 삭제
erDiagram
    company_mng {
        varchar company_code PK "회사코드"
        varchar company_name "회사명"
    }
    
    user_info {
        varchar user_id PK "사용자ID"
        varchar company_code "회사코드 (멀티테넌시)"
        varchar user_name "사용자명"
        varchar user_type "SUPER_ADMIN | COMPANY_ADMIN | USER"
    }
    
    dept_info {
        varchar dept_code PK "부서코드"
        varchar company_code "회사코드"
        varchar dept_name "부서명"
    }
    
    user_dept {
        varchar user_id "사용자ID"
        varchar dept_code "부서코드"
        varchar company_code "회사코드"
    }
    
    authority_master {
        int objid PK "권한그룹ID"
        varchar company_code "회사코드"
        varchar auth_group_name "권한그룹명"
    }
    
    authority_sub_user {
        int master_objid "권한그룹ID"
        varchar user_id "사용자ID"
        varchar company_code "회사코드"
    }

    company_mng ||--o{ user_info : "company_code = company_code"
    company_mng ||--o{ dept_info : "company_code = company_code"
    user_info ||--o{ user_dept : "user_id = user_id"
    dept_info ||--o{ user_dept : "dept_code = dept_code"
    authority_master ||--o{ authority_sub_user : "objid = master_objid"
    user_info ||--o{ authority_sub_user : "user_id = user_id"

실제 코드 JOIN 예시:

-- 사용자 권한 조회 (authService.ts:158)
SELECT am.auth_group_name, am.objid
FROM authority_sub_user asu
INNER JOIN authority_master am ON asu.master_objid = am.objid
WHERE asu.user_id = $1

1-2. 메뉴/권한 시스템 JOIN 관계

CRUD 테이블 순서 설명
C menu_inforel_menu_auth 메뉴 생성 → 권한그룹에 메뉴 할당
R authority_masterrel_menu_authmenu_info 사용자 권한으로 접근 가능 메뉴 필터링
U menu_info 단독 / rel_menu_auth 삭제 후 재생성 메뉴 수정 or 권한 재할당
D rel_menu_authmenu_info 권한 매핑 먼저 삭제 → 메뉴 삭제
erDiagram
    menu_info {
        int objid PK "메뉴ID"
        varchar company_code "회사코드"
        varchar menu_name_kor "메뉴명"
        varchar menu_url "메뉴URL"
        int parent_obj_id "상위메뉴ID"
    }
    
    rel_menu_auth {
        int menu_objid "메뉴ID"
        int auth_objid "권한그룹ID"
        varchar company_code "회사코드"
    }
    
    authority_master {
        int objid PK "권한그룹ID"
        varchar company_code "회사코드"
    }

    menu_info ||--o{ rel_menu_auth : "objid = menu_objid"
    authority_master ||--o{ rel_menu_auth : "objid = auth_objid"

실제 코드 JOIN 예시:

-- 사용자 메뉴 조회 (adminService.ts)
SELECT mi.*
FROM menu_info mi
JOIN rel_menu_auth rma ON mi.objid = rma.menu_objid
WHERE rma.auth_objid IN (사용자권한목록)
AND mi.company_code = $companyCode

1-3. 화면 시스템 JOIN 관계

CRUD 테이블 순서 설명
C screen_definitionsscreen_layoutsscreen_menu_assignments 화면 정의 → 레이아웃 → 메뉴 연결
R menu_infoscreen_menu_assignmentsscreen_definitions + screen_layouts JOIN 메뉴에서 화면+레이아웃 JOIN
U screen_definitions / screen_layouts 개별 (같은 screen_id) 정의와 레이아웃 각각 수정
D screen_layoutsscreen_menu_assignmentsscreen_definitions 레이아웃 → 메뉴연결 → 정의 순서

그룹: screen_groupsscreen_group_screens는 별도 API로 관리 (복사/그룹화 용도)

erDiagram
    screen_definitions {
        uuid screen_id PK "화면ID"
        varchar company_code "회사코드"
        varchar screen_name "화면명"
        varchar table_name "연결테이블"
    }
    
    screen_layouts {
        uuid screen_id PK "화면ID"
        jsonb layout_metadata "레이아웃JSON"
    }
    
    screen_menu_assignments {
        uuid screen_id "화면ID"
        int menu_objid "메뉴ID"
        varchar company_code "회사코드"
    }
    
    screen_groups {
        int id PK "그룹ID"
        varchar company_code "회사코드"
        varchar group_name "그룹명"
    }
    
    screen_group_screens {
        int group_id "그룹ID"
        uuid screen_id "화면ID"
        varchar company_code "회사코드"
    }

    screen_definitions ||--|| screen_layouts : "screen_id = screen_id"
    screen_definitions ||--o{ screen_menu_assignments : "screen_id = screen_id"
    menu_info ||--o{ screen_menu_assignments : "objid = menu_objid"
    screen_groups ||--o{ screen_group_screens : "id = group_id"
    screen_definitions ||--o{ screen_group_screens : "screen_id = screen_id"

실제 코드 JOIN 예시:

-- 화면 정의 + 레이아웃 조회 (screenGroupController.ts:1272)
SELECT sd.*, sl.layout_metadata
FROM screen_definitions sd
JOIN screen_layouts sl ON sd.screen_id = sl.screen_id
WHERE sd.screen_id = $1

1-4. 테이블 타입/메타데이터 JOIN 관계

CRUD 테이블 순서 설명
C 각 테이블 독립 생성 DDL 실행 시 자동 생성, 또는 개별 등록
R table_type_columns + table_labels + table_relationships LEFT JOIN 화면 로딩 시 메타데이터 조합
U 각 테이블 개별 (table_name + column_name + company_code 기준) 컬럼 정의/라벨/관계 각각 수정
D 각 테이블 독립 삭제 테이블 삭제 시 관련 메타데이터 개별 삭제

코드값 조회: table_column_category_valuescode_categorycode_info (드롭다운 옵션)

erDiagram
    table_type_columns {
        varchar table_name PK "테이블명"
        varchar column_name PK "컬럼명"
        varchar company_code PK "회사코드"
        varchar display_name "표시명"
        varchar data_type "데이터타입"
        varchar reference_table "참조테이블"
        varchar reference_column "참조컬럼"
    }
    
    table_labels {
        varchar table_name PK "테이블명"
        varchar company_code PK "회사코드"
        varchar display_name "테이블표시명"
    }
    
    table_column_category_values {
        varchar table_name "테이블명"
        varchar column_name "컬럼명"
        varchar category_code "카테고리코드"
        varchar company_code "회사코드"
    }
    
    table_relationships {
        varchar table_name "테이블명"
        varchar source_column "소스컬럼"
        varchar target_table "타겟테이블"
        varchar target_column "타겟컬럼"
        varchar company_code "회사코드"
    }
    
    code_category {
        varchar category_code PK "카테고리코드"
        varchar company_code PK "회사코드"
        varchar category_name "카테고리명"
    }
    
    code_info {
        varchar category_code "카테고리코드"
        varchar code_value PK "코드값"
        varchar company_code PK "회사코드"
        varchar code_name "코드명"
    }

    table_type_columns ||--o{ table_labels : "table_name = table_name"
    table_type_columns ||--o{ table_column_category_values : "table_name, column_name"
    table_type_columns ||--o{ table_relationships : "table_name = table_name"
    code_category ||--o{ code_info : "category_code = category_code"
    table_column_category_values }o--|| code_category : "category_code = category_code"

실제 코드 JOIN 예시:

-- 테이블 컬럼 정보 조회 (tableManagementService.ts:210)
SELECT ttc.*, cl.display_name as column_label
FROM table_type_columns ttc
LEFT JOIN column_labels cl 
  ON ttc.table_name = cl.table_name 
  AND ttc.column_name = cl.column_name
WHERE ttc.table_name = $1
AND ttc.company_code = $2

1-5. 플로우 시스템 JOIN 관계

CRUD 테이블 순서 설명
C flow_definitionflow_stepflow_step_connectionflow_data_mapping 플로우 → 스텝 → 연결선 → 매핑
R flow_definition + flow_step + flow_step_connection JOIN 플로우 화면 렌더링
U 각 테이블 개별 (definition_id/step_id 기준) 정의/스텝/연결 각각 수정
D 각 테이블 독립 삭제 (DB CASCADE 의존) step/connection/definition 각각 삭제 API

데이터 이동: flow_data_mapping(컬럼 변환) → 소스→타겟 INSERT → flow_audit_log(자동 기록)

erDiagram
    flow_definition {
        int id PK "플로우ID"
        varchar company_code "회사코드"
        varchar name "플로우명"
    }
    
    flow_step {
        int id PK "스텝ID"
        int definition_id "플로우ID"
        varchar company_code "회사코드"
        varchar step_name "스텝명"
        varchar table_name "연결테이블"
        int step_order "순서"
    }
    
    flow_step_connection {
        int id PK "연결ID"
        int from_step_id "출발스텝ID"
        int to_step_id "도착스텝ID"
        int definition_id "플로우ID"
    }
    
    flow_data_mapping {
        int from_step_id "출발스텝ID"
        int to_step_id "도착스텝ID"
        varchar source_column "소스컬럼"
        varchar target_column "타겟컬럼"
    }
    
    flow_audit_log {
        int id PK "로그ID"
        int definition_id "플로우ID"
        int from_step_id "출발스텝ID"
        int to_step_id "도착스텝ID"
        int data_id "데이터ID"
        timestamp moved_at "이동시간"
    }

    flow_definition ||--o{ flow_step : "id = definition_id"
    flow_step ||--o{ flow_step_connection : "id = from_step_id"
    flow_step ||--o{ flow_step_connection : "id = to_step_id"
    flow_step ||--o{ flow_data_mapping : "id = from_step_id"
    flow_step ||--o{ flow_audit_log : "id = from_step_id"

실제 코드 JOIN 예시:

-- 플로우 감사로그 조회 (flowDataMoveService.ts:461)
SELECT fal.*, 
       fs_from.step_name as from_step_name,
       fs_to.step_name as to_step_name
FROM flow_audit_log fal
LEFT JOIN flow_step fs_from ON fal.from_step_id = fs_from.id
LEFT JOIN flow_step fs_to ON fal.to_step_id = fs_to.id
WHERE fal.definition_id = $1

1-6. 배치/수집 시스템 JOIN 관계

CRUD 테이블 순서 설명
C external_db_connectionsbatch_configsbatch_mappings 외부DB 연결 → 배치 설정 → 매핑 규칙
R batch_configs + external_db_connections + batch_mappings JOIN 배치 실행 시 전체 설정 조회
U batch_mappings 삭제 후 재생성 / batch_configs 개별 수정 매핑은 전체 교체 방식
D batch_configs 삭제 시 batch_mappings CASCADE 삭제 설정만 삭제하면 매핑 자동 삭제

실행 시: 크론 → 외부DB 조회 → 내부 테이블 동기화 → batch_execution_logs(결과 기록)

erDiagram
    external_db_connections {
        int id PK "연결ID"
        varchar company_code "회사코드"
        varchar connection_name "연결명"
        varchar db_type "postgresql|mysql|mssql"
        varchar host "호스트"
        int port "포트"
    }
    
    batch_configs {
        int id PK "배치ID"
        varchar company_code "회사코드"
        varchar batch_name "배치명"
        varchar cron_expression "크론식"
        int connection_id "연결ID"
        varchar is_active "Y|N"
    }
    
    batch_mappings {
        int id PK "매핑ID"
        int batch_config_id "배치ID"
        varchar source_table "소스테이블"
        varchar source_column "소스컬럼"
        varchar target_table "타겟테이블"
        varchar target_column "타겟컬럼"
    }
    
    batch_execution_logs {
        int id PK "로그ID"
        int batch_config_id "배치ID"
        timestamp started_at "시작시간"
        timestamp finished_at "종료시간"
        varchar status "SUCCESS|FAILED"
    }

    external_db_connections ||--o{ batch_configs : "id = connection_id"
    batch_configs ||--o{ batch_mappings : "id = batch_config_id"
    batch_configs ||--o{ batch_execution_logs : "id = batch_config_id"

실제 코드 JOIN 예시:

-- 배치 설정 + 매핑 조회 (batchService.ts:143)
SELECT bc.*, bm.*
FROM batch_configs bc
LEFT JOIN batch_mappings bm ON bc.id = bm.batch_config_id
WHERE bc.id = $1
AND bc.company_code = $2
ORDER BY bm.mapping_order

2. 로직 플로우 요약

위 JOIN 관계가 언제 사용되는지 간략 설명

2-1. 로그인 → 화면 접근 순서

단계 테이블 JOIN 관계 설명
1 user_info - user_id, password 확인
2 user_info - company_code 조회 → 멀티테넌시 분기
3 company_mng user_info.company_code = company_mng.company_code 회사명 조회
4 authority_sub_userauthority_master asu.master_objid = am.objid 사용자 권한 조회
5 menu_inforel_menu_auth mi.objid = rma.menu_objid 권한별 메뉴 필터
6 screen_menu_assignmentsscreen_definitions sma.screen_id = sd.screen_id 메뉴-화면 연결
7 screen_definitionsscreen_layouts sd.screen_id = sl.screen_id 화면+레이아웃
8 table_type_columns WHERE table_name = $1 컬럼 메타데이터

2-2. 데이터 조회 순서

단계 테이블 JOIN 관계 설명
1 table_type_columns - 컬럼 정의 조회
2 table_labels ttc.table_name = tl.table_name 테이블 표시명
3 table_column_category_values ttc.table_name, column_name 카테고리 값
4 table_relationships ttc.table_name = tr.table_name 참조 관계
5 code_categorycode_info cc.category_code = ci.category_code 코드값 조회
6 비즈니스 테이블 LEFT JOIN (table_relationships 기반) 실제 데이터

2-3. 플로우 데이터 이동 순서

단계 테이블 JOIN 관계 설명
1 flow_definition - 플로우 정의
2 flow_step fs.definition_id = fd.id 스텝 목록
3 flow_step_connection fsc.from_step_id = fs.id 연결 관계
4 flow_data_mapping fdm.from_step_id, to_step_id 컬럼 매핑
5 소스 테이블 - 데이터 조회
6 타겟 테이블 - 데이터 INSERT
7 flow_audit_log - 이동 기록

2-4. 배치 실행 순서

단계 테이블 JOIN 관계 설명
1 batch_configs - 활성 배치 조회
2 external_db_connections bc.connection_id = edc.id 외부 DB 정보
3 batch_mappings bm.batch_config_id = bc.id 매핑 규칙
4 외부 DB - 데이터 조회
5 내부 테이블 - 데이터 동기화
6 batch_execution_logs bel.batch_config_id = bc.id 실행 로그

3. 멀티테넌시 (company_code) 적용 요약

테이블 company_code 필터 비고
user_info O 사용자별 회사 구분
menu_info O 회사별 메뉴
screen_definitions O 회사별 화면
table_type_columns O 회사별 컬럼 정의
flow_definition O 회사별 플로우
batch_configs O 회사별 배치
모든 비즈니스 테이블 O 자동 필터 적용
company_mng X (PK) 회사 마스터

company_code = '*': 최고관리자, 모든 회사 데이터 접근 가능


4. 비효율성 분석

상세 내용: DB_INEFFICIENCY_ANALYSIS.md

심각도 항목 권장 조치
🔴 screen_definitions.layout_metadata 미사용 컬럼 삭제
🔴 user_dept 비정규화 정규화 리팩토링
🟡 히스토리 테이블 39개 통합 감사 테이블
🟡 cascading 미사용 3개 테이블 삭제
🟢 dept_info.company_name 선택적 정규화