2189 lines
59 KiB
Markdown
2189 lines
59 KiB
Markdown
# WACE ERP 데이터베이스 아키텍처 분석 보고서
|
|
|
|
> 📅 작성일: 2026-01-20
|
|
> 🎯 목적: WACE ERP 시스템 전체 워크플로우 문서화를 위한 DB 구조 분석
|
|
> 📊 DB 엔진: PostgreSQL 16.8
|
|
|
|
---
|
|
|
|
## 📋 목차
|
|
|
|
1. [개요](#1-개요)
|
|
2. [전체 테이블 목록](#2-전체-테이블-목록)
|
|
3. [멀티테넌시 아키텍처](#3-멀티테넌시-아키텍처)
|
|
4. [핵심 시스템 테이블](#4-핵심-시스템-테이블)
|
|
5. [메타데이터 관리 시스템](#5-메타데이터-관리-시스템)
|
|
6. [화면 관리 시스템](#6-화면-관리-시스템)
|
|
7. [비즈니스 도메인별 테이블](#7-비즈니스-도메인별-테이블)
|
|
8. [플로우 및 데이터 통합](#8-플로우-및-데이터-통합)
|
|
9. [인덱스 전략](#9-인덱스-전략)
|
|
10. [동적 테이블 생성 패턴](#10-동적-테이블-생성-패턴)
|
|
11. [마이그레이션 히스토리](#11-마이그레이션-히스토리)
|
|
|
|
---
|
|
|
|
## 1. 개요
|
|
|
|
### 1.1 데이터베이스 통계
|
|
|
|
```
|
|
- 총 테이블 수: 약 280개
|
|
- 총 함수 수: 약 50개
|
|
- 총 트리거 수: 약 30개
|
|
- 총 시퀀스 수: 약 100개
|
|
- 뷰 수: 약 20개
|
|
```
|
|
|
|
### 1.2 아키텍처 특징
|
|
|
|
- **멀티테넌시**: 모든 테이블에 `company_code` 컬럼으로 회사별 데이터 격리
|
|
- **동적 스키마**: 런타임에 테이블 생성/수정 가능
|
|
- **메타데이터 드리븐**: UI 컴포넌트가 메타데이터 테이블을 기반으로 동적 렌더링
|
|
- **이력 관리**: 주요 테이블에 `_log` 테이블로 변경 이력 추적
|
|
- **외부 연동**: 외부 DB 및 REST API 연결 지원
|
|
- **플로우 기반**: 화면 간 데이터 흐름을 정의하고 실행
|
|
|
|
---
|
|
|
|
## 2. 전체 테이블 목록
|
|
|
|
### 2.1 테이블 분류 체계
|
|
|
|
```
|
|
시스템 관리 (약 30개)
|
|
├── 사용자/권한 (10개)
|
|
├── 메뉴 관리 (5개)
|
|
├── 회사 관리 (3개)
|
|
└── 공통 코드 (5개)
|
|
|
|
메타데이터 시스템 (약 20개)
|
|
├── 테이블/컬럼 정의 (8개)
|
|
├── 화면 정의 (10개)
|
|
└── 레이아웃/컴포넌트 (5개)
|
|
|
|
비즈니스 도메인 (약 200개)
|
|
├── 영업/수주 (30개)
|
|
├── 구매/발주 (25개)
|
|
├── 재고/창고 (20개)
|
|
├── 생산/작업 (25개)
|
|
├── 품질/검사 (15개)
|
|
├── 물류/운송 (20개)
|
|
├── PLM/설계 (30개)
|
|
├── 회계/원가 (20개)
|
|
└── 기타 (15개)
|
|
|
|
통합/플로우 (약 30개)
|
|
├── 데이터플로우 (10개)
|
|
├── 배치 작업 (8개)
|
|
└── 외부 연동 (12개)
|
|
```
|
|
|
|
### 2.2 주요 테이블 목록 (알파벳순)
|
|
|
|
<details>
|
|
<summary>전체 테이블 목록 보기 (280개)</summary>
|
|
|
|
```
|
|
approval
|
|
attach_file_info
|
|
auth_tokens
|
|
authority_master
|
|
authority_master_history
|
|
authority_sub_user
|
|
batch_configs
|
|
batch_execution_logs
|
|
batch_job_executions
|
|
batch_job_parameters
|
|
batch_jobs
|
|
batch_mappings
|
|
batch_schedules
|
|
button_action_standards
|
|
carrier_contract_mng
|
|
carrier_contract_mng_log
|
|
carrier_mng
|
|
carrier_mng_log
|
|
carrier_vehicle_mng
|
|
carrier_vehicle_mng_log
|
|
cascading_auto_fill_group
|
|
cascading_auto_fill_mapping
|
|
cascading_condition
|
|
cascading_hierarchy_group
|
|
cascading_hierarchy_level
|
|
cascading_multi_parent
|
|
cascading_multi_parent_source
|
|
cascading_mutual_exclusion
|
|
cascading_relation
|
|
cascading_reverse_lookup
|
|
category_column_mapping
|
|
category_value_cascading_group
|
|
category_value_cascading_mapping
|
|
chartmgmt
|
|
check_report_mng
|
|
code_category
|
|
code_info
|
|
collection_batch_executions
|
|
collection_batch_management
|
|
column_labels
|
|
comm_code
|
|
comm_code_history
|
|
comm_exchange_rate
|
|
comments
|
|
company_code_sequence
|
|
company_mng
|
|
component_standards
|
|
contract_mgmt
|
|
contract_mgmt_option
|
|
counselingmgmt
|
|
customer_item
|
|
customer_item_alias
|
|
customer_item_mapping
|
|
customer_item_price
|
|
customer_mng
|
|
customer_service_mgmt
|
|
customer_service_part
|
|
customer_service_workingtime
|
|
dashboard_elements
|
|
dashboard_shares
|
|
dashboard_slider_items
|
|
dashboard_sliders
|
|
dashboards
|
|
data_collection_configs
|
|
data_collection_history
|
|
data_collection_jobs
|
|
data_relationship_bridge
|
|
dataflow_diagrams
|
|
dataflow_external_calls
|
|
ddl_execution_log
|
|
defect_standard_mng
|
|
defect_standard_mng_log
|
|
delivery_destination
|
|
delivery_history
|
|
delivery_history_defect
|
|
delivery_part_price
|
|
delivery_route_mng
|
|
delivery_route_mng_log
|
|
delivery_status
|
|
dept_info
|
|
dept_info_history
|
|
digital_twin_layout
|
|
digital_twin_layout_template
|
|
digital_twin_location_layout
|
|
digital_twin_objects
|
|
digital_twin_zone_layout
|
|
drivers
|
|
dtg_contracts
|
|
dtg_maintenance_history
|
|
dtg_management
|
|
dtg_management_log
|
|
dtg_monthly_settlements
|
|
dynamic_form_data
|
|
equipment_consumable
|
|
equipment_consumable_log
|
|
equipment_inspection_item
|
|
equipment_inspection_item_log
|
|
equipment_mng
|
|
equipment_mng_log
|
|
estimate_mgmt
|
|
excel_mapping_template
|
|
expense_detail
|
|
expense_master
|
|
external_call_configs
|
|
external_call_logs
|
|
external_connection_permission
|
|
external_db_connection
|
|
external_db_connections
|
|
external_rest_api_connections
|
|
external_work_review_info
|
|
facility_assembly_plan
|
|
file_down_log
|
|
flow_audit_log
|
|
flow_data_mapping
|
|
flow_data_status
|
|
flow_definition
|
|
flow_external_connection_permission
|
|
flow_external_db_connection
|
|
flow_integration_log
|
|
flow_step
|
|
flow_step_connection
|
|
fund_mgmt
|
|
grid_standards
|
|
inbound_mng
|
|
inboxtask
|
|
injection_cost
|
|
input_cost_goal
|
|
input_resource
|
|
inspection_equipment_mng
|
|
inspection_equipment_mng_log
|
|
inspection_standard
|
|
inventory_history
|
|
inventory_stock
|
|
item_info
|
|
item_inspection_info
|
|
item_routing_detail
|
|
item_routing_version
|
|
klbom_tbl
|
|
language_master
|
|
layout_instances
|
|
layout_standards
|
|
login_access_log
|
|
logistics_cost_mng
|
|
logistics_cost_mng_log
|
|
mail_log
|
|
maintenance_schedules
|
|
material_cost
|
|
material_detail_mgmt
|
|
material_master_mgmt
|
|
material_mng
|
|
material_release
|
|
menu_info
|
|
menu_screen_group_items
|
|
menu_screen_groups
|
|
mold_dev_request_info
|
|
multi_lang_category
|
|
multi_lang_key_master
|
|
multi_lang_text
|
|
node_flows
|
|
numbering_rule_parts
|
|
numbering_rules
|
|
oem_factory_mng
|
|
oem_milestone_mng
|
|
oem_mng
|
|
option_mng
|
|
option_price_history
|
|
order_mgmt
|
|
order_mng_master
|
|
order_mng_sub
|
|
order_plan_mgmt
|
|
order_plan_result_error
|
|
order_spec_mng
|
|
order_spec_mng_history
|
|
outbound_mng
|
|
part_bom_qty
|
|
part_bom_report
|
|
part_distribution_list
|
|
part_mgmt
|
|
part_mng
|
|
part_mng_history
|
|
planning_issue
|
|
pms_invest_cost_mng
|
|
pms_pjt_concept_info
|
|
pms_pjt_info
|
|
pms_pjt_year_goal
|
|
pms_rel_pjt_concept_milestone
|
|
pms_rel_pjt_concept_prod
|
|
pms_rel_pjt_prod
|
|
pms_rel_prod_ref_dept
|
|
pms_wbs_task
|
|
pms_wbs_task_confirm
|
|
pms_wbs_task_info
|
|
pms_wbs_task_standard
|
|
pms_wbs_template
|
|
problem_mng
|
|
process_equipment
|
|
process_mng
|
|
procurement_standard
|
|
product_group_mng
|
|
product_kind_spec
|
|
product_kind_spec_main
|
|
product_mgmt
|
|
product_mgmt_model
|
|
product_mgmt_price_history
|
|
product_mgmt_upg_detail
|
|
product_mgmt_upg_master
|
|
product_mng
|
|
product_spec
|
|
production_issue
|
|
production_record
|
|
production_task
|
|
profit_loss
|
|
profit_loss_coefficient
|
|
profit_loss_coolingtime
|
|
profit_loss_depth
|
|
profit_loss_lossrate
|
|
profit_loss_machine
|
|
profit_loss_pretime
|
|
profit_loss_srrate
|
|
profit_loss_total
|
|
profit_loss_total_addlist
|
|
profit_loss_weight
|
|
project
|
|
project_mgmt
|
|
purchase_detail
|
|
purchase_order
|
|
purchase_order_master
|
|
purchase_order_mng
|
|
purchase_order_multi
|
|
purchase_order_part
|
|
ratecal_mgmt
|
|
receive_history
|
|
receiving
|
|
rel_menu_auth
|
|
report_layout
|
|
report_master
|
|
report_menu_mapping
|
|
report_query
|
|
report_template
|
|
safety_budget_execution
|
|
safety_incidents
|
|
safety_inspections
|
|
safety_inspections_log
|
|
sales_bom_part_qty
|
|
sales_bom_report
|
|
sales_bom_report_part
|
|
sales_long_delivery
|
|
sales_long_delivery_input
|
|
sales_long_delivery_predict
|
|
sales_order_detail
|
|
sales_order_detail_log
|
|
sales_order_mng
|
|
sales_part_chg
|
|
sales_request_master
|
|
sales_request_part
|
|
sample_supply
|
|
screen_data_flows
|
|
screen_data_transfer
|
|
screen_definitions
|
|
screen_embedding
|
|
screen_field_joins
|
|
screen_group_members
|
|
screen_group_screens
|
|
screen_groups
|
|
screen_layouts
|
|
screen_menu_assignments
|
|
screen_split_panel
|
|
screen_table_relations
|
|
screen_templates
|
|
screen_widgets
|
|
shipment_detail
|
|
shipment_header
|
|
shipment_instruction
|
|
shipment_instruction_item
|
|
shipment_pallet
|
|
shipment_plan
|
|
standard_doc_info
|
|
structural_review_proposal
|
|
style_templates
|
|
supplier_item
|
|
supplier_item_alias
|
|
supplier_item_mapping
|
|
supplier_item_price
|
|
supplier_mng
|
|
supplier_mng_log
|
|
supply_charger_mng
|
|
supply_mng
|
|
supply_mng_history
|
|
table_column_category_values
|
|
table_labels
|
|
table_log_config
|
|
table_relationships
|
|
table_type_columns
|
|
tax_invoice
|
|
tax_invoice_item
|
|
time_sheet
|
|
transport_logs
|
|
transport_statistics
|
|
transport_vehicle_locations
|
|
used_mng
|
|
user_dept
|
|
user_dept_sub
|
|
user_info
|
|
user_info_history
|
|
vehicle_location_history
|
|
vehicle_locations
|
|
vehicle_trip_summary
|
|
vehicles
|
|
warehouse_info
|
|
warehouse_location
|
|
web_type_standards
|
|
work_instruction
|
|
work_instruction_detail
|
|
work_instruction_detail_log
|
|
work_instruction_log
|
|
work_order
|
|
work_orders
|
|
work_orders_detail
|
|
work_request
|
|
yard_layout
|
|
yard_material_placement
|
|
```
|
|
|
|
</details>
|
|
|
|
---
|
|
|
|
## 3. 멀티테넌시 아키텍처
|
|
|
|
### 3.1 company_code 패턴
|
|
|
|
**모든 테이블에 필수적으로 포함되는 컬럼:**
|
|
|
|
```sql
|
|
company_code VARCHAR(20) NOT NULL
|
|
```
|
|
|
|
**의미:**
|
|
- 하나의 데이터베이스에서 여러 회사의 데이터를 격리
|
|
- 모든 쿼리는 반드시 `company_code` 필터 포함 필요
|
|
|
|
### 3.2 특별한 company_code 값
|
|
|
|
#### `company_code = "*"` 의미
|
|
|
|
```sql
|
|
-- ❌ 잘못된 이해: 모든 회사가 공유하는 공통 데이터
|
|
-- ✅ 올바른 이해: 슈퍼 관리자 전용 데이터
|
|
|
|
-- 일반 회사는 "*" 데이터를 볼 수 없음
|
|
SELECT * FROM table_name
|
|
WHERE company_code = 'COMPANY_A'
|
|
AND company_code != '*'; -- 필수!
|
|
```
|
|
|
|
**용도:**
|
|
- 시스템 관리자용 메타데이터
|
|
- 전역 설정 값
|
|
- 기본 템플릿
|
|
|
|
### 3.3 멀티테넌시 쿼리 패턴
|
|
|
|
```sql
|
|
-- ✅ 표준 SELECT 패턴
|
|
SELECT * FROM table_name
|
|
WHERE company_code = $1
|
|
AND company_code != '*'
|
|
ORDER BY created_date DESC;
|
|
|
|
-- ✅ JOIN 패턴 (company_code 매칭 필수!)
|
|
SELECT a.*, b.name
|
|
FROM table_a a
|
|
LEFT JOIN table_b b
|
|
ON a.ref_id = b.id
|
|
AND a.company_code = b.company_code -- 필수!
|
|
WHERE a.company_code = $1;
|
|
|
|
-- ✅ 서브쿼리 패턴
|
|
SELECT *
|
|
FROM orders o
|
|
WHERE company_code = $1
|
|
AND product_id IN (
|
|
SELECT id FROM products
|
|
WHERE company_code = $1 -- 서브쿼리에도 필수!
|
|
);
|
|
|
|
-- ✅ 집계 패턴
|
|
SELECT
|
|
product_type,
|
|
COUNT(*) as total,
|
|
SUM(amount) as total_amount
|
|
FROM sales
|
|
WHERE company_code = $1
|
|
GROUP BY product_type;
|
|
```
|
|
|
|
### 3.4 company_code 인덱스 전략
|
|
|
|
**모든 테이블에 필수 인덱스:**
|
|
|
|
```sql
|
|
CREATE INDEX idx_{table_name}_company_code
|
|
ON {table_name}(company_code);
|
|
|
|
-- 복합 인덱스 예시
|
|
CREATE INDEX idx_sales_company_date
|
|
ON sales(company_code, sale_date DESC);
|
|
```
|
|
|
|
---
|
|
|
|
## 4. 핵심 시스템 테이블
|
|
|
|
### 4.1 사용자 관리
|
|
|
|
#### user_info (사용자 정보)
|
|
|
|
```sql
|
|
CREATE TABLE user_info (
|
|
sabun VARCHAR(1024), -- 사번
|
|
user_id VARCHAR(1024) PRIMARY KEY,-- 사용자 ID
|
|
user_password VARCHAR(1024), -- 암호화된 비밀번호
|
|
user_name VARCHAR(1024), -- 한글명
|
|
user_name_eng VARCHAR(1024), -- 영문명
|
|
user_name_cn VARCHAR(1024), -- 중문명
|
|
dept_code VARCHAR(1024), -- 부서 코드
|
|
dept_name VARCHAR(1024), -- 부서명
|
|
position_code VARCHAR(1024), -- 직위 코드
|
|
position_name VARCHAR(1024), -- 직위명
|
|
email VARCHAR(1024), -- 이메일
|
|
tel VARCHAR(1024), -- 전화번호
|
|
cell_phone VARCHAR(1024), -- 휴대폰
|
|
user_type VARCHAR(1024), -- 사용자 유형 코드
|
|
user_type_name VARCHAR(1024), -- 사용자 유형명
|
|
company_code VARCHAR(50), -- 회사 코드 (멀티테넌시)
|
|
status VARCHAR(32), -- active/inactive
|
|
license_number VARCHAR(50), -- 면허번호
|
|
vehicle_number VARCHAR(50), -- 차량번호
|
|
signup_type VARCHAR(20), -- 가입 유형
|
|
branch_name VARCHAR(100), -- 지점명
|
|
regdate TIMESTAMP, -- 등록일
|
|
end_date TIMESTAMP -- 종료일
|
|
);
|
|
```
|
|
|
|
**관련 테이블:**
|
|
- `user_info_history`: 사용자 정보 변경 이력
|
|
- `user_dept`: 사용자-부서 관계
|
|
- `user_dept_sub`: 사용자 하위 부서
|
|
|
|
#### auth_tokens (인증 토큰)
|
|
|
|
```sql
|
|
CREATE TABLE auth_tokens (
|
|
id SERIAL PRIMARY KEY,
|
|
user_id VARCHAR(255) NOT NULL,
|
|
token VARCHAR(500) NOT NULL,
|
|
refresh_token VARCHAR(500),
|
|
expires_at TIMESTAMP NOT NULL,
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
ip_address VARCHAR(50),
|
|
user_agent TEXT
|
|
);
|
|
```
|
|
|
|
### 4.2 권한 관리
|
|
|
|
#### authority_master (권한 그룹)
|
|
|
|
```sql
|
|
CREATE TABLE authority_master (
|
|
objid NUMERIC PRIMARY KEY,
|
|
auth_code VARCHAR(64), -- 권한 코드
|
|
auth_name VARCHAR(64), -- 권한명
|
|
company_code VARCHAR(50), -- 회사 코드
|
|
status VARCHAR(32), -- 상태
|
|
writer VARCHAR(32), -- 작성자
|
|
regdate TIMESTAMP -- 등록일
|
|
);
|
|
```
|
|
|
|
**관련 테이블:**
|
|
- `authority_master_history`: 권한 변경 이력
|
|
- `authority_sub_user`: 권한-사용자 매핑
|
|
- `rel_menu_auth`: 권한-메뉴 매핑
|
|
|
|
### 4.3 메뉴 관리
|
|
|
|
#### menu_info (메뉴 정보)
|
|
|
|
```sql
|
|
CREATE TABLE menu_info (
|
|
objid NUMERIC PRIMARY KEY,
|
|
menu_type NUMERIC, -- 0=일반, 1=시스템관리, 2=동적생성
|
|
parent_obj_id NUMERIC, -- 부모 메뉴 ID
|
|
menu_name_kor VARCHAR(64), -- 한글 메뉴명
|
|
menu_name_eng VARCHAR(64), -- 영문 메뉴명
|
|
menu_code VARCHAR(50), -- 메뉴 코드
|
|
menu_url VARCHAR(256), -- 메뉴 URL
|
|
seq NUMERIC, -- 순서
|
|
screen_code VARCHAR(50), -- 화면 코드 (동적 생성 시)
|
|
screen_group_id INTEGER, -- 화면 그룹 ID
|
|
company_code VARCHAR(50), -- 회사 코드
|
|
status VARCHAR(32), -- active/inactive
|
|
lang_key VARCHAR(100), -- 다국어 키
|
|
source_menu_objid BIGINT, -- 원본 메뉴 ID (복사 시)
|
|
writer VARCHAR(32),
|
|
regdate TIMESTAMP
|
|
);
|
|
```
|
|
|
|
**특징:**
|
|
- `menu_type = 2`: 화면 생성 시 자동으로 생성되는 메뉴
|
|
- 트리거: `auto_create_menu_for_screen()` - 화면 생성 시 자동 메뉴 추가
|
|
|
|
**관련 테이블:**
|
|
- `menu_screen_groups`: 메뉴 화면 그룹
|
|
- `menu_screen_group_items`: 그룹-화면 연결
|
|
|
|
### 4.4 회사 관리
|
|
|
|
#### company_mng (회사 정보)
|
|
|
|
```sql
|
|
CREATE TABLE company_mng (
|
|
company_code VARCHAR(32) PRIMARY KEY,
|
|
company_name VARCHAR(64),
|
|
business_registration_number VARCHAR(20), -- 사업자등록번호
|
|
representative_name VARCHAR(100), -- 대표자명
|
|
representative_phone VARCHAR(20), -- 대표 연락처
|
|
email VARCHAR(255), -- 회사 이메일
|
|
website VARCHAR(500), -- 웹사이트
|
|
address VARCHAR(500), -- 주소
|
|
status VARCHAR(32),
|
|
writer VARCHAR(32),
|
|
regdate TIMESTAMP
|
|
);
|
|
```
|
|
|
|
**관련 테이블:**
|
|
- `company_code_sequence`: 회사별 시퀀스 관리
|
|
|
|
### 4.5 부서 관리
|
|
|
|
#### dept_info (부서 정보)
|
|
|
|
```sql
|
|
CREATE TABLE dept_info (
|
|
dept_code VARCHAR(1024) PRIMARY KEY,
|
|
dept_name VARCHAR(1024),
|
|
parent_dept_code VARCHAR(1024), -- 상위 부서
|
|
company_code VARCHAR(50),
|
|
status VARCHAR(32),
|
|
writer VARCHAR(32),
|
|
regdate TIMESTAMP
|
|
);
|
|
```
|
|
|
|
**관련 테이블:**
|
|
- `dept_info_history`: 부서 정보 변경 이력
|
|
|
|
---
|
|
|
|
## 5. 메타데이터 관리 시스템
|
|
|
|
WACE ERP의 핵심 특징은 **메타데이터 드리븐 아키텍처**입니다. 화면, 테이블, 컬럼 정보를 메타데이터 테이블에서 관리하고, 프론트엔드가 이를 기반으로 동적 렌더링합니다.
|
|
|
|
### 5.1 테이블 메타데이터
|
|
|
|
#### table_labels (테이블 정의)
|
|
|
|
```sql
|
|
CREATE TABLE table_labels (
|
|
table_name VARCHAR(100) PRIMARY KEY, -- 테이블명 (물리명)
|
|
table_label VARCHAR(200), -- 테이블 한글명
|
|
description TEXT, -- 설명
|
|
use_log_table VARCHAR(1) DEFAULT 'N', -- 이력 테이블 사용 여부
|
|
created_date TIMESTAMP,
|
|
updated_date TIMESTAMP
|
|
);
|
|
```
|
|
|
|
**역할:**
|
|
- 동적으로 생성된 모든 테이블의 메타정보 저장
|
|
- 화면 생성 시 테이블 선택 목록 제공
|
|
- 데이터 딕셔너리로 활용
|
|
|
|
#### table_type_columns (컬럼 타입 정의)
|
|
|
|
```sql
|
|
CREATE TABLE table_type_columns (
|
|
id SERIAL PRIMARY KEY,
|
|
table_name VARCHAR(255) NOT NULL,
|
|
column_name VARCHAR(255) NOT NULL,
|
|
company_code VARCHAR(20) NOT NULL, -- 회사별 컬럼 설정
|
|
input_type VARCHAR(50) DEFAULT 'text',-- 입력 타입
|
|
detail_settings TEXT DEFAULT '{}', -- JSON 상세 설정
|
|
is_nullable VARCHAR(10) DEFAULT 'Y',
|
|
display_order INTEGER DEFAULT 0, -- 표시 순서
|
|
created_date TIMESTAMP,
|
|
updated_date TIMESTAMP,
|
|
|
|
UNIQUE(table_name, column_name, company_code)
|
|
);
|
|
```
|
|
|
|
**input_type 종류:**
|
|
- `text`: 일반 텍스트
|
|
- `number`: 숫자
|
|
- `date`: 날짜
|
|
- `select`: 드롭다운 (options 필요)
|
|
- `textarea`: 여러 줄 텍스트
|
|
- `entity`: 참조 테이블 (referenceTable, referenceColumn 필요)
|
|
- `checkbox`: 체크박스
|
|
- `radio`: 라디오 버튼
|
|
|
|
**detail_settings 예시:**
|
|
|
|
```json
|
|
// select 타입
|
|
{
|
|
"options": [
|
|
{"label": "일반", "value": "normal"},
|
|
{"label": "긴급", "value": "urgent"}
|
|
]
|
|
}
|
|
|
|
// entity 타입
|
|
{
|
|
"referenceTable": "customer_mng",
|
|
"referenceColumn": "customer_code",
|
|
"displayColumn": "customer_name"
|
|
}
|
|
```
|
|
|
|
#### column_labels (컬럼 라벨 - 레거시)
|
|
|
|
```sql
|
|
CREATE TABLE column_labels (
|
|
table_name VARCHAR(100) NOT NULL,
|
|
column_name VARCHAR(100) NOT NULL,
|
|
column_label VARCHAR(200), -- 한글 라벨
|
|
input_type VARCHAR(50),
|
|
detail_settings TEXT,
|
|
description TEXT,
|
|
display_order INTEGER,
|
|
is_visible BOOLEAN DEFAULT true,
|
|
created_date TIMESTAMP,
|
|
updated_date TIMESTAMP,
|
|
|
|
PRIMARY KEY (table_name, column_name)
|
|
);
|
|
```
|
|
|
|
**참고:**
|
|
- 레거시 호환을 위해 유지
|
|
- 새로운 컬럼은 `table_type_columns` 사용 권장
|
|
- `table_type_columns`는 회사별 설정, `column_labels`는 전역 설정
|
|
|
|
### 5.2 카테고리 값 관리
|
|
|
|
#### table_column_category_values (컬럼 카테고리 값)
|
|
|
|
```sql
|
|
CREATE TABLE table_column_category_values (
|
|
id SERIAL PRIMARY KEY,
|
|
table_name VARCHAR(255) NOT NULL,
|
|
column_name VARCHAR(255) NOT NULL,
|
|
company_code VARCHAR(20) NOT NULL,
|
|
category_value VARCHAR(500) NOT NULL, -- 카테고리 값
|
|
display_label VARCHAR(500), -- 표시 라벨
|
|
display_order INTEGER DEFAULT 0,
|
|
is_active VARCHAR(1) DEFAULT 'Y',
|
|
parent_value VARCHAR(500), -- 부모 카테고리 (계층 구조)
|
|
created_date TIMESTAMP,
|
|
updated_date TIMESTAMP,
|
|
|
|
UNIQUE(table_name, column_name, company_code, category_value)
|
|
);
|
|
```
|
|
|
|
**용도:**
|
|
- 동적 드롭다운 값 관리
|
|
- 계층형 카테고리 지원 (parent_value)
|
|
- 회사별 카테고리 값 커스터마이징
|
|
|
|
**관련 테이블:**
|
|
- `category_column_mapping`: 카테고리-컬럼 매핑
|
|
- `category_value_cascading_group`: 카테고리 캐스케이딩 그룹
|
|
- `category_value_cascading_mapping`: 캐스케이딩 매핑
|
|
|
|
### 5.3 테이블 관계 관리
|
|
|
|
#### table_relationships (테이블 관계)
|
|
|
|
```sql
|
|
CREATE TABLE table_relationships (
|
|
id SERIAL PRIMARY KEY,
|
|
parent_table VARCHAR(100), -- 부모 테이블
|
|
parent_column VARCHAR(100), -- 부모 컬럼
|
|
child_table VARCHAR(100), -- 자식 테이블
|
|
child_column VARCHAR(100), -- 자식 컬럼
|
|
relationship_type VARCHAR(20), -- one-to-many, many-to-one 등
|
|
created_date TIMESTAMP
|
|
);
|
|
```
|
|
|
|
---
|
|
|
|
## 6. 화면 관리 시스템
|
|
|
|
WACE ERP는 코드 작성 없이 화면을 동적으로 생성/수정할 수 있는 **Low-Code 플랫폼** 기능을 제공합니다.
|
|
|
|
### 6.1 화면 정의
|
|
|
|
#### screen_definitions (화면 정의)
|
|
|
|
```sql
|
|
CREATE TABLE screen_definitions (
|
|
screen_id SERIAL PRIMARY KEY,
|
|
screen_name VARCHAR(100) NOT NULL, -- 화면명
|
|
screen_code VARCHAR(50) NOT NULL, -- 화면 코드 (URL용)
|
|
table_name VARCHAR(100) NOT NULL, -- 메인 테이블
|
|
company_code VARCHAR(50) NOT NULL,
|
|
description TEXT,
|
|
is_active CHAR(1) DEFAULT 'Y', -- Y=활성, N=비활성, D=삭제
|
|
layout_metadata JSONB, -- 레이아웃 JSON
|
|
|
|
-- 외부 데이터 소스 지원
|
|
db_source_type VARCHAR(10) DEFAULT 'internal', -- internal/external
|
|
db_connection_id INTEGER, -- 외부 DB 연결 ID
|
|
data_source_type VARCHAR(20) DEFAULT 'database', -- database/rest_api
|
|
rest_api_connection_id INTEGER, -- REST API 연결 ID
|
|
rest_api_endpoint VARCHAR(500), -- API 엔드포인트
|
|
rest_api_json_path VARCHAR(200) DEFAULT 'data', -- JSON 응답 경로
|
|
|
|
source_screen_id INTEGER, -- 원본 화면 ID (복사 시)
|
|
|
|
created_date TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
created_by VARCHAR(50),
|
|
updated_date TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
updated_by VARCHAR(50),
|
|
deleted_date TIMESTAMP, -- 휴지통 이동 시점
|
|
deleted_by VARCHAR(50),
|
|
delete_reason TEXT,
|
|
|
|
UNIQUE(screen_code, company_code)
|
|
);
|
|
```
|
|
|
|
**화면 생성 플로우:**
|
|
1. 관리자가 화면 설정 페이지에서 테이블 선택
|
|
2. `screen_definitions` 레코드 생성
|
|
3. 트리거 `auto_create_menu_for_screen()` 실행 → `menu_info` 자동 생성
|
|
4. 프론트엔드가 `/screen/{screen_code}` 경로로 접근 시 동적 렌더링
|
|
|
|
#### screen_layouts (화면 레이아웃 - 레거시)
|
|
|
|
```sql
|
|
CREATE TABLE screen_layouts (
|
|
layout_id SERIAL PRIMARY KEY,
|
|
screen_id INTEGER REFERENCES screen_definitions(screen_id),
|
|
layout_name VARCHAR(100),
|
|
layout_type VARCHAR(50), -- grid, form, split, tab 등
|
|
layout_config JSONB, -- 레이아웃 설정
|
|
display_order INTEGER,
|
|
is_active CHAR(1) DEFAULT 'Y',
|
|
company_code VARCHAR(50),
|
|
created_date TIMESTAMP,
|
|
updated_date TIMESTAMP
|
|
);
|
|
```
|
|
|
|
### 6.2 화면 그룹 관리
|
|
|
|
#### screen_groups (화면 그룹)
|
|
|
|
```sql
|
|
CREATE TABLE screen_groups (
|
|
id SERIAL PRIMARY KEY,
|
|
group_name VARCHAR(100) NOT NULL, -- 그룹명
|
|
group_code VARCHAR(50) NOT NULL, -- 그룹 코드
|
|
main_table_name VARCHAR(100), -- 메인 테이블
|
|
description TEXT,
|
|
icon VARCHAR(100), -- 아이콘
|
|
display_order INT DEFAULT 0,
|
|
is_active VARCHAR(1) DEFAULT 'Y',
|
|
company_code VARCHAR(20) NOT NULL,
|
|
|
|
-- 계층 구조 지원 (037 마이그레이션에서 추가)
|
|
parent_group_id INTEGER REFERENCES screen_groups(id) ON DELETE CASCADE,
|
|
group_level INTEGER DEFAULT 0, -- 0=대, 1=중, 2=소
|
|
hierarchy_path VARCHAR(500), -- 예: /1/3/5/
|
|
|
|
created_date TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_date TIMESTAMPTZ DEFAULT NOW(),
|
|
writer VARCHAR(50),
|
|
|
|
UNIQUE(company_code, group_code)
|
|
);
|
|
|
|
CREATE INDEX idx_screen_groups_company_code ON screen_groups(company_code);
|
|
CREATE INDEX idx_screen_groups_parent_id ON screen_groups(parent_group_id);
|
|
CREATE INDEX idx_screen_groups_hierarchy_path ON screen_groups(hierarchy_path);
|
|
```
|
|
|
|
#### screen_group_screens (화면-그룹 연결)
|
|
|
|
```sql
|
|
CREATE TABLE screen_group_screens (
|
|
id SERIAL PRIMARY KEY,
|
|
group_id INT NOT NULL REFERENCES screen_groups(id) ON DELETE CASCADE,
|
|
screen_id INT NOT NULL REFERENCES screen_definitions(screen_id) ON DELETE CASCADE,
|
|
screen_role VARCHAR(50) DEFAULT 'main', -- main, register, list, detail 등
|
|
display_order INT DEFAULT 0,
|
|
is_default VARCHAR(1) DEFAULT 'N', -- 기본 화면 여부
|
|
company_code VARCHAR(20) NOT NULL,
|
|
created_date TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_date TIMESTAMPTZ DEFAULT NOW(),
|
|
writer VARCHAR(50),
|
|
|
|
UNIQUE(group_id, screen_id)
|
|
);
|
|
```
|
|
|
|
**용도:**
|
|
- 관련 화면들을 그룹으로 묶어 관리
|
|
- 예: "영업 관리" 그룹 → 견적 화면, 수주 화면, 출하 화면
|
|
|
|
### 6.3 화면 필드 조인
|
|
|
|
#### screen_field_joins (화면 필드 조인 설정)
|
|
|
|
```sql
|
|
CREATE TABLE screen_field_joins (
|
|
id SERIAL PRIMARY KEY,
|
|
screen_id INT NOT NULL REFERENCES screen_definitions(screen_id) ON DELETE CASCADE,
|
|
layout_id INT,
|
|
component_id VARCHAR(500),
|
|
field_name VARCHAR(100),
|
|
|
|
-- 저장 테이블 설정
|
|
save_table VARCHAR(100) NOT NULL,
|
|
save_column VARCHAR(100) NOT NULL,
|
|
|
|
-- 조인 테이블 설정
|
|
join_table VARCHAR(100) NOT NULL,
|
|
join_column VARCHAR(100) NOT NULL,
|
|
display_column VARCHAR(100) NOT NULL,
|
|
|
|
-- 조인 옵션
|
|
join_type VARCHAR(20) DEFAULT 'LEFT',
|
|
filter_condition TEXT,
|
|
sort_column VARCHAR(100),
|
|
sort_direction VARCHAR(10) DEFAULT 'ASC',
|
|
|
|
is_active VARCHAR(1) DEFAULT 'Y',
|
|
company_code VARCHAR(20) NOT NULL,
|
|
created_date TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_date TIMESTAMPTZ DEFAULT NOW(),
|
|
writer VARCHAR(50)
|
|
);
|
|
```
|
|
|
|
**예시:**
|
|
```json
|
|
{
|
|
"save_table": "sales_order",
|
|
"save_column": "customer_code",
|
|
"join_table": "customer_mng",
|
|
"join_column": "customer_code",
|
|
"display_column": "customer_name"
|
|
}
|
|
```
|
|
|
|
### 6.4 화면 간 데이터 흐름
|
|
|
|
#### screen_data_flows (화면 간 데이터 흐름)
|
|
|
|
```sql
|
|
CREATE TABLE screen_data_flows (
|
|
id SERIAL PRIMARY KEY,
|
|
group_id INT REFERENCES screen_groups(id) ON DELETE SET NULL,
|
|
|
|
-- 소스 화면
|
|
source_screen_id INT NOT NULL REFERENCES screen_definitions(screen_id) ON DELETE CASCADE,
|
|
source_action VARCHAR(50), -- click, submit, select 등
|
|
|
|
-- 타겟 화면
|
|
target_screen_id INT NOT NULL REFERENCES screen_definitions(screen_id) ON DELETE CASCADE,
|
|
target_action VARCHAR(50), -- open, load, refresh 등
|
|
|
|
-- 데이터 매핑 설정
|
|
data_mapping JSONB, -- 필드 매핑 정보
|
|
|
|
-- 흐름 설정
|
|
flow_type VARCHAR(20) DEFAULT 'unidirectional', -- unidirectional/bidirectional
|
|
flow_label VARCHAR(100), -- 시각화 라벨
|
|
condition_expression TEXT, -- 실행 조건식
|
|
|
|
is_active VARCHAR(1) DEFAULT 'Y',
|
|
company_code VARCHAR(20) NOT NULL,
|
|
created_date TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_date TIMESTAMPTZ DEFAULT NOW(),
|
|
writer VARCHAR(50)
|
|
);
|
|
```
|
|
|
|
**data_mapping 예시:**
|
|
|
|
```json
|
|
{
|
|
"customer_code": "customer_code",
|
|
"customer_name": "customer_name",
|
|
"selected_date": "order_date"
|
|
}
|
|
```
|
|
|
|
#### screen_table_relations (화면-테이블 관계)
|
|
|
|
```sql
|
|
CREATE TABLE screen_table_relations (
|
|
id SERIAL PRIMARY KEY,
|
|
group_id INT REFERENCES screen_groups(id) ON DELETE SET NULL,
|
|
screen_id INT NOT NULL REFERENCES screen_definitions(screen_id) ON DELETE CASCADE,
|
|
table_name VARCHAR(100) NOT NULL,
|
|
|
|
relation_type VARCHAR(20) DEFAULT 'main', -- main, join, lookup
|
|
crud_operations VARCHAR(20) DEFAULT 'CRUD',-- CRUD 조합
|
|
description TEXT,
|
|
|
|
is_active VARCHAR(1) DEFAULT 'Y',
|
|
company_code VARCHAR(20) NOT NULL,
|
|
created_date TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_date TIMESTAMPTZ DEFAULT NOW(),
|
|
writer VARCHAR(50)
|
|
);
|
|
```
|
|
|
|
### 6.5 컴포넌트 표준
|
|
|
|
#### component_standards (컴포넌트 표준)
|
|
|
|
```sql
|
|
CREATE TABLE component_standards (
|
|
component_code VARCHAR(50) PRIMARY KEY,
|
|
component_name VARCHAR(100) NOT NULL,
|
|
component_name_eng VARCHAR(100),
|
|
description TEXT,
|
|
category VARCHAR(50) NOT NULL, -- input, layout, display 등
|
|
icon_name VARCHAR(50),
|
|
default_size JSON, -- {width, height}
|
|
component_config JSON NOT NULL, -- 컴포넌트 설정
|
|
preview_image VARCHAR(255),
|
|
sort_order INTEGER DEFAULT 0,
|
|
is_active CHAR(1) DEFAULT 'Y',
|
|
is_public CHAR(1) DEFAULT 'Y',
|
|
company_code VARCHAR(50) NOT NULL,
|
|
created_date TIMESTAMP,
|
|
updated_date TIMESTAMP
|
|
);
|
|
```
|
|
|
|
#### layout_standards (레이아웃 표준)
|
|
|
|
```sql
|
|
CREATE TABLE layout_standards (
|
|
layout_code VARCHAR(50) PRIMARY KEY,
|
|
layout_name VARCHAR(100) NOT NULL,
|
|
layout_type VARCHAR(50), -- grid, form, split, tab
|
|
default_config JSON,
|
|
is_active CHAR(1) DEFAULT 'Y',
|
|
company_code VARCHAR(50),
|
|
created_date TIMESTAMP,
|
|
updated_date TIMESTAMP
|
|
);
|
|
```
|
|
|
|
---
|
|
|
|
## 7. 비즈니스 도메인별 테이블
|
|
|
|
### 7.1 영업/수주 관리
|
|
|
|
#### 수주 관리 (Order Management)
|
|
|
|
```
|
|
sales_order_mng -- 수주 마스터
|
|
├── sales_order_detail -- 수주 상세
|
|
├── sales_order_detail_log -- 수주 상세 이력
|
|
├── sales_request_master -- 영업 요청 마스터
|
|
├── sales_request_part -- 영업 요청 부품
|
|
└── sales_part_chg -- 영업 부품 변경
|
|
```
|
|
|
|
**sales_order_mng:**
|
|
- 고객별 수주 정보
|
|
- 납기, 금액, 상태 관리
|
|
|
|
**sales_order_detail:**
|
|
- 수주 라인 아이템
|
|
- 품목, 수량, 단가 정보
|
|
|
|
#### 견적 관리
|
|
|
|
```
|
|
estimate_mgmt -- 견적 관리
|
|
contract_mgmt -- 계약 관리
|
|
├── contract_mgmt_option -- 계약 옵션
|
|
```
|
|
|
|
#### BOM 관리
|
|
|
|
```
|
|
sales_bom_report -- 영업 BOM 리포트
|
|
├── sales_bom_report_part -- 영업 BOM 부품
|
|
└── sales_bom_part_qty -- 영업 BOM 부품 수량
|
|
```
|
|
|
|
### 7.2 구매/발주 관리
|
|
|
|
```
|
|
purchase_order_master -- 발주 마스터
|
|
├── purchase_order -- 발주 상세
|
|
├── purchase_order_part -- 발주 부품
|
|
├── purchase_order_multi -- 다중 발주
|
|
└── purchase_detail -- 구매 상세
|
|
|
|
supplier_mng -- 공급업체 관리
|
|
├── supplier_mng_log -- 공급업체 이력
|
|
├── supplier_item -- 공급업체 품목
|
|
├── supplier_item_alias -- 공급업체 품목 별칭
|
|
├── supplier_item_mapping -- 공급업체 품목 매핑
|
|
└── supplier_item_price -- 공급업체 품목 가격
|
|
```
|
|
|
|
### 7.3 재고/창고 관리
|
|
|
|
```
|
|
inventory_stock -- 재고 현황
|
|
inventory_history -- 재고 이력
|
|
warehouse_info -- 창고 정보
|
|
warehouse_location -- 창고 위치
|
|
inbound_mng -- 입고 관리
|
|
outbound_mng -- 출고 관리
|
|
receiving -- 입하
|
|
receive_history -- 입하 이력
|
|
```
|
|
|
|
### 7.4 생산/작업 관리
|
|
|
|
```
|
|
work_orders -- 작업지시 (신규)
|
|
├── work_orders_detail -- 작업지시 상세
|
|
work_order -- 작업지시 (레거시)
|
|
work_instruction -- 작업 지시서
|
|
├── work_instruction_detail -- 작업 지시서 상세
|
|
├── work_instruction_detail_log
|
|
└── work_instruction_log
|
|
|
|
production_record -- 생산 실적
|
|
production_task -- 생산 작업
|
|
production_issue -- 생산 이슈
|
|
work_request -- 작업 요청
|
|
```
|
|
|
|
#### work_orders (작업지시 - 050 마이그레이션)
|
|
|
|
```sql
|
|
CREATE TABLE work_orders (
|
|
id VARCHAR(500) PRIMARY KEY DEFAULT gen_random_uuid()::text,
|
|
created_date TIMESTAMP DEFAULT NOW(),
|
|
updated_date TIMESTAMP DEFAULT NOW(),
|
|
writer VARCHAR(500),
|
|
company_code VARCHAR(500),
|
|
|
|
-- 작업지시 정보
|
|
wo_number VARCHAR(500), -- WO-20250130-001
|
|
product_code VARCHAR(500),
|
|
product_name VARCHAR(500),
|
|
spec VARCHAR(500),
|
|
order_qty VARCHAR(500),
|
|
completed_qty VARCHAR(500),
|
|
start_date VARCHAR(500),
|
|
due_date VARCHAR(500),
|
|
status VARCHAR(500), -- normal/urgent
|
|
progress_status VARCHAR(500), -- pending/in-progress/completed
|
|
equipment VARCHAR(500),
|
|
routing VARCHAR(500),
|
|
work_team VARCHAR(500), -- DAY/NIGHT
|
|
worker VARCHAR(500),
|
|
shift VARCHAR(500), -- DAY/NIGHT
|
|
remark VARCHAR(500)
|
|
);
|
|
|
|
CREATE INDEX idx_work_orders_company_code ON work_orders(company_code);
|
|
CREATE INDEX idx_work_orders_wo_number ON work_orders(wo_number);
|
|
```
|
|
|
|
### 7.5 품질/검사 관리
|
|
|
|
```
|
|
inspection_standard -- 검사 기준
|
|
item_inspection_info -- 품목 검사 정보
|
|
inspection_equipment_mng -- 검사 설비 관리
|
|
├── inspection_equipment_mng_log
|
|
defect_standard_mng -- 불량 기준 관리
|
|
├── defect_standard_mng_log
|
|
check_report_mng -- 검사 성적서 관리
|
|
safety_inspections -- 안전 점검
|
|
└── safety_inspections_log
|
|
```
|
|
|
|
### 7.6 물류/운송 관리
|
|
|
|
```
|
|
vehicles -- 차량 정보
|
|
├── vehicle_locations -- 차량 위치
|
|
├── vehicle_location_history -- 차량 위치 이력
|
|
├── vehicle_trip_summary -- 차량 운행 요약
|
|
drivers -- 운전자 정보
|
|
transport_logs -- 운송 로그
|
|
transport_statistics -- 운송 통계
|
|
transport_vehicle_locations -- 차량 위치
|
|
|
|
carrier_mng -- 운송사 관리
|
|
├── carrier_mng_log
|
|
├── carrier_contract_mng -- 운송사 계약
|
|
├── carrier_contract_mng_log
|
|
├── carrier_vehicle_mng -- 운송사 차량
|
|
└── carrier_vehicle_mng_log
|
|
|
|
delivery_route_mng -- 배송 경로 관리
|
|
├── delivery_route_mng_log
|
|
delivery_destination -- 배송지
|
|
delivery_status -- 배송 상태
|
|
delivery_history -- 배송 이력
|
|
├── delivery_history_defect -- 배송 불량
|
|
delivery_part_price -- 배송 부품 가격
|
|
```
|
|
|
|
#### DTG 관리 (디지털 타코그래프)
|
|
|
|
```
|
|
dtg_management -- DTG 관리
|
|
├── dtg_management_log
|
|
dtg_contracts -- DTG 계약
|
|
dtg_maintenance_history -- DTG 정비 이력
|
|
dtg_monthly_settlements -- DTG 월별 정산
|
|
```
|
|
|
|
### 7.7 PLM/설계 관리
|
|
|
|
```
|
|
part_mng -- 부품 관리 (메인)
|
|
├── part_mng_history
|
|
part_mgmt -- 부품 관리 (서브)
|
|
part_bom_qty -- 부품 BOM 수량
|
|
part_bom_report -- 부품 BOM 리포트
|
|
part_distribution_list -- 부품 배포 목록
|
|
|
|
item_info -- 품목 정보
|
|
item_routing_version -- 품목 라우팅 버전
|
|
item_routing_detail -- 품목 라우팅 상세
|
|
|
|
product_mng -- 제품 관리
|
|
product_mgmt -- 제품 관리 (메인)
|
|
├── product_mgmt_model -- 제품 모델
|
|
├── product_mgmt_price_history -- 제품 가격 이력
|
|
├── product_mgmt_upg_master -- 제품 업그레이드 마스터
|
|
└── product_mgmt_upg_detail -- 제품 업그레이드 상세
|
|
|
|
product_kind_spec -- 제품 종류 사양
|
|
product_kind_spec_main -- 제품 종류 사양 메인
|
|
product_spec -- 제품 사양
|
|
product_group_mng -- 제품 그룹 관리
|
|
|
|
mold_dev_request_info -- 금형 개발 요청
|
|
structural_review_proposal -- 구조 검토 제안
|
|
```
|
|
|
|
### 7.8 프로젝트 관리 (PMS)
|
|
|
|
```
|
|
pms_pjt_info -- 프로젝트 정보
|
|
├── pms_pjt_concept_info -- 프로젝트 개념 정보
|
|
├── pms_pjt_year_goal -- 프로젝트 연도 목표
|
|
pms_wbs_task -- WBS 작업
|
|
├── pms_wbs_task_info -- WBS 작업 정보
|
|
├── pms_wbs_task_confirm -- WBS 작업 확인
|
|
├── pms_wbs_task_standard -- WBS 작업 표준
|
|
└── pms_wbs_template -- WBS 템플릿
|
|
|
|
pms_rel_pjt_concept_milestone -- 프로젝트 개념-마일스톤 관계
|
|
pms_rel_pjt_concept_prod -- 프로젝트 개념-제품 관계
|
|
pms_rel_pjt_prod -- 프로젝트-제품 관계
|
|
pms_rel_prod_ref_dept -- 제품-참조부서 관계
|
|
|
|
pms_invest_cost_mng -- 투자 비용 관리
|
|
project_mgmt -- 프로젝트 관리
|
|
problem_mng -- 문제 관리
|
|
planning_issue -- 계획 이슈
|
|
```
|
|
|
|
### 7.9 회계/원가 관리
|
|
|
|
```
|
|
tax_invoice -- 세금계산서
|
|
├── tax_invoice_item -- 세금계산서 항목
|
|
fund_mgmt -- 자금 관리
|
|
expense_master -- 비용 마스터
|
|
├── expense_detail -- 비용 상세
|
|
|
|
profit_loss -- 손익 계산
|
|
├── profit_loss_total -- 손익 합계
|
|
├── profit_loss_coefficient -- 손익 계수
|
|
├── profit_loss_machine -- 손익 기계
|
|
├── profit_loss_weight -- 손익 무게
|
|
├── profit_loss_depth -- 손익 깊이
|
|
├── profit_loss_pretime -- 손익 사전 시간
|
|
├── profit_loss_coolingtime -- 손익 냉각 시간
|
|
├── profit_loss_lossrate -- 손익 손실률
|
|
└── profit_loss_srrate -- 손익 SR률
|
|
|
|
material_cost -- 자재 비용
|
|
injection_cost -- 사출 비용
|
|
logistics_cost_mng -- 물류 비용 관리
|
|
└── logistics_cost_mng_log
|
|
|
|
input_cost_goal -- 투입 비용 목표
|
|
input_resource -- 투입 자원
|
|
```
|
|
|
|
### 7.10 고객/협력사 관리
|
|
|
|
```
|
|
customer_mng -- 고객 관리
|
|
customer_item -- 고객 품목
|
|
├── customer_item_alias -- 고객 품목 별칭
|
|
├── customer_item_mapping -- 고객 품목 매핑
|
|
└── customer_item_price -- 고객 품목 가격
|
|
|
|
customer_service_mgmt -- 고객 서비스 관리
|
|
├── customer_service_part -- 고객 서비스 부품
|
|
└── customer_service_workingtime -- 고객 서비스 작업시간
|
|
|
|
oem_mng -- OEM 관리
|
|
├── oem_factory_mng -- OEM 공장 관리
|
|
└── oem_milestone_mng -- OEM 마일스톤 관리
|
|
```
|
|
|
|
### 7.11 설비/장비 관리
|
|
|
|
```
|
|
equipment_mng -- 설비 관리
|
|
├── equipment_mng_log
|
|
equipment_consumable -- 설비 소모품
|
|
├── equipment_consumable_log
|
|
equipment_inspection_item -- 설비 검사 항목
|
|
└── equipment_inspection_item_log
|
|
|
|
process_equipment -- 공정 설비
|
|
process_mng -- 공정 관리
|
|
maintenance_schedules -- 정비 일정
|
|
```
|
|
|
|
### 7.12 기타
|
|
|
|
```
|
|
approval -- 결재
|
|
comments -- 댓글
|
|
inboxtask -- 수신함 작업
|
|
time_sheet -- 작업 시간
|
|
attach_file_info -- 첨부 파일
|
|
file_down_log -- 파일 다운로드 로그
|
|
login_access_log -- 로그인 접근 로그
|
|
```
|
|
|
|
---
|
|
|
|
## 8. 플로우 및 데이터 통합
|
|
|
|
### 8.1 플로우 정의
|
|
|
|
#### flow_definition (플로우 정의)
|
|
|
|
```sql
|
|
CREATE TABLE flow_definition (
|
|
flow_id SERIAL PRIMARY KEY,
|
|
flow_name VARCHAR(200) NOT NULL,
|
|
flow_code VARCHAR(100) NOT NULL,
|
|
flow_type VARCHAR(50), -- data_transfer, approval, batch 등
|
|
description TEXT,
|
|
trigger_type VARCHAR(50), -- manual, schedule, event
|
|
trigger_config JSONB,
|
|
is_active VARCHAR(1) DEFAULT 'Y',
|
|
company_code VARCHAR(20),
|
|
created_date TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_date TIMESTAMPTZ DEFAULT NOW(),
|
|
created_by VARCHAR(50),
|
|
updated_by VARCHAR(50),
|
|
|
|
UNIQUE(flow_code, company_code)
|
|
);
|
|
```
|
|
|
|
#### flow_step (플로우 단계)
|
|
|
|
```sql
|
|
CREATE TABLE flow_step (
|
|
step_id SERIAL PRIMARY KEY,
|
|
flow_id INTEGER REFERENCES flow_definition(flow_id) ON DELETE CASCADE,
|
|
step_name VARCHAR(200) NOT NULL,
|
|
step_type VARCHAR(50) NOT NULL, -- query, transform, api_call, condition 등
|
|
step_order INTEGER NOT NULL,
|
|
step_config JSONB NOT NULL,
|
|
error_handling_config JSONB,
|
|
is_active VARCHAR(1) DEFAULT 'Y',
|
|
company_code VARCHAR(20),
|
|
created_date TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_date TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
```
|
|
|
|
#### flow_step_connection (플로우 단계 연결)
|
|
|
|
```sql
|
|
CREATE TABLE flow_step_connection (
|
|
connection_id SERIAL PRIMARY KEY,
|
|
flow_id INTEGER REFERENCES flow_definition(flow_id) ON DELETE CASCADE,
|
|
source_step_id INTEGER REFERENCES flow_step(step_id) ON DELETE CASCADE,
|
|
target_step_id INTEGER REFERENCES flow_step(step_id) ON DELETE CASCADE,
|
|
condition_expression TEXT, -- 조건부 실행
|
|
connection_type VARCHAR(20) DEFAULT 'sequential', -- sequential, parallel, conditional
|
|
company_code VARCHAR(20),
|
|
created_date TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
```
|
|
|
|
### 8.2 데이터플로우
|
|
|
|
#### dataflow_diagrams (데이터플로우 다이어그램)
|
|
|
|
```sql
|
|
CREATE TABLE dataflow_diagrams (
|
|
diagram_id SERIAL PRIMARY KEY,
|
|
diagram_name VARCHAR(200) NOT NULL,
|
|
diagram_type VARCHAR(50),
|
|
diagram_json JSONB NOT NULL, -- 다이어그램 시각화 정보
|
|
description TEXT,
|
|
is_active VARCHAR(1) DEFAULT 'Y',
|
|
company_code VARCHAR(20),
|
|
created_date TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_date TIMESTAMPTZ DEFAULT NOW(),
|
|
created_by VARCHAR(50),
|
|
updated_by VARCHAR(50)
|
|
);
|
|
```
|
|
|
|
#### flow_data_mapping (플로우 데이터 매핑)
|
|
|
|
```sql
|
|
CREATE TABLE flow_data_mapping (
|
|
mapping_id SERIAL PRIMARY KEY,
|
|
flow_id INTEGER REFERENCES flow_definition(flow_id) ON DELETE CASCADE,
|
|
source_type VARCHAR(20), -- table, api, flow
|
|
source_identifier VARCHAR(200), -- 테이블명 또는 API 엔드포인트
|
|
source_field VARCHAR(100),
|
|
target_type VARCHAR(20),
|
|
target_identifier VARCHAR(200),
|
|
target_field VARCHAR(100),
|
|
transformation_rule TEXT, -- 변환 규칙 (JavaScript 표현식)
|
|
company_code VARCHAR(20),
|
|
created_date TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
```
|
|
|
|
#### flow_data_status (플로우 데이터 상태)
|
|
|
|
```sql
|
|
CREATE TABLE flow_data_status (
|
|
status_id SERIAL PRIMARY KEY,
|
|
flow_id INTEGER REFERENCES flow_definition(flow_id),
|
|
execution_id VARCHAR(100),
|
|
source_table VARCHAR(100),
|
|
source_record_id VARCHAR(500),
|
|
target_table VARCHAR(100),
|
|
target_record_id VARCHAR(500),
|
|
status VARCHAR(20), -- pending, processing, completed, failed
|
|
error_message TEXT,
|
|
processed_at TIMESTAMPTZ,
|
|
company_code VARCHAR(20),
|
|
created_date TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
```
|
|
|
|
### 8.3 외부 연동
|
|
|
|
#### external_db_connections (외부 DB 연결)
|
|
|
|
```sql
|
|
CREATE TABLE external_db_connections (
|
|
id SERIAL PRIMARY KEY,
|
|
connection_name VARCHAR(200) NOT NULL,
|
|
connection_code VARCHAR(100) NOT NULL,
|
|
db_type VARCHAR(50) NOT NULL, -- postgresql, mysql, mssql, oracle
|
|
host VARCHAR(255) NOT NULL,
|
|
port INTEGER NOT NULL,
|
|
database_name VARCHAR(100) NOT NULL,
|
|
username VARCHAR(100),
|
|
password_encrypted TEXT,
|
|
ssl_enabled BOOLEAN DEFAULT false,
|
|
connection_options JSONB,
|
|
is_active VARCHAR(1) DEFAULT 'Y',
|
|
company_code VARCHAR(20),
|
|
created_date TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_date TIMESTAMPTZ DEFAULT NOW(),
|
|
created_by VARCHAR(50),
|
|
|
|
UNIQUE(connection_code, company_code)
|
|
);
|
|
```
|
|
|
|
#### external_rest_api_connections (외부 REST API 연결)
|
|
|
|
```sql
|
|
CREATE TABLE external_rest_api_connections (
|
|
id SERIAL PRIMARY KEY,
|
|
connection_name VARCHAR(200) NOT NULL,
|
|
connection_code VARCHAR(100) NOT NULL,
|
|
base_url VARCHAR(500) NOT NULL,
|
|
auth_type VARCHAR(50), -- none, basic, bearer, api_key
|
|
auth_config JSONB,
|
|
default_headers JSONB,
|
|
timeout_seconds INTEGER DEFAULT 30,
|
|
retry_count INTEGER DEFAULT 0,
|
|
is_active VARCHAR(1) DEFAULT 'Y',
|
|
company_code VARCHAR(20),
|
|
created_date TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_date TIMESTAMPTZ DEFAULT NOW(),
|
|
|
|
UNIQUE(connection_code, company_code)
|
|
);
|
|
```
|
|
|
|
#### external_call_configs (외부 호출 설정)
|
|
|
|
```sql
|
|
CREATE TABLE external_call_configs (
|
|
id SERIAL PRIMARY KEY,
|
|
config_name VARCHAR(200) NOT NULL,
|
|
config_code VARCHAR(100) NOT NULL,
|
|
connection_id INTEGER, -- external_rest_api_connections 참조
|
|
http_method VARCHAR(10), -- GET, POST, PUT, DELETE
|
|
endpoint_path VARCHAR(500),
|
|
request_mapping JSONB, -- 요청 데이터 매핑
|
|
response_mapping JSONB, -- 응답 데이터 매핑
|
|
error_handling JSONB,
|
|
is_active VARCHAR(1) DEFAULT 'Y',
|
|
company_code VARCHAR(20),
|
|
created_date TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_date TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
```
|
|
|
|
### 8.4 배치 작업
|
|
|
|
#### batch_jobs (배치 작업 정의)
|
|
|
|
```sql
|
|
CREATE TABLE batch_jobs (
|
|
job_id SERIAL PRIMARY KEY,
|
|
job_name VARCHAR(200) NOT NULL,
|
|
job_code VARCHAR(100) NOT NULL,
|
|
job_type VARCHAR(50), -- data_collection, aggregation, sync 등
|
|
source_type VARCHAR(50), -- database, api, file
|
|
source_config JSONB,
|
|
target_config JSONB,
|
|
schedule_config JSONB,
|
|
is_active VARCHAR(1) DEFAULT 'Y',
|
|
company_code VARCHAR(20),
|
|
created_date TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_date TIMESTAMPTZ DEFAULT NOW(),
|
|
|
|
UNIQUE(job_code, company_code)
|
|
);
|
|
```
|
|
|
|
#### batch_execution_logs (배치 실행 로그)
|
|
|
|
```sql
|
|
CREATE TABLE batch_execution_logs (
|
|
execution_id SERIAL PRIMARY KEY,
|
|
job_id INTEGER REFERENCES batch_jobs(job_id),
|
|
execution_status VARCHAR(20), -- running, completed, failed
|
|
start_time TIMESTAMPTZ,
|
|
end_time TIMESTAMPTZ,
|
|
records_processed INTEGER,
|
|
records_failed INTEGER,
|
|
error_message TEXT,
|
|
execution_details JSONB,
|
|
company_code VARCHAR(20),
|
|
created_date TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
```
|
|
|
|
---
|
|
|
|
## 9. 인덱스 전략
|
|
|
|
### 9.1 필수 인덱스
|
|
|
|
**모든 테이블에 적용:**
|
|
|
|
```sql
|
|
-- company_code 인덱스 (멀티테넌시 성능)
|
|
CREATE INDEX idx_{table_name}_company_code ON {table_name}(company_code);
|
|
|
|
-- 복합 인덱스 (company_code + 주요 검색 컬럼)
|
|
CREATE INDEX idx_{table_name}_company_{column}
|
|
ON {table_name}(company_code, {column});
|
|
```
|
|
|
|
### 9.2 화면 관련 인덱스
|
|
|
|
```sql
|
|
-- screen_definitions
|
|
CREATE INDEX idx_screen_definitions_company_code ON screen_definitions(company_code);
|
|
CREATE INDEX idx_screen_definitions_table_name ON screen_definitions(table_name);
|
|
CREATE INDEX idx_screen_definitions_is_active ON screen_definitions(is_active);
|
|
CREATE UNIQUE INDEX idx_screen_definitions_code_company
|
|
ON screen_definitions(screen_code, company_code);
|
|
|
|
-- screen_groups
|
|
CREATE INDEX idx_screen_groups_company_code ON screen_groups(company_code);
|
|
CREATE INDEX idx_screen_groups_parent_id ON screen_groups(parent_group_id);
|
|
CREATE INDEX idx_screen_groups_hierarchy_path ON screen_groups(hierarchy_path);
|
|
|
|
-- screen_field_joins
|
|
CREATE INDEX idx_screen_field_joins_screen_id ON screen_field_joins(screen_id);
|
|
CREATE INDEX idx_screen_field_joins_save_table ON screen_field_joins(save_table);
|
|
CREATE INDEX idx_screen_field_joins_join_table ON screen_field_joins(join_table);
|
|
```
|
|
|
|
### 9.3 메타데이터 인덱스
|
|
|
|
```sql
|
|
-- table_type_columns
|
|
CREATE UNIQUE INDEX idx_table_type_columns_unique
|
|
ON table_type_columns(table_name, column_name, company_code);
|
|
|
|
-- column_labels
|
|
CREATE INDEX idx_column_labels_table ON column_labels(table_name);
|
|
```
|
|
|
|
### 9.4 비즈니스 테이블 인덱스 예시
|
|
|
|
```sql
|
|
-- sales_order_mng
|
|
CREATE INDEX idx_sales_order_company_code ON sales_order_mng(company_code);
|
|
CREATE INDEX idx_sales_order_customer ON sales_order_mng(customer_code);
|
|
CREATE INDEX idx_sales_order_date ON sales_order_mng(order_date DESC);
|
|
CREATE INDEX idx_sales_order_status ON sales_order_mng(order_status);
|
|
|
|
-- work_orders
|
|
CREATE INDEX idx_work_orders_company_code ON work_orders(company_code);
|
|
CREATE INDEX idx_work_orders_wo_number ON work_orders(wo_number);
|
|
CREATE INDEX idx_work_orders_start_date ON work_orders(start_date);
|
|
CREATE INDEX idx_work_orders_product_code ON work_orders(product_code);
|
|
```
|
|
|
|
### 9.5 플로우 관련 인덱스
|
|
|
|
```sql
|
|
-- flow_definition
|
|
CREATE UNIQUE INDEX idx_flow_definition_code_company
|
|
ON flow_definition(flow_code, company_code);
|
|
|
|
-- flow_step
|
|
CREATE INDEX idx_flow_step_flow_id ON flow_step(flow_id);
|
|
CREATE INDEX idx_flow_step_order ON flow_step(flow_id, step_order);
|
|
|
|
-- flow_data_status
|
|
CREATE INDEX idx_flow_data_status_flow_execution
|
|
ON flow_data_status(flow_id, execution_id);
|
|
CREATE INDEX idx_flow_data_status_source
|
|
ON flow_data_status(source_table, source_record_id);
|
|
```
|
|
|
|
---
|
|
|
|
## 10. 동적 테이블 생성 패턴
|
|
|
|
WACE ERP의 핵심 기능 중 하나는 **런타임에 테이블을 동적으로 생성**할 수 있다는 것입니다.
|
|
|
|
### 10.1 표준 컬럼 구조
|
|
|
|
**모든 동적 생성 테이블의 기본 컬럼:**
|
|
|
|
```sql
|
|
CREATE TABLE {dynamic_table_name} (
|
|
-- 시스템 기본 컬럼 (자동 포함)
|
|
id VARCHAR(500) PRIMARY KEY DEFAULT gen_random_uuid()::text,
|
|
created_date TIMESTAMP DEFAULT NOW(),
|
|
updated_date TIMESTAMP DEFAULT NOW(),
|
|
writer VARCHAR(500),
|
|
company_code VARCHAR(500),
|
|
|
|
-- 사용자 정의 컬럼 (모두 VARCHAR(500))
|
|
{user_column_1} VARCHAR(500),
|
|
{user_column_2} VARCHAR(500),
|
|
...
|
|
);
|
|
|
|
-- 필수 인덱스
|
|
CREATE INDEX idx_{table_name}_company_code ON {table_name}(company_code);
|
|
```
|
|
|
|
### 10.2 메타데이터 등록 프로세스
|
|
|
|
동적 테이블 생성 시 반드시 수행해야 하는 작업:
|
|
|
|
#### 1단계: 테이블 생성
|
|
|
|
```sql
|
|
CREATE TABLE {table_name} (
|
|
-- 위의 표준 구조 참조
|
|
);
|
|
```
|
|
|
|
#### 2단계: table_labels 등록
|
|
|
|
```sql
|
|
INSERT INTO table_labels (table_name, table_label, description, created_date, updated_date)
|
|
VALUES ('{table_name}', '{한글명}', '{설명}', NOW(), NOW())
|
|
ON CONFLICT (table_name)
|
|
DO UPDATE SET
|
|
table_label = EXCLUDED.table_label,
|
|
description = EXCLUDED.description,
|
|
updated_date = NOW();
|
|
```
|
|
|
|
#### 3단계: table_type_columns 등록
|
|
|
|
```sql
|
|
-- 기본 컬럼 등록 (display_order: -5 ~ -1)
|
|
INSERT INTO table_type_columns (
|
|
table_name, column_name, company_code, input_type, detail_settings,
|
|
is_nullable, display_order, created_date, updated_date
|
|
) VALUES
|
|
('{table_name}', 'id', '{company_code}', 'text', '{}', 'Y', -5, NOW(), NOW()),
|
|
('{table_name}', 'created_date', '{company_code}', 'date', '{}', 'Y', -4, NOW(), NOW()),
|
|
('{table_name}', 'updated_date', '{company_code}', 'date', '{}', 'Y', -3, NOW(), NOW()),
|
|
('{table_name}', 'writer', '{company_code}', 'text', '{}', 'Y', -2, NOW(), NOW()),
|
|
('{table_name}', 'company_code', '{company_code}', 'text', '{}', 'Y', -1, NOW(), NOW())
|
|
ON CONFLICT (table_name, column_name, company_code)
|
|
DO UPDATE SET
|
|
input_type = EXCLUDED.input_type,
|
|
display_order = EXCLUDED.display_order,
|
|
updated_date = NOW();
|
|
|
|
-- 사용자 정의 컬럼 등록 (display_order: 0부터 시작)
|
|
INSERT INTO table_type_columns (
|
|
table_name, column_name, company_code, input_type, detail_settings,
|
|
is_nullable, display_order, created_date, updated_date
|
|
) VALUES
|
|
('{table_name}', '{column_1}', '{company_code}', 'text', '{}', 'Y', 0, NOW(), NOW()),
|
|
('{table_name}', '{column_2}', '{company_code}', 'number', '{}', 'Y', 1, NOW(), NOW()),
|
|
...
|
|
```
|
|
|
|
#### 4단계: column_labels 등록 (레거시 호환용)
|
|
|
|
```sql
|
|
INSERT INTO column_labels (
|
|
table_name, column_name, column_label, input_type, detail_settings,
|
|
description, display_order, is_visible, created_date, updated_date
|
|
) VALUES
|
|
('{table_name}', 'id', 'ID', 'text', '{}', '기본키', -5, true, NOW(), NOW()),
|
|
...
|
|
ON CONFLICT (table_name, column_name)
|
|
DO UPDATE SET
|
|
column_label = EXCLUDED.column_label,
|
|
input_type = EXCLUDED.input_type,
|
|
updated_date = NOW();
|
|
```
|
|
|
|
### 10.3 마이그레이션 예시
|
|
|
|
**050_create_work_orders_table.sql:**
|
|
|
|
```sql
|
|
-- ============================================
|
|
-- 1. 테이블 생성
|
|
-- ============================================
|
|
CREATE TABLE work_orders (
|
|
id VARCHAR(500) PRIMARY KEY DEFAULT gen_random_uuid()::text,
|
|
created_date TIMESTAMP DEFAULT NOW(),
|
|
updated_date TIMESTAMP DEFAULT NOW(),
|
|
writer VARCHAR(500),
|
|
company_code VARCHAR(500),
|
|
|
|
wo_number VARCHAR(500),
|
|
product_code VARCHAR(500),
|
|
product_name VARCHAR(500),
|
|
...
|
|
);
|
|
|
|
CREATE INDEX idx_work_orders_company_code ON work_orders(company_code);
|
|
CREATE INDEX idx_work_orders_wo_number ON work_orders(wo_number);
|
|
|
|
-- ============================================
|
|
-- 2. table_labels 등록
|
|
-- ============================================
|
|
INSERT INTO table_labels (table_name, table_label, description, created_date, updated_date)
|
|
VALUES ('work_orders', '작업지시', '작업지시 관리 테이블', NOW(), NOW())
|
|
ON CONFLICT (table_name) DO UPDATE SET ...;
|
|
|
|
-- ============================================
|
|
-- 3. table_type_columns 등록
|
|
-- ============================================
|
|
INSERT INTO table_type_columns (...) VALUES (...);
|
|
|
|
-- ============================================
|
|
-- 4. column_labels 등록
|
|
-- ============================================
|
|
INSERT INTO column_labels (...) VALUES (...);
|
|
|
|
-- ============================================
|
|
-- 5. 코멘트 추가
|
|
-- ============================================
|
|
COMMENT ON TABLE work_orders IS '작업지시 관리 테이블';
|
|
COMMENT ON COLUMN work_orders.wo_number IS '작업지시번호 (WO-YYYYMMDD-XXX)';
|
|
```
|
|
|
|
---
|
|
|
|
## 11. 마이그레이션 히스토리
|
|
|
|
### 11.1 마이그레이션 파일 목록
|
|
|
|
```
|
|
db/migrations/
|
|
├── 037_add_parent_group_to_screen_groups.sql -- 화면 그룹 계층 구조
|
|
├── 050_create_work_orders_table.sql -- 작업지시 테이블
|
|
├── 051_insert_work_order_screen_definition.sql -- 작업지시 화면 정의
|
|
├── 052_insert_work_order_screen_layout.sql -- 작업지시 화면 레이아웃
|
|
├── 054_create_screen_management_enhancement.sql -- 화면 관리 기능 확장
|
|
└── plm_schema_20260120.sql -- 전체 스키마 덤프
|
|
```
|
|
|
|
### 11.2 주요 마이그레이션 내용
|
|
|
|
#### 037: 화면 그룹 계층 구조
|
|
|
|
- `screen_groups`에 계층 구조 지원 추가
|
|
- `parent_group_id`, `group_level`, `hierarchy_path` 컬럼 추가
|
|
- 대/중/소 분류 지원
|
|
|
|
#### 050~052: 작업지시 시스템
|
|
|
|
- `work_orders` 테이블 생성
|
|
- 메타데이터 등록 (table_labels, table_type_columns, column_labels)
|
|
- 화면 정의 및 레이아웃 생성
|
|
|
|
#### 054: 화면 관리 기능 확장
|
|
|
|
- `screen_groups`: 화면 그룹
|
|
- `screen_group_screens`: 화면-그룹 연결
|
|
- `screen_field_joins`: 화면 필드 조인 설정
|
|
- `screen_data_flows`: 화면 간 데이터 흐름
|
|
- `screen_table_relations`: 화면-테이블 관계
|
|
|
|
### 11.3 마이그레이션 실행 가이드
|
|
|
|
**마이그레이션 문서:**
|
|
- `RUN_027_MIGRATION.md`
|
|
- `RUN_043_MIGRATION.md`
|
|
- `RUN_044_MIGRATION.md`
|
|
- `RUN_046_MIGRATION.md`
|
|
- `RUN_063_064_MIGRATION.md`
|
|
- `RUN_065_MIGRATION.md`
|
|
- `RUN_078_MIGRATION.md`
|
|
|
|
---
|
|
|
|
## 12. 데이터베이스 함수 및 트리거
|
|
|
|
### 12.1 주요 함수
|
|
|
|
#### 화면 관련
|
|
|
|
```sql
|
|
-- 화면 생성 시 메뉴 자동 생성
|
|
CREATE FUNCTION auto_create_menu_for_screen() RETURNS TRIGGER;
|
|
|
|
-- 화면 삭제 시 메뉴 비활성화
|
|
CREATE FUNCTION auto_deactivate_menu_for_screen() RETURNS TRIGGER;
|
|
```
|
|
|
|
#### 통계 집계
|
|
|
|
```sql
|
|
-- 일일 운송 통계 집계
|
|
CREATE FUNCTION aggregate_daily_transport_statistics(target_date DATE) RETURNS INTEGER;
|
|
```
|
|
|
|
#### 거리 계산
|
|
|
|
```sql
|
|
-- Haversine 거리 계산
|
|
CREATE FUNCTION calculate_distance(lat1 NUMERIC, lng1 NUMERIC, lat2 NUMERIC, lng2 NUMERIC)
|
|
RETURNS NUMERIC;
|
|
|
|
-- 이전 위치로부터 거리 계산
|
|
CREATE FUNCTION calculate_distance_from_prev() RETURNS TRIGGER;
|
|
```
|
|
|
|
#### 비즈니스 로직
|
|
|
|
```sql
|
|
-- 수주 잔량 계산
|
|
CREATE FUNCTION calculate_order_balance() RETURNS TRIGGER;
|
|
|
|
-- 세금계산서 합계 계산
|
|
CREATE FUNCTION calculate_tax_invoice_total() RETURNS TRIGGER;
|
|
|
|
-- 영업에서 프로젝트 자동 생성
|
|
CREATE FUNCTION auto_create_project_from_sales(p_sales_no VARCHAR) RETURNS VARCHAR;
|
|
```
|
|
|
|
#### 로그 관리
|
|
|
|
```sql
|
|
-- 테이블 변경 로그 트리거 함수
|
|
CREATE FUNCTION carrier_contract_mng_log_trigger_func() RETURNS TRIGGER;
|
|
CREATE FUNCTION carrier_mng_log_trigger_func() RETURNS TRIGGER;
|
|
-- ... 각 테이블별 로그 트리거 함수
|
|
```
|
|
|
|
### 12.2 주요 트리거
|
|
|
|
```sql
|
|
-- 화면 생성 시 메뉴 자동 생성
|
|
CREATE TRIGGER trg_auto_create_menu_for_screen
|
|
AFTER INSERT ON screen_definitions
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION auto_create_menu_for_screen();
|
|
|
|
-- 화면 삭제 시 메뉴 비활성화
|
|
CREATE TRIGGER trg_auto_deactivate_menu_for_screen
|
|
AFTER UPDATE ON screen_definitions
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION auto_deactivate_menu_for_screen();
|
|
|
|
-- 차량 위치 이력 거리 계산
|
|
CREATE TRIGGER trg_calculate_distance_from_prev
|
|
BEFORE INSERT ON vehicle_location_history
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION calculate_distance_from_prev();
|
|
```
|
|
|
|
---
|
|
|
|
## 13. 뷰 (Views)
|
|
|
|
### 13.1 시스템 뷰
|
|
|
|
```sql
|
|
-- 권한 그룹 요약
|
|
CREATE VIEW v_authority_group_summary AS
|
|
SELECT
|
|
am.objid,
|
|
am.auth_name,
|
|
am.auth_code,
|
|
am.company_code,
|
|
(SELECT COUNT(*) FROM authority_sub_user WHERE master_objid = am.objid) AS member_count,
|
|
(SELECT COUNT(*) FROM rel_menu_auth WHERE auth_objid = am.objid) AS menu_count
|
|
FROM authority_master am;
|
|
```
|
|
|
|
---
|
|
|
|
## 14. 데이터베이스 보안 및 암호화
|
|
|
|
### 14.1 암호화 컬럼
|
|
|
|
```sql
|
|
-- external_db_connections
|
|
password_encrypted TEXT -- AES 암호화된 비밀번호
|
|
|
|
-- external_rest_api_connections
|
|
auth_config JSONB -- 암호화된 인증 정보
|
|
```
|
|
|
|
### 14.2 접근 제어
|
|
|
|
- PostgreSQL 롤 기반 접근 제어
|
|
- 회사별 데이터 격리 (company_code)
|
|
- 사용자별 권한 관리 (authority_master, rel_menu_auth)
|
|
|
|
---
|
|
|
|
## 15. 성능 최적화 전략
|
|
|
|
### 15.1 인덱스 최적화
|
|
|
|
- **company_code 인덱스**: 모든 테이블에 필수
|
|
- **복합 인덱스**: 자주 함께 조회되는 컬럼 조합
|
|
- **부분 인덱스**: 특정 조건의 데이터만 인덱싱
|
|
|
|
### 15.2 쿼리 최적화
|
|
|
|
- **서브쿼리 최소화**: JOIN으로 대체
|
|
- **EXPLAIN ANALYZE** 활용
|
|
- **인덱스 힌트** 사용
|
|
|
|
### 15.3 캐싱 전략
|
|
|
|
- **참조 데이터 캐싱**: referenceCacheService.ts
|
|
- **Redis 캐싱**: 자주 조회되는 메타데이터
|
|
|
|
### 15.4 파티셔닝
|
|
|
|
- 대용량 이력 테이블 파티셔닝 고려
|
|
- 날짜 기반 파티셔닝 (vehicle_location_history 등)
|
|
|
|
---
|
|
|
|
## 16. 백업 및 복구
|
|
|
|
### 16.1 백업 전략
|
|
|
|
```bash
|
|
# 전체 스키마 백업
|
|
pg_dump -h host -U user -d database > plm_schema_YYYYMMDD.sql
|
|
|
|
# 데이터 포함 백업
|
|
pg_dump -h host -U user -d database --data-only > data_YYYYMMDD.sql
|
|
|
|
# 특정 테이블 백업
|
|
pg_dump -h host -U user -d database -t table_name > table_backup.sql
|
|
```
|
|
|
|
### 16.2 마이그레이션 롤백
|
|
|
|
- DDL 작업 전 백업 필수
|
|
- 트랜잭션 기반 마이그레이션
|
|
- 롤백 스크립트 준비
|
|
|
|
---
|
|
|
|
## 17. 모니터링 및 로깅
|
|
|
|
### 17.1 시스템 로그 테이블
|
|
|
|
```
|
|
login_access_log -- 로그인 접근 로그
|
|
ddl_execution_log -- DDL 실행 로그
|
|
batch_execution_logs -- 배치 실행 로그
|
|
flow_audit_log -- 플로우 감사 로그
|
|
flow_integration_log -- 플로우 통합 로그
|
|
external_call_logs -- 외부 호출 로그
|
|
mail_log -- 메일 발송 로그
|
|
file_down_log -- 파일 다운로드 로그
|
|
```
|
|
|
|
### 17.2 변경 이력 테이블
|
|
|
|
**패턴:** `{원본테이블}_log` 또는 `{원본테이블}_history`
|
|
|
|
```
|
|
user_info_history
|
|
dept_info_history
|
|
authority_master_history
|
|
comm_code_history
|
|
carrier_mng_log
|
|
supplier_mng_log
|
|
equipment_mng_log
|
|
...
|
|
```
|
|
|
|
---
|
|
|
|
## 18. 결론
|
|
|
|
### 18.1 핵심 아키텍처 특징
|
|
|
|
1. **멀티테넌시**: company_code로 완벽한 데이터 격리
|
|
2. **메타데이터 드리븐**: 동적 화면/테이블 생성
|
|
3. **Low-Code 플랫폼**: 코드 없이 화면 구축
|
|
4. **플로우 기반**: 시각적 데이터 흐름 설계
|
|
5. **외부 연동**: DB/API 통합 지원
|
|
6. **이력 관리**: 완벽한 변경 이력 추적
|
|
|
|
### 18.2 확장성
|
|
|
|
- **수평 확장**: 멀티테넌시로 무한한 회사 추가 가능
|
|
- **수직 확장**: 동적 테이블/컬럼 추가
|
|
- **기능 확장**: 플로우/배치 작업으로 비즈니스 로직 추가
|
|
|
|
### 18.3 유지보수성
|
|
|
|
- **표준화된 구조**: 모든 테이블이 동일한 패턴
|
|
- **자동화**: 트리거/함수로 반복 작업 자동화
|
|
- **문서화**: 메타데이터 테이블 자체가 문서
|
|
|
|
---
|
|
|
|
## 부록 A: 백엔드 서비스 매핑
|
|
|
|
### 주요 서비스와 테이블 매핑
|
|
|
|
```typescript
|
|
// backend-node/src/services/
|
|
|
|
screenManagementService.ts → screen_definitions, screen_layouts
|
|
tableManagementService.ts → table_labels, table_type_columns, column_labels
|
|
menuService.ts → menu_info, menu_screen_groups
|
|
categoryTreeService.ts → table_column_category_values
|
|
flowDefinitionService.ts → flow_definition, flow_step
|
|
flowExecutionService.ts → flow_data_status, flow_audit_log
|
|
dataflowService.ts → dataflow_diagrams, screen_data_flows
|
|
externalDbConnectionService.ts → external_db_connections
|
|
externalRestApiConnectionService.ts → external_rest_api_connections
|
|
batchService.ts → batch_jobs, batch_execution_logs
|
|
authService.ts → user_info, auth_tokens
|
|
roleService.ts → authority_master, rel_menu_auth
|
|
```
|
|
|
|
---
|
|
|
|
## 부록 B: SQL 쿼리 예시
|
|
|
|
### 멀티테넌시 표준 쿼리
|
|
|
|
```sql
|
|
-- ✅ 단일 테이블 조회
|
|
SELECT * FROM sales_order_mng
|
|
WHERE company_code = $1
|
|
AND company_code != '*'
|
|
AND order_date >= $2
|
|
ORDER BY order_date DESC
|
|
LIMIT 100;
|
|
|
|
-- ✅ JOIN 쿼리
|
|
SELECT
|
|
so.order_no,
|
|
so.order_date,
|
|
c.customer_name,
|
|
p.product_name,
|
|
so.quantity,
|
|
so.unit_price
|
|
FROM sales_order_mng so
|
|
LEFT JOIN customer_mng c
|
|
ON so.customer_code = c.customer_code
|
|
AND so.company_code = c.company_code
|
|
LEFT JOIN product_mng p
|
|
ON so.product_code = p.product_code
|
|
AND so.company_code = p.company_code
|
|
WHERE so.company_code = $1
|
|
AND so.company_code != '*'
|
|
AND so.order_date BETWEEN $2 AND $3;
|
|
|
|
-- ✅ 집계 쿼리
|
|
SELECT
|
|
customer_code,
|
|
COUNT(*) as order_count,
|
|
SUM(total_amount) as total_sales
|
|
FROM sales_order_mng
|
|
WHERE company_code = $1
|
|
AND company_code != '*'
|
|
AND order_date >= DATE_TRUNC('month', CURRENT_DATE)
|
|
GROUP BY customer_code
|
|
HAVING COUNT(*) >= 5
|
|
ORDER BY total_sales DESC;
|
|
```
|
|
|
|
---
|
|
|
|
## 부록 C: 참고 문서
|
|
|
|
```
|
|
docs/
|
|
├── DDD1542/
|
|
│ ├── DB_STRUCTURE_DIAGRAM.md -- DB 구조 다이어그램
|
|
│ ├── DB_INEFFICIENCY_ANALYSIS.md -- DB 비효율성 분석
|
|
│ ├── COMPONENT_URL_SYSTEM_IMPLEMENTATION.md
|
|
│ ├── V2_마이그레이션_학습노트_DDD1542.md
|
|
│ └── 본서버_개발서버_마이그레이션_가이드.md
|
|
├── backend-architecture-analysis.md -- 백엔드 아키텍처 분석
|
|
└── screen-implementation-guide/ -- 화면 구현 가이드
|
|
```
|
|
|
|
---
|
|
|
|
**문서 작성자**: Cursor AI (DB Specialist Agent)
|
|
**문서 버전**: 1.0
|
|
**마지막 업데이트**: 2026-01-20
|
|
**스키마 버전**: plm_schema_20260120.sql
|
|
|
|
---
|