- Created a comprehensive analysis document for the backend architecture, detailing the directory structure, API routes, authentication workflows, and more. - Added a database architecture analysis report outlining the database structure, multi-tenancy architecture, and key system tables. - Introduced a frontend architecture analysis document that covers the directory structure, component systems, and Next.js App Router structure. These documents aim to enhance the understanding of the WACE ERP system's architecture and facilitate better workflow documentation.
59 KiB
59 KiB
WACE ERP 데이터베이스 아키텍처 분석 보고서
📅 작성일: 2026-01-20
🎯 목적: WACE ERP 시스템 전체 워크플로우 문서화를 위한 DB 구조 분석
📊 DB 엔진: PostgreSQL 16.8
📋 목차
- 개요
- 전체 테이블 목록
- 멀티테넌시 아키텍처
- 핵심 시스템 테이블
- 메타데이터 관리 시스템
- 화면 관리 시스템
- 비즈니스 도메인별 테이블
- 플로우 및 데이터 통합
- 인덱스 전략
- 동적 테이블 생성 패턴
- 마이그레이션 히스토리
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 주요 테이블 목록 (알파벳순)
전체 테이블 목록 보기 (280개)
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
3. 멀티테넌시 아키텍처
3.1 company_code 패턴
모든 테이블에 필수적으로 포함되는 컬럼:
company_code VARCHAR(20) NOT NULL
의미:
- 하나의 데이터베이스에서 여러 회사의 데이터를 격리
- 모든 쿼리는 반드시
company_code필터 포함 필요
3.2 특별한 company_code 값
company_code = "*" 의미
-- ❌ 잘못된 이해: 모든 회사가 공유하는 공통 데이터
-- ✅ 올바른 이해: 슈퍼 관리자 전용 데이터
-- 일반 회사는 "*" 데이터를 볼 수 없음
SELECT * FROM table_name
WHERE company_code = 'COMPANY_A'
AND company_code != '*'; -- 필수!
용도:
- 시스템 관리자용 메타데이터
- 전역 설정 값
- 기본 템플릿
3.3 멀티테넌시 쿼리 패턴
-- ✅ 표준 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 인덱스 전략
모든 테이블에 필수 인덱스:
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 (사용자 정보)
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 (인증 토큰)
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 (권한 그룹)
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 (메뉴 정보)
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 (회사 정보)
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 (부서 정보)
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 (테이블 정의)
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 (컬럼 타입 정의)
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 예시:
// select 타입
{
"options": [
{"label": "일반", "value": "normal"},
{"label": "긴급", "value": "urgent"}
]
}
// entity 타입
{
"referenceTable": "customer_mng",
"referenceColumn": "customer_code",
"displayColumn": "customer_name"
}
column_labels (컬럼 라벨 - 레거시)
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 (컬럼 카테고리 값)
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 (테이블 관계)
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 (화면 정의)
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)
);
화면 생성 플로우:
- 관리자가 화면 설정 페이지에서 테이블 선택
screen_definitions레코드 생성- 트리거
auto_create_menu_for_screen()실행 →menu_info자동 생성 - 프론트엔드가
/screen/{screen_code}경로로 접근 시 동적 렌더링
screen_layouts (화면 레이아웃 - 레거시)
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 (화면 그룹)
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 (화면-그룹 연결)
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 (화면 필드 조인 설정)
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)
);
예시:
{
"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 (화면 간 데이터 흐름)
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 예시:
{
"customer_code": "customer_code",
"customer_name": "customer_name",
"selected_date": "order_date"
}
screen_table_relations (화면-테이블 관계)
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 (컴포넌트 표준)
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 (레이아웃 표준)
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 마이그레이션)
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 (플로우 정의)
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 (플로우 단계)
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 (플로우 단계 연결)
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 (데이터플로우 다이어그램)
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 (플로우 데이터 매핑)
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 (플로우 데이터 상태)
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 연결)
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 연결)
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 (외부 호출 설정)
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 (배치 작업 정의)
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 (배치 실행 로그)
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 필수 인덱스
모든 테이블에 적용:
-- 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 화면 관련 인덱스
-- 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 메타데이터 인덱스
-- 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 비즈니스 테이블 인덱스 예시
-- 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 플로우 관련 인덱스
-- 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 표준 컬럼 구조
모든 동적 생성 테이블의 기본 컬럼:
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단계: 테이블 생성
CREATE TABLE {table_name} (
-- 위의 표준 구조 참조
);
2단계: table_labels 등록
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 등록
-- 기본 컬럼 등록 (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 등록 (레거시 호환용)
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:
-- ============================================
-- 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.mdRUN_043_MIGRATION.mdRUN_044_MIGRATION.mdRUN_046_MIGRATION.mdRUN_063_064_MIGRATION.mdRUN_065_MIGRATION.mdRUN_078_MIGRATION.md
12. 데이터베이스 함수 및 트리거
12.1 주요 함수
화면 관련
-- 화면 생성 시 메뉴 자동 생성
CREATE FUNCTION auto_create_menu_for_screen() RETURNS TRIGGER;
-- 화면 삭제 시 메뉴 비활성화
CREATE FUNCTION auto_deactivate_menu_for_screen() RETURNS TRIGGER;
통계 집계
-- 일일 운송 통계 집계
CREATE FUNCTION aggregate_daily_transport_statistics(target_date DATE) RETURNS INTEGER;
거리 계산
-- Haversine 거리 계산
CREATE FUNCTION calculate_distance(lat1 NUMERIC, lng1 NUMERIC, lat2 NUMERIC, lng2 NUMERIC)
RETURNS NUMERIC;
-- 이전 위치로부터 거리 계산
CREATE FUNCTION calculate_distance_from_prev() RETURNS TRIGGER;
비즈니스 로직
-- 수주 잔량 계산
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;
로그 관리
-- 테이블 변경 로그 트리거 함수
CREATE FUNCTION carrier_contract_mng_log_trigger_func() RETURNS TRIGGER;
CREATE FUNCTION carrier_mng_log_trigger_func() RETURNS TRIGGER;
-- ... 각 테이블별 로그 트리거 함수
12.2 주요 트리거
-- 화면 생성 시 메뉴 자동 생성
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 시스템 뷰
-- 권한 그룹 요약
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 암호화 컬럼
-- 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 백업 전략
# 전체 스키마 백업
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 핵심 아키텍처 특징
- 멀티테넌시: company_code로 완벽한 데이터 격리
- 메타데이터 드리븐: 동적 화면/테이블 생성
- Low-Code 플랫폼: 코드 없이 화면 구축
- 플로우 기반: 시각적 데이터 흐름 설계
- 외부 연동: DB/API 통합 지원
- 이력 관리: 완벽한 변경 이력 추적
18.2 확장성
- 수평 확장: 멀티테넌시로 무한한 회사 추가 가능
- 수직 확장: 동적 테이블/컬럼 추가
- 기능 확장: 플로우/배치 작업으로 비즈니스 로직 추가
18.3 유지보수성
- 표준화된 구조: 모든 테이블이 동일한 패턴
- 자동화: 트리거/함수로 반복 작업 자동화
- 문서화: 메타데이터 테이블 자체가 문서
부록 A: 백엔드 서비스 매핑
주요 서비스와 테이블 매핑
// 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 쿼리 예시
멀티테넌시 표준 쿼리
-- ✅ 단일 테이블 조회
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