# 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

---
