-- V19: 엑셀 업로드 매핑 템플릿 시스템 -- 1. upload_template (마스터) CREATE TABLE upload_template ( template_id BIGSERIAL PRIMARY KEY, template_code VARCHAR(50) NOT NULL UNIQUE, template_name VARCHAR(100) NOT NULL, category VARCHAR(30) NOT NULL, -- RECRUIT/MAINTAIN/CONTRACT/AGENT/CUSTOM target_table VARCHAR(50) NOT NULL, company_code VARCHAR(20), -- NULL이면 범용 header_row INT NOT NULL DEFAULT 1, data_start_row INT NOT NULL DEFAULT 2, sheet_index INT NOT NULL DEFAULT 0, sheet_name VARCHAR(50), file_encoding VARCHAR(20) DEFAULT 'UTF-8', delimiter VARCHAR(5), skip_empty_row CHAR(1) DEFAULT 'Y', max_error_count INT DEFAULT 1000, batch_size INT DEFAULT 1000, description VARCHAR(200), is_active CHAR(1) DEFAULT 'Y', created_at TIMESTAMP DEFAULT NOW(), created_by BIGINT, updated_at TIMESTAMP, updated_by BIGINT ); CREATE INDEX idx_upload_tpl_category ON upload_template(category); CREATE INDEX idx_upload_tpl_company ON upload_template(company_code) WHERE company_code IS NOT NULL; -- 2. upload_template_column (컬럼 매핑 규칙) CREATE TABLE upload_template_column ( column_id BIGSERIAL PRIMARY KEY, template_id BIGINT NOT NULL REFERENCES upload_template(template_id) ON DELETE CASCADE, sort_order INT NOT NULL, source_type VARCHAR(10) NOT NULL DEFAULT 'COLUMN', -- COLUMN/FIXED/EXPRESSION source_column VARCHAR(10), -- 엑셀 컬럼 (A,B,C 또는 0,1,2) source_header VARCHAR(100), target_field VARCHAR(50) NOT NULL, target_type VARCHAR(20) NOT NULL DEFAULT 'STRING', -- STRING/NUMBER/DECIMAL/DATE/INTEGER transform_rule VARCHAR(30), -- TRIM/UPPER/LOWER/DATE/DIVIDE/MULTIPLY/LOOKUP/CODE_MAP/FIXED/REPLACE/SUBSTRING/CONCAT/DEFAULT/REQUIRED transform_param VARCHAR(200), -- JSON 또는 단순값 date_format VARCHAR(30), number_divide INT, number_multiply INT, fixed_value VARCHAR(200), default_value VARCHAR(200), lookup_table VARCHAR(50), lookup_source_field VARCHAR(50), lookup_target_field VARCHAR(50), code_map_group VARCHAR(50), is_required CHAR(1) DEFAULT 'N', validation_regex VARCHAR(200), validation_message VARCHAR(200), description VARCHAR(200), UNIQUE (template_id, sort_order) ); CREATE INDEX idx_upload_tpl_col ON upload_template_column(template_id); -- 3. upload_history (업로드 이력) CREATE TABLE upload_history ( history_id BIGSERIAL PRIMARY KEY, template_id BIGINT NOT NULL REFERENCES upload_template(template_id), template_code VARCHAR(50) NOT NULL, file_name VARCHAR(300) NOT NULL, file_size BIGINT, total_count INT NOT NULL DEFAULT 0, success_count INT NOT NULL DEFAULT 0, error_count INT NOT NULL DEFAULT 0, skip_count INT NOT NULL DEFAULT 0, error_file_id BIGINT, -- file_storage 느슨한 참조 (제약 없음) status VARCHAR(10) NOT NULL DEFAULT 'PROCESSING', -- PROCESSING/COMPLETED/FAILED/CANCELLED error_message TEXT, started_at TIMESTAMP NOT NULL DEFAULT NOW(), finished_at TIMESTAMP, duration_sec INT, created_by BIGINT ); CREATE INDEX idx_upload_history_tpl ON upload_history(template_id, started_at DESC); CREATE INDEX idx_upload_history_started ON upload_history(started_at DESC); -- 4. 메뉴 등록 (GRP_SYSTEM 하위, sort_order 7) INSERT INTO menu (menu_code, menu_name, menu_type, menu_path, component_path, menu_icon, menu_level, sort_order, is_visible, is_active, parent_menu_id, description) VALUES ('SYSTEM_UPLOAD_TEMPLATE', '엑셀 업로드 템플릿', 'PAGE', '/system/upload-templates', 'system/UploadTemplateManager', 'file-spreadsheet', 2, 7, 'Y', 'Y', (SELECT menu_id FROM menu WHERE menu_code = 'GRP_SYSTEM'), '보험사별 엑셀 업로드 양식 매핑 관리') ON CONFLICT (menu_code) DO NOTHING; -- 5. 메뉴 권한 4건 정의 INSERT INTO menu_permission (menu_id, perm_code, perm_name, sort_order) SELECT menu_id, 'READ', '조회', 1 FROM menu WHERE menu_code = 'SYSTEM_UPLOAD_TEMPLATE' ON CONFLICT (menu_id, perm_code) DO NOTHING; INSERT INTO menu_permission (menu_id, perm_code, perm_name, sort_order) SELECT menu_id, 'CREATE', '등록', 2 FROM menu WHERE menu_code = 'SYSTEM_UPLOAD_TEMPLATE' ON CONFLICT (menu_id, perm_code) DO NOTHING; INSERT INTO menu_permission (menu_id, perm_code, perm_name, sort_order) SELECT menu_id, 'UPDATE', '수정', 3 FROM menu WHERE menu_code = 'SYSTEM_UPLOAD_TEMPLATE' ON CONFLICT (menu_id, perm_code) DO NOTHING; INSERT INTO menu_permission (menu_id, perm_code, perm_name, sort_order) SELECT menu_id, 'DELETE', '삭제', 4 FROM menu WHERE menu_code = 'SYSTEM_UPLOAD_TEMPLATE' ON CONFLICT (menu_id, perm_code) DO NOTHING; -- 6. SUPER_ADMIN / ADMIN : READ + CREATE + UPDATE + DELETE INSERT INTO role_menu_permission (role_id, menu_id, perm_code, is_granted) SELECT r.role_id, m.menu_id, p.perm_code, 'Y' FROM role r CROSS JOIN menu m CROSS JOIN (VALUES ('READ'), ('CREATE'), ('UPDATE'), ('DELETE')) AS p(perm_code) WHERE r.role_code IN ('SUPER_ADMIN', 'ADMIN') AND m.menu_code = 'SYSTEM_UPLOAD_TEMPLATE' ON CONFLICT (role_id, menu_id, perm_code) DO NOTHING; -- 7. MANAGER : READ 만 INSERT INTO role_menu_permission (role_id, menu_id, perm_code, is_granted) SELECT r.role_id, m.menu_id, 'READ', 'Y' FROM role r CROSS JOIN menu m WHERE r.role_code = 'MANAGER' AND m.menu_code = 'SYSTEM_UPLOAD_TEMPLATE' ON CONFLICT (role_id, menu_id, perm_code) DO NOTHING;