- 화면 복제 기능을 개선하여 DB 구조 개편 후의 효율적인 화면 관리를 지원합니다. - 그룹 복제 시 버튼의 `targetScreenId`가 새 화면으로 매핑되지 않는 버그를 수정하였습니다. - 관련된 서비스 및 쿼리에서 `table_type_columns`를 사용하여 라벨 정보를 조회하도록 변경하였습니다. - 여러 컨트롤러 및 서비스에서 `column_labels` 대신 `table_type_columns`를 참조하도록 업데이트하였습니다.
549 lines
17 KiB
HTML
549 lines
17 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="ko">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>PLM 데이터베이스 구조 다이어그램</title>
|
||
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
|
||
<style>
|
||
body {
|
||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||
max-width: 1400px;
|
||
margin: 0 auto;
|
||
padding: 20px;
|
||
background: #f5f5f5;
|
||
}
|
||
h1 { color: #333; border-bottom: 2px solid #4a90d9; padding-bottom: 10px; }
|
||
h2 { color: #4a90d9; margin-top: 40px; }
|
||
h3 { color: #666; }
|
||
.diagram-container {
|
||
background: white;
|
||
padding: 20px;
|
||
border-radius: 8px;
|
||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||
margin: 20px 0;
|
||
overflow-x: auto;
|
||
}
|
||
.mermaid { text-align: center; }
|
||
table { border-collapse: collapse; width: 100%; margin: 10px 0; }
|
||
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
|
||
th { background: #4a90d9; color: white; }
|
||
tr:nth-child(even) { background: #f9f9f9; }
|
||
.info { background: #e7f3ff; padding: 10px; border-radius: 4px; margin: 10px 0; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<h1>PLM 데이터베이스 구조 다이어그램</h1>
|
||
<div class="info">
|
||
<strong>생성일:</strong> 2026-01-22 | <strong>총 테이블:</strong> 164개 | <strong>코드 기반 관계 분석 완료</strong>
|
||
</div>
|
||
|
||
<h2>사용자 화면 플로우 (User Flow)</h2>
|
||
|
||
<h3>1. 로그인 → 메뉴 → 화면 접근 플로우</h3>
|
||
<div class="diagram-container">
|
||
<div class="mermaid">
|
||
flowchart LR
|
||
subgraph LOGIN["🔐 로그인"]
|
||
A[사용자 로그인] --> B{user_info 인증}
|
||
B -->|성공| C[company_code 확인]
|
||
B -->|실패| D[login_access_log 기록]
|
||
end
|
||
|
||
subgraph COMPANY["🏢 회사 분기"]
|
||
C --> E{company_code 타입}
|
||
E -->|"*"| F[최고관리자 SUPER_ADMIN]
|
||
E -->|회사코드| G[회사관리자/일반사용자]
|
||
F --> H[company_mng 회사정보 조회]
|
||
G --> H
|
||
H --> I[JWT 토큰 발급 + companyCode 포함]
|
||
end
|
||
|
||
subgraph AUTH["👤 권한 확인"]
|
||
I --> J[authority_sub_user 조회]
|
||
J --> K[authority_master 권한 확인]
|
||
end
|
||
|
||
subgraph MENU["📋 메뉴 로딩"]
|
||
K --> L[rel_menu_auth 메뉴권한 조회]
|
||
L --> M[menu_info 메뉴 목록]
|
||
M -->|company_code 필터| N[해당 회사 메뉴만 표시]
|
||
end
|
||
|
||
subgraph SCREEN["📱 화면 렌더링"]
|
||
N -->|메뉴 클릭| O[screen_menu_assignments 조회]
|
||
O --> P[screen_definitions 화면정의]
|
||
P --> Q[screen_layouts 레이아웃]
|
||
Q --> R[table_type_columns 컬럼정보]
|
||
R -->|company_code 필터| S[해당 회사 데이터만 조회]
|
||
end
|
||
</div>
|
||
</div>
|
||
|
||
<h3>2. Low-code 화면 데이터 조회 플로우</h3>
|
||
<div class="diagram-container">
|
||
<div class="mermaid">
|
||
flowchart TB
|
||
subgraph USER["👤 사용자 액션"]
|
||
A[화면 접속] --> B[데이터 조회 요청]
|
||
end
|
||
|
||
subgraph SCREEN_DEF["📱 화면 정의 조회"]
|
||
B --> C[screen_definitions]
|
||
C --> D[screen_layouts]
|
||
D --> E{위젯 타입 확인}
|
||
end
|
||
|
||
subgraph TABLE_INFO["🏷️ 테이블 정보"]
|
||
E -->|테이블 위젯| F[table_type_columns]
|
||
F --> G[table_labels 라벨]
|
||
F --> H[table_column_category_values 카테고리]
|
||
F --> I[table_relationships 관계]
|
||
end
|
||
|
||
subgraph DATA_QUERY["📊 데이터 조회"]
|
||
G --> J[동적 SQL 생성]
|
||
H --> J
|
||
I --> J
|
||
J --> K[실제 비즈니스 테이블 조회]
|
||
K --> L[데이터 반환]
|
||
end
|
||
|
||
subgraph RENDER["🖥️ 화면 표시"]
|
||
L --> M[그리드/폼에 데이터 바인딩]
|
||
M --> N[사용자에게 표시]
|
||
end
|
||
</div>
|
||
</div>
|
||
|
||
<h3>3. 플로우 시스템 데이터 이동 플로우</h3>
|
||
<div class="diagram-container">
|
||
<div class="mermaid">
|
||
flowchart LR
|
||
subgraph FLOW_DEF["🔄 플로우 정의"]
|
||
A[flow_definition] --> B[flow_step]
|
||
B --> C[flow_step_connection]
|
||
end
|
||
|
||
subgraph USER_ACTION["👤 사용자 액션"]
|
||
D[데이터 선택] --> E[이동 버튼 클릭]
|
||
end
|
||
|
||
subgraph MOVE_PROCESS["📤 데이터 이동"]
|
||
E --> F{flow_step_connection 다음 스텝 확인}
|
||
F --> G[flow_data_mapping 매핑]
|
||
G --> H[소스 테이블에서 데이터 복사]
|
||
H --> I[타겟 테이블에 INSERT]
|
||
end
|
||
|
||
subgraph LOGGING["📝 로깅"]
|
||
I --> J[flow_audit_log 기록]
|
||
J --> K[flow_data_status 상태 업데이트]
|
||
end
|
||
|
||
subgraph RESULT["✅ 결과"]
|
||
K --> L[화면 새로고침]
|
||
L --> M[이동된 데이터 표시]
|
||
end
|
||
</div>
|
||
</div>
|
||
|
||
<h3>4. 배치 실행 플로우</h3>
|
||
<div class="diagram-container">
|
||
<div class="mermaid">
|
||
flowchart TB
|
||
subgraph TRIGGER["⏰ 트리거"]
|
||
A[스케줄러 cron] --> B[batch_configs 조회]
|
||
B --> C{활성화 여부}
|
||
end
|
||
|
||
subgraph CONNECTION["🔌 연결"]
|
||
C -->|활성| D[external_db_connections]
|
||
D --> E[외부 DB 연결]
|
||
end
|
||
|
||
subgraph MAPPING["🗺️ 매핑"]
|
||
E --> F[batch_mappings 조회]
|
||
F --> G[소스 테이블 → 타겟 테이블]
|
||
end
|
||
|
||
subgraph EXECUTION["⚡ 실행"]
|
||
G --> H[외부 DB에서 데이터 조회]
|
||
H --> I[내부 DB에 동기화]
|
||
I --> J[batch_execution_logs 기록]
|
||
end
|
||
|
||
subgraph RESULT["📊 결과"]
|
||
J --> K{성공/실패}
|
||
K -->|성공| L[다음 스케줄 대기]
|
||
K -->|실패| M[에러 로그 기록]
|
||
end
|
||
</div>
|
||
</div>
|
||
|
||
<h3>5. 화면 간 데이터 전달 플로우</h3>
|
||
<div class="diagram-container">
|
||
<div class="mermaid">
|
||
flowchart LR
|
||
subgraph PARENT["📱 부모 화면"]
|
||
A[screen_definitions A] --> B[그리드에서 행 선택]
|
||
B --> C[선택된 데이터]
|
||
end
|
||
|
||
subgraph TRANSFER["🔗 데이터 전달"]
|
||
C --> D[screen_embedding 관계 확인]
|
||
D --> E[screen_data_transfer 설정]
|
||
E --> F{전달 필드 매핑}
|
||
end
|
||
|
||
subgraph CHILD["📱 자식 화면"]
|
||
F --> G[screen_definitions B]
|
||
G --> H[필터 조건으로 적용]
|
||
H --> I[관련 데이터만 조회]
|
||
I --> J[자식 화면에 표시]
|
||
end
|
||
</div>
|
||
</div>
|
||
|
||
<h3>6. 캐스케이딩 선택 플로우</h3>
|
||
<div class="diagram-container">
|
||
<div class="mermaid">
|
||
flowchart TB
|
||
subgraph SELECT1["1️⃣ 첫 번째 선택"]
|
||
A[사용자가 대분류 선택] --> B[cascading_hierarchy_group]
|
||
end
|
||
|
||
subgraph CASCADE["🔗 캐스케이딩"]
|
||
B --> C[cascading_hierarchy_level 조회]
|
||
C --> D[cascading_relation 관계 확인]
|
||
D --> E[하위 레벨 옵션 필터링]
|
||
end
|
||
|
||
subgraph SELECT2["2️⃣ 두 번째 선택"]
|
||
E --> F[중분류 옵션만 표시]
|
||
F --> G[사용자가 중분류 선택]
|
||
end
|
||
|
||
subgraph SELECT3["3️⃣ 세 번째 선택"]
|
||
G --> H[소분류 옵션 필터링]
|
||
H --> I[소분류 옵션만 표시]
|
||
I --> J[최종 선택 완료]
|
||
end
|
||
|
||
subgraph AUTOFILL["✨ 자동 채움"]
|
||
J --> K[cascading_auto_fill_mapping]
|
||
K --> L[관련 필드 자동 입력]
|
||
end
|
||
</div>
|
||
</div>
|
||
|
||
<hr/>
|
||
|
||
<h2>핵심 테이블 관계도 (ER Diagram)</h2>
|
||
|
||
<h3>1. 사용자/권한 시스템</h3>
|
||
<div class="diagram-container">
|
||
<div class="mermaid">
|
||
erDiagram
|
||
company_mng ||--o{ user_info : "company_code"
|
||
company_mng ||--o{ dept_info : "company_code"
|
||
|
||
user_info ||--o{ user_dept : "user_id"
|
||
dept_info ||--o{ user_dept : "dept_code"
|
||
|
||
authority_master ||--o{ authority_sub_user : "objid → master_objid"
|
||
user_info ||--o{ authority_sub_user : "user_id"
|
||
|
||
authority_master ||--o{ authority_master_history : "objid"
|
||
user_info ||--o{ user_info_history : "user_id"
|
||
user_info ||--o{ auth_tokens : "user_id"
|
||
user_info ||--o{ login_access_log : "user_id"
|
||
|
||
authority_master ||--o{ rel_menu_auth : "auth_group_id"
|
||
menu_info ||--o{ rel_menu_auth : "menu_objid"
|
||
|
||
user_info {
|
||
string user_id PK
|
||
string company_code
|
||
string user_name
|
||
}
|
||
|
||
authority_master {
|
||
int objid PK
|
||
string company_code
|
||
string auth_group_name
|
||
}
|
||
|
||
company_mng {
|
||
string company_code PK
|
||
string company_name
|
||
}
|
||
</div>
|
||
</div>
|
||
|
||
<h2>2. 메뉴/화면 시스템</h2>
|
||
<div class="diagram-container">
|
||
<div class="mermaid">
|
||
erDiagram
|
||
menu_info ||--o{ screen_menu_assignments : "objid → menu_objid"
|
||
screen_definitions ||--o{ screen_menu_assignments : "screen_id"
|
||
|
||
screen_definitions ||--|| screen_layouts : "screen_id"
|
||
|
||
screen_groups ||--o{ screen_group_screens : "id → group_id"
|
||
screen_definitions ||--o{ screen_group_screens : "screen_id"
|
||
|
||
menu_info ||--o{ menu_screen_groups : "objid → menu_objid"
|
||
menu_screen_groups ||--o{ menu_screen_group_items : "id → group_id"
|
||
|
||
screen_definitions ||--o{ screen_data_flows : "source/target_screen_id"
|
||
screen_groups ||--o{ screen_data_flows : "group_id"
|
||
|
||
screen_definitions ||--o{ screen_table_relations : "screen_id"
|
||
screen_groups ||--o{ screen_table_relations : "group_id"
|
||
|
||
screen_definitions ||--o{ screen_field_joins : "screen_id"
|
||
|
||
screen_definitions ||--o{ screen_embedding : "parent/child_screen_id"
|
||
screen_embedding ||--o{ screen_split_panel : "left/right_embedding_id"
|
||
screen_embedding ||--o{ screen_data_transfer : "source/target"
|
||
|
||
screen_definitions {
|
||
uuid screen_id PK
|
||
string company_code
|
||
string screen_name
|
||
string table_name
|
||
}
|
||
|
||
screen_layouts {
|
||
uuid screen_id PK_FK
|
||
jsonb layout_metadata
|
||
}
|
||
|
||
menu_info {
|
||
int objid PK
|
||
string company_code
|
||
string menu_name
|
||
string menu_url
|
||
}
|
||
</div>
|
||
</div>
|
||
|
||
<h2>3. 플로우 시스템</h2>
|
||
<div class="diagram-container">
|
||
<div class="mermaid">
|
||
erDiagram
|
||
flow_definition ||--o{ flow_step : "id → definition_id"
|
||
flow_step ||--o{ flow_step_connection : "id → from/to_step_id"
|
||
|
||
flow_step ||--o{ flow_audit_log : "id → from/to_step_id"
|
||
flow_step ||--o{ flow_data_mapping : "step_id"
|
||
flow_step ||--o{ flow_data_status : "step_id"
|
||
|
||
flow_definition ||--o{ flow_integration_log : "definition_id"
|
||
flow_definition ||--o{ node_flows : "definition_id"
|
||
flow_definition ||--o{ dataflow_diagrams : "definition_id"
|
||
|
||
flow_definition ||--o{ flow_external_db_connection : "definition_id"
|
||
|
||
flow_definition {
|
||
int id PK
|
||
string company_code
|
||
string name
|
||
string description
|
||
}
|
||
|
||
flow_step {
|
||
int id PK
|
||
int definition_id
|
||
string step_name
|
||
string table_name
|
||
}
|
||
|
||
flow_step_connection {
|
||
int id PK
|
||
int from_step_id
|
||
int to_step_id
|
||
}
|
||
</div>
|
||
</div>
|
||
|
||
<h2>4. 테이블타입/코드 시스템</h2>
|
||
<div class="diagram-container">
|
||
<div class="mermaid">
|
||
erDiagram
|
||
table_type_columns ||--o{ table_labels : "table_name, column_name"
|
||
table_type_columns ||--o{ table_column_category_values : "table_name, column_name"
|
||
table_type_columns ||--o{ category_column_mapping : "table_name, column_name"
|
||
table_type_columns ||--o{ table_relationships : "table_name"
|
||
table_type_columns ||--o{ table_log_config : "original_table_name"
|
||
|
||
code_category ||--o{ code_info : "category_code"
|
||
|
||
cascading_hierarchy_group ||--o{ cascading_hierarchy_level : "group_code"
|
||
cascading_hierarchy_group ||--o{ cascading_relation : "group_code"
|
||
|
||
cascading_auto_fill_group ||--o{ cascading_auto_fill_mapping : "group_code"
|
||
|
||
category_value_cascading_group ||--o{ category_value_cascading_mapping : "group_id"
|
||
|
||
language_master ||--o{ multi_lang_category : "lang_code"
|
||
|
||
table_type_columns {
|
||
string table_name PK
|
||
string column_name PK
|
||
string company_code PK
|
||
string display_name
|
||
string data_type
|
||
}
|
||
|
||
code_category {
|
||
string category_code PK
|
||
string company_code PK
|
||
string category_name
|
||
}
|
||
|
||
code_info {
|
||
string category_code PK_FK
|
||
string code_value PK
|
||
string company_code PK
|
||
string code_name
|
||
}
|
||
</div>
|
||
</div>
|
||
|
||
<h2>5. 배치/수집 시스템</h2>
|
||
<div class="diagram-container">
|
||
<div class="mermaid">
|
||
erDiagram
|
||
batch_configs ||--o{ batch_mappings : "id → config_id"
|
||
batch_configs ||--o{ batch_execution_logs : "id → config_id"
|
||
|
||
external_db_connections ||--o{ batch_configs : "connection_id"
|
||
external_db_connections ||--o{ data_collection_configs : "connection_id"
|
||
|
||
data_collection_configs ||--o{ data_collection_jobs : "id → config_id"
|
||
data_collection_jobs ||--o{ data_collection_history : "job_id"
|
||
|
||
external_rest_api_connections ||--o{ external_call_configs : "connection_id"
|
||
|
||
batch_configs {
|
||
int id PK
|
||
string company_code
|
||
string batch_name
|
||
string cron_expression
|
||
}
|
||
|
||
external_db_connections {
|
||
int id PK
|
||
string company_code
|
||
string connection_name
|
||
string db_type
|
||
}
|
||
</div>
|
||
</div>
|
||
|
||
<h2>6. 업무 도메인 (동적 관계)</h2>
|
||
<div class="diagram-container">
|
||
<div class="mermaid">
|
||
erDiagram
|
||
customer_mng ||--o{ sales_order_mng : "customer_code"
|
||
sales_order_mng ||--o{ sales_order_detail : "order_id"
|
||
|
||
supplier_mng ||--o{ purchase_order_mng : "supplier_code"
|
||
purchase_order_mng ||--o{ purchase_detail : "order_id"
|
||
|
||
warehouse_info ||--o{ warehouse_location : "warehouse_code"
|
||
warehouse_info ||--o{ inventory_stock : "warehouse_code"
|
||
inventory_stock ||--o{ inventory_history : "stock_id"
|
||
|
||
item_info ||--o{ item_routing_version : "item_code"
|
||
item_routing_version ||--o{ item_routing_detail : "version_id"
|
||
process_mng ||--o{ process_equipment : "process_code"
|
||
|
||
carrier_mng ||--o{ carrier_vehicle_mng : "carrier_code"
|
||
carrier_mng ||--o{ carrier_contract_mng : "carrier_code"
|
||
vehicles ||--o{ vehicle_locations : "vehicle_id"
|
||
vehicles ||--o{ vehicle_location_history : "vehicle_id"
|
||
|
||
equipment_mng ||--o{ equipment_consumable : "equipment_code"
|
||
equipment_mng ||--o{ maintenance_schedules : "equipment_code"
|
||
</div>
|
||
</div>
|
||
|
||
<h2>전체 구조 개요</h2>
|
||
<div class="diagram-container">
|
||
<div class="mermaid">
|
||
graph TB
|
||
subgraph SYSTEM["🔐 시스템/인증 (11개)"]
|
||
AUTH[authority_master<br/>authority_sub_user<br/>rel_menu_auth]
|
||
USER[user_info<br/>user_dept<br/>auth_tokens]
|
||
ORG[company_mng<br/>dept_info]
|
||
end
|
||
|
||
subgraph SCREEN["📱 메뉴/화면 (18개)"]
|
||
MENU[menu_info<br/>menu_screen_groups]
|
||
SCR[screen_definitions<br/>screen_layouts<br/>screen_groups]
|
||
DASH[dashboards<br/>dashboard_elements]
|
||
end
|
||
|
||
subgraph CODE["🏷️ 테이블타입/코드 (20개)"]
|
||
TTC[table_type_columns<br/>table_labels<br/>table_relationships]
|
||
CODE_M[code_category<br/>code_info]
|
||
CASC[cascading_*]
|
||
end
|
||
|
||
subgraph FLOW["🔄 플로우 (10개)"]
|
||
FLOW_DEF[flow_definition<br/>flow_step<br/>flow_step_connection]
|
||
FLOW_DATA[flow_data_mapping<br/>flow_audit_log]
|
||
end
|
||
|
||
subgraph BATCH["⚙️ 배치/수집 (9개)"]
|
||
BATCH_CFG[batch_configs<br/>batch_mappings]
|
||
EXT_CONN[external_db_connections<br/>external_rest_api_connections]
|
||
end
|
||
|
||
subgraph DOMAIN["📊 업무도메인 (69개)"]
|
||
SALES[영업/구매 17개]
|
||
PROD[생산/품질 20개]
|
||
LOGI[물류/창고 8개]
|
||
TRANS[차량/운송 16개]
|
||
EQUIP[설비/안전 8개]
|
||
end
|
||
|
||
USER --> AUTH
|
||
MENU --> SCR
|
||
SCR --> TTC
|
||
FLOW_DEF --> FLOW_DATA
|
||
BATCH_CFG --> EXT_CONN
|
||
</div>
|
||
</div>
|
||
|
||
<h2>카테고리별 테이블 수</h2>
|
||
<table>
|
||
<tr><th>카테고리</th><th>테이블 수</th></tr>
|
||
<tr><td>🔐 시스템/인증</td><td>11개</td></tr>
|
||
<tr><td>📱 메뉴/화면</td><td>18개</td></tr>
|
||
<tr><td>🏷️ 테이블타입/코드</td><td>20개</td></tr>
|
||
<tr><td>🔄 플로우</td><td>10개</td></tr>
|
||
<tr><td>⚙️ 배치/수집</td><td>9개</td></tr>
|
||
<tr><td>📊 보고서</td><td>5개</td></tr>
|
||
<tr><td>📦 물류/창고</td><td>8개</td></tr>
|
||
<tr><td>🏭 생산/품질</td><td>20개</td></tr>
|
||
<tr><td>💰 영업/구매</td><td>17개</td></tr>
|
||
<tr><td>🔧 설비/안전</td><td>8개</td></tr>
|
||
<tr><td>🚛 차량/운송</td><td>16개</td></tr>
|
||
<tr><td>📁 기타</td><td>22개</td></tr>
|
||
<tr><th>총계</th><th>164개</th></tr>
|
||
</table>
|
||
|
||
<script>
|
||
mermaid.initialize({
|
||
startOnLoad: true,
|
||
theme: 'default',
|
||
securityLevel: 'loose'
|
||
});
|
||
</script>
|
||
</body>
|
||
</html>
|