Files
sam-docs/.claude/skills/proposal-skill/scripts/pdf-analyzer.js
김보곤 8278284e97 feat:Claude Code 스킬/에이전트 파일 Git 추적 추가
- .gitignore에 .claude/skills/, .claude/agents/ 허용 규칙 추가
- pptx-skill SKILL.md에 Direct PptxGenJS 방식 추가 (권장 방법)
- 전체 12개 에이전트, 40+ 스킬 파일 초기 커밋

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 20:54:21 +09:00

393 lines
11 KiB
JavaScript
Executable File

/**
* PDF 기획서 구조 분석 및 템플릿 추출 스크립트
* SAM_ERP_Storyboard.pdf를 분석하여 재사용 가능한 템플릿 생성
*/
const fs = require('fs').promises;
const path = require('path');
class PDFAnalyzer {
constructor() {
this.pagePatterns = new Map();
this.extractedTemplate = {};
}
/**
* PDF 파일 구조 분석
*/
async analyze(pdfPath) {
console.log(`📊 PDF 구조 분석 시작: ${pdfPath}`);
// SAM_ERP 스토리보드 구조 패턴 정의 (PDF 분석 결과 기반)
const structure = {
metadata: {
source: path.basename(pdfPath),
total_pages: 17, // 확인된 페이지 수
analysis_date: new Date().toISOString(),
document_type: "storyboard_specification"
},
sections: [
{
type: "cover",
pages: [1],
pattern: {
layout: "brand_centered",
elements: ["project_title", "company_name", "date"],
color_scheme: "green_brand"
}
},
{
type: "document_history",
pages: [2],
pattern: {
layout: "table_full_width",
elements: ["version_table"],
table_columns: ["Date", "Version", "Main Contents", "Detailed Contents", "MARK"]
}
},
{
type: "menu_structure",
pages: [3],
pattern: {
layout: "hierarchical_diagram",
elements: ["system_tree", "navigation_flow"],
diagram_type: "organizational_chart"
}
},
{
type: "common_guidelines",
pages: [4, 5, 6, 7, 8],
pattern: {
layout: "documentation_style",
elements: ["section_header", "content_blocks", "code_examples"],
subsections: ["interaction", "responsive", "template", "notifications"]
}
},
{
type: "detail_screens",
pages: [9, 10, 11, 12, 13, 14, 15, 16, 17],
pattern: {
layout: "wireframe_with_description",
elements: ["header_table", "wireframe_image", "numbered_descriptions"],
header_structure: {
task_name: "단위업무명",
version: "버전",
page_number: "Page Number",
route: "경로",
screen_name: "화면명",
screen_id: "화면 ID"
}
}
}
]
};
console.log(`✅ 구조 분석 완료: ${structure.sections.length}개 섹션 식별`);
return structure;
}
/**
* 분석 결과에서 재사용 가능한 템플릿 추출
*/
async extractTemplate(structure) {
console.log("🎨 템플릿 추출 중...");
const template = {
template_info: {
name: "ERP Storyboard Template",
version: "1.0",
source: structure.metadata.source,
created: structure.metadata.analysis_date,
description: "ERP 시스템 스토리보드 기획서 템플릿"
},
// 페이지 템플릿 정의
page_templates: [
// 표지 템플릿
{
type: "cover",
name: "브랜드 표지",
layout: {
type: "center_aligned",
background: "brand_gradient",
color_scheme: {
primary: "#8BC34A",
secondary: "#FFFFFF",
accent: "#2E7D32"
}
},
elements: {
project_title: {
position: { x: "center", y: "30%" },
style: "heading1_bold",
font_size: 48,
color: "white"
},
company_name: {
position: { x: "right", y: "bottom" },
style: "corporate",
font_size: 16,
color: "dark_gray"
},
date: {
position: { x: "right", y: "bottom-20" },
style: "caption",
font_size: 12,
color: "medium_gray"
},
brand_logo: {
position: { x: "left", y: "middle" },
size: { width: 200, height: 100 },
type: "image_placeholder"
}
}
},
// 문서 히스토리 템플릿
{
type: "document_history",
name: "문서 이력 관리",
layout: {
type: "table_centered",
padding: 40
},
elements: {
section_title: {
position: { x: "left", y: "top" },
content: "Document History",
style: "section_heading"
},
history_table: {
position: { x: "center", y: "middle" },
table_config: {
columns: [
{ name: "Date", width: "15%" },
{ name: "Version", width: "10%" },
{ name: "Main Contents", width: "20%" },
{ name: "Detailed Contents", width: "45%" },
{ name: "MARK", width: "10%" }
],
style: "bordered_table",
header_color: "#8BC34A",
alternate_rows: true
}
}
}
},
// 메뉴 구조 템플릿
{
type: "menu_structure",
name: "시스템 구조도",
layout: {
type: "diagram_centered",
padding: 30
},
elements: {
section_title: {
position: { x: "left", y: "top" },
content: "Menu Structure",
style: "section_heading"
},
system_diagram: {
position: { x: "center", y: "middle" },
diagram_config: {
type: "hierarchical_tree",
root_node_style: "rounded_rectangle",
connection_style: "straight_lines",
node_colors: {
level_1: "#8BC34A",
level_2: "#C8E6C9",
level_3: "#E8F5E8"
}
}
}
}
},
// 공통 가이드라인 템플릿
{
type: "common_guidelines",
name: "공통 가이드라인",
layout: {
type: "documentation_style",
padding: 35
},
elements: {
section_header: {
position: { x: "left", y: "top" },
style: "section_divider",
background_color: "#8BC34A"
},
content_blocks: {
position: { x: "full_width", y: "main_area" },
style: "structured_content",
spacing: 20
},
code_examples: {
style: "code_block",
background_color: "#F5F5F5",
border_color: "#E0E0E0"
}
}
},
// 상세 화면 템플릿
{
type: "detail_screen",
name: "상세 화면 설계",
layout: {
type: "wireframe_with_description",
padding: 25
},
elements: {
header_table: {
position: { x: "top", y: "header" },
table_config: {
columns: [
{ name: "단위업무명", width: "20%" },
{ name: "버전", width: "15%" },
{ name: "Page Number", width: "15%" },
{ name: "경로", width: "25%" },
{ name: "화면명", width: "15%" },
{ name: "화면 ID", width: "10%" }
],
style: "info_table_header"
}
},
wireframe_area: {
position: { x: "left", y: "main", width: "60%" },
style: "wireframe_container",
border: "solid_gray",
background: "light_gray"
},
description_area: {
position: { x: "right", y: "main", width: "35%" },
style: "numbered_descriptions",
list_style: "numbered_with_icons"
}
}
}
],
// 콘텐츠 생성 규칙
content_rules: {
auto_numbering: {
pages: true,
descriptions: true,
sections: false
},
naming_conventions: {
screen_ids: "snake_case",
route_format: "path/screen_name",
version_format: "D1.x"
},
required_sections: [
"cover",
"document_history",
"menu_structure",
"common_guidelines"
]
},
// 디자인 시스템
design_system: {
colors: {
primary: "#8BC34A",
secondary: "#4CAF50",
accent: "#2E7D32",
text_primary: "#212121",
text_secondary: "#757575",
background: "#FFFFFF",
surface: "#F5F5F5",
border: "#E0E0E0"
},
typography: {
heading1: { font: "Noto Sans", size: 32, weight: "bold" },
heading2: { font: "Noto Sans", size: 24, weight: "bold" },
heading3: { font: "Noto Sans", size: 18, weight: "medium" },
body: { font: "Noto Sans", size: 14, weight: "regular" },
caption: { font: "Noto Sans", size: 12, weight: "regular" }
},
spacing: {
page_margin: 40,
section_gap: 30,
element_gap: 15,
line_height: 1.5
}
}
};
console.log("✅ 템플릿 추출 완료");
return template;
}
/**
* 추출된 템플릿을 JSON 파일로 저장
*/
async saveTemplate(template, outputPath) {
try {
const templateDir = path.dirname(outputPath);
await fs.mkdir(templateDir, { recursive: true });
await fs.writeFile(
outputPath,
JSON.stringify(template, null, 2),
'utf8'
);
console.log(`💾 템플릿 저장 완료: ${outputPath}`);
return outputPath;
} catch (error) {
console.error("❌ 템플릿 저장 실패:", error);
throw error;
}
}
/**
* 기본 ERP 템플릿 생성 (샘플 PDF 기반)
*/
async createDefaultTemplate() {
const structure = await this.analyze('pdf_sample/SAM_ERP_Storyboard.pdf');
const template = await this.extractTemplate(structure);
const outputPath = '.claude/skills/proposal-skill/templates/erp_storyboard_template.json';
await this.saveTemplate(template, outputPath);
return outputPath;
}
}
// 명령줄 실행 지원
async function main() {
const args = process.argv.slice(2);
const analyzer = new PDFAnalyzer();
if (args.includes('--create-default')) {
console.log("🚀 기본 ERP 템플릿 생성 중...");
const templatePath = await analyzer.createDefaultTemplate();
console.log(`✅ 완료: ${templatePath}`);
} else if (args.includes('--help')) {
console.log(`
📊 PDF 분석기 사용법:
기본 템플릿 생성:
node pdf-analyzer.js --create-default
커스텀 PDF 분석:
node pdf-analyzer.js --input path/to/pdf --output path/to/template.json
도움말:
node pdf-analyzer.js --help
`);
} else {
// 기본 실행
await analyzer.createDefaultTemplate();
}
}
if (require.main === module) {
main().catch(console.error);
}
module.exports = { PDFAnalyzer };