const path = require('path');
module.paths.unshift(path.join(require('os').homedir(), '.claude/skills/pptx-skill/scripts/node_modules'));

const PptxGenJS = require('pptxgenjs');

async function main() {
    const pres = new PptxGenJS();
    pres.defineLayout({ name: 'CUSTOM_16x9', width: 10, height: 5.625 });
    pres.layout = 'CUSTOM_16x9';

    // === 컬러 팔레트 ===
    const C = {
        navy: '0f172a',
        navyLight: '1e293b',
        navyMid: '334155',
        blue: '3b82f6',
        blueLight: '60a5fa',
        blueDark: '1d4ed8',
        blueBg: '1e3a5f',
        white: 'FFFFFF',
        gray100: 'f1f5f9',
        gray200: 'e2e8f0',
        gray300: 'cbd5e1',
        gray400: '94a3b8',
        gray500: '64748b',
        gray600: '475569',
        gray700: '334155',
        red: 'ef4444',
        redBg: 'fef2f2',
        redLight: 'fca5a5',
        green: '22c55e',
        greenBg: 'f0fdf4',
        greenLight: '86efac',
        amber: 'f59e0b',
        amberBg: 'fffbeb',
        purple: 'a855f7',
        purpleBg: 'faf5ff',
        cyan: '06b6d4',
        cyanBg: 'ecfeff',
    };

    const biLogoPath = '/home/aweso/sam/docs/assets/bi/sam_bi_white.png';

    // === 공통 푸터 함수 ===
    function addFooter(slide, pageNum, totalPages) {
        // 하단 라인
        slide.addShape(pres.ShapeType.rect, {
            x: 0.5, y: 5.15, w: 9, h: 0.01, fill: { color: C.navyMid }
        });
        slide.addText('SAM 이메일 정책 | (주)코드브릿지엑스', {
            x: 0.5, y: 5.2, w: 7, h: 0.3,
            fontSize: 7, color: C.gray500, fontFace: 'Arial'
        });
        slide.addText(`${pageNum} / ${totalPages}`, {
            x: 7.5, y: 5.2, w: 2, h: 0.3,
            fontSize: 7, color: C.gray500, align: 'right', fontFace: 'Arial'
        });
    }

    // === 공통 페이지 헤더 ===
    function addPageHeader(slide, title, subtitle) {
        slide.background = { fill: C.white };
        // 상단 네이비 바
        slide.addShape(pres.ShapeType.rect, {
            x: 0, y: 0, w: 10, h: 0.06, fill: { color: C.blue }
        });
        // 제목 액센트 바
        slide.addShape(pres.ShapeType.rect, {
            x: 0.5, y: 0.4, w: 0.06, h: 0.4, fill: { color: C.blue }
        });
        slide.addText(title, {
            x: 0.72, y: 0.35, w: 6, h: 0.5,
            fontSize: 20, bold: true, color: C.navy, fontFace: 'Arial'
        });
        if (subtitle) {
            slide.addText(subtitle, {
                x: 0.72, y: 0.8, w: 8, h: 0.3,
                fontSize: 10, color: C.gray500, fontFace: 'Arial'
            });
        }
    }

    // === 넘버 서클 ===
    function addNumberCircle(slide, num, x, y, color) {
        slide.addShape(pres.ShapeType.ellipse, {
            x, y, w: 0.35, h: 0.35, fill: { color: color || C.blue }
        });
        slide.addText(String(num), {
            x, y, w: 0.35, h: 0.35,
            fontSize: 12, bold: true, color: C.white,
            align: 'center', valign: 'middle', fontFace: 'Arial'
        });
    }

    const TOTAL = 12;

    // ==============================
    // 슬라이드 1: 표지
    // ==============================
    const s1 = pres.addSlide();
    s1.background = { fill: C.navy };

    // 상단 그라데이션 효과 (가상)
    s1.addShape(pres.ShapeType.rect, {
        x: 0, y: 0, w: 10, h: 2, fill: { color: C.navyLight }
    });
    s1.addShape(pres.ShapeType.rect, {
        x: 0, y: 0, w: 10, h: 0.08, fill: { color: C.blue }
    });

    // BI 로고
    s1.addImage({
        path: biLogoPath,
        x: 0.7, y: 0.4, w: 1.6, h: 0.7
    });

    // 메인 제목
    s1.addText('멀티테넌시 이메일 정책', {
        x: 0.7, y: 2.2, w: 8.5, h: 0.8,
        fontSize: 36, bold: true, color: C.white, fontFace: 'Arial'
    });
    // 서브 제목
    s1.addText('SAM Email System Architecture & Policy', {
        x: 0.7, y: 2.95, w: 8.5, h: 0.5,
        fontSize: 16, color: C.blueLight, fontFace: 'Arial'
    });

    // 구분선
    s1.addShape(pres.ShapeType.rect, {
        x: 0.7, y: 3.6, w: 2.5, h: 0.03, fill: { color: C.blue }
    });

    // 메타 정보
    s1.addText([
        { text: '2026-03-11', options: { fontSize: 11, color: C.gray400 } },
        { text: '  |  ', options: { fontSize: 11, color: C.navyMid } },
        { text: '개발팀 내부 공유', options: { fontSize: 11, color: C.gray400 } },
    ], { x: 0.7, y: 3.85, w: 6, h: 0.4, fontFace: 'Arial' });

    // 하단
    s1.addText('(주)코드브릿지엑스', {
        x: 0.7, y: 5.0, w: 5, h: 0.3,
        fontSize: 9, color: C.gray500, fontFace: 'Arial'
    });

    // ==============================
    // 슬라이드 2: 현재 문제점 (AS-IS)
    // ==============================
    const s2 = pres.addSlide();
    addPageHeader(s2, '현재 문제점 (AS-IS)', '기존 이메일 시스템의 한계');

    const problems = [
        { icon: '1', title: '단일 SMTP 설정', desc: '.env에 고정된 Gmail SMTP\nGmail 일일 500건 제한에 전체 영향', color: C.red, bg: C.redBg },
        { icon: '2', title: '단일 발신 주소', desc: 'develop@codebridge-x.com 하나로\n모든 테넌트 메일 발송', color: C.red, bg: C.redBg },
        { icon: '3', title: '발송 기록 없음', desc: '메일 발송 이력 추적 불가\n장애 시 원인 파악 어려움', color: C.amber, bg: C.amberBg },
        { icon: '4', title: 'Mailable 중복', desc: 'EsignRequestMail이\nAPI + MNG 양쪽에 존재', color: C.amber, bg: C.amberBg },
        { icon: '5', title: '템플릿 하드코딩', desc: '테넌트별 로고/서명/컬러\n커스터마이징 불가', color: C.amber, bg: C.amberBg },
        { icon: '6', title: 'Mail::to() 직접 호출', desc: 'TenantMailService 없이\n각 컨트롤러에서 직접 발송', color: C.purple, bg: C.purpleBg },
    ];

    problems.forEach((p, i) => {
        const col = i % 3;
        const row = Math.floor(i / 3);
        const x = 0.5 + col * 3.1;
        const y = 1.3 + row * 1.95;

        // 카드 배경
        s2.addShape(pres.ShapeType.roundRect, {
            x, y, w: 2.9, h: 1.75, rectRadius: 0.1,
            fill: { color: p.bg }, line: { color: p.color, width: 0.5, dashType: 'solid' }
        });
        // 넘버 원
        addNumberCircle(s2, p.icon, x + 0.15, y + 0.15, p.color);
        // 제목
        s2.addText(p.title, {
            x: x + 0.6, y: y + 0.15, w: 2.1, h: 0.35,
            fontSize: 11, bold: true, color: p.color, fontFace: 'Arial'
        });
        // 설명
        s2.addText(p.desc, {
            x: x + 0.2, y: y + 0.6, w: 2.5, h: 0.9,
            fontSize: 9, color: C.gray600, fontFace: 'Arial', lineSpacingMultiple: 1.3
        });
    });

    addFooter(s2, 2, TOTAL);

    // ==============================
    // 슬라이드 3: 목표 아키텍처 (TO-BE)
    // ==============================
    const s3 = pres.addSlide();
    addPageHeader(s3, '목표 아키텍처 (TO-BE)', '3-Layer 구조로 테넌트 격리, 브랜딩, 추적을 구현');

    // Layer 1
    s3.addShape(pres.ShapeType.roundRect, {
        x: 0.5, y: 1.4, w: 9, h: 1.0, rectRadius: 0.12,
        fill: { color: 'eff6ff' }, line: { color: C.blue, width: 1.5 }
    });
    s3.addText('Layer 1', {
        x: 0.7, y: 1.45, w: 1.2, h: 0.3,
        fontSize: 8, bold: true, color: C.white, fontFace: 'Arial'
    });
    s3.addShape(pres.ShapeType.roundRect, {
        x: 0.7, y: 1.45, w: 0.7, h: 0.25, rectRadius: 0.04,
        fill: { color: C.blue }
    });
    s3.addText('Layer 1', {
        x: 0.7, y: 1.45, w: 0.7, h: 0.25,
        fontSize: 8, bold: true, color: C.white, align: 'center', fontFace: 'Arial'
    });
    s3.addText('테넌트 메일 설정 (tenant_mail_configs)', {
        x: 1.55, y: 1.45, w: 5, h: 0.3,
        fontSize: 13, bold: true, color: C.blueDark, fontFace: 'Arial'
    });
    s3.addText('SMTP 설정  |  발신자 주소/이름  |  브랜딩 정보 (로고, 컬러, 서명)  |  Provider 선택', {
        x: 0.9, y: 1.85, w: 8.2, h: 0.35,
        fontSize: 9, color: C.gray600, fontFace: 'Arial'
    });

    // 화살표 1
    s3.addText('▼', {
        x: 4.5, y: 2.4, w: 1, h: 0.3,
        fontSize: 16, color: C.blue, align: 'center', fontFace: 'Arial'
    });

    // Layer 2
    s3.addShape(pres.ShapeType.roundRect, {
        x: 0.5, y: 2.7, w: 9, h: 1.0, rectRadius: 0.12,
        fill: { color: C.greenBg }, line: { color: C.green, width: 1.5 }
    });
    s3.addShape(pres.ShapeType.roundRect, {
        x: 0.7, y: 2.75, w: 0.7, h: 0.25, rectRadius: 0.04,
        fill: { color: C.green }
    });
    s3.addText('Layer 2', {
        x: 0.7, y: 2.75, w: 0.7, h: 0.25,
        fontSize: 8, bold: true, color: C.white, align: 'center', fontFace: 'Arial'
    });
    s3.addText('메일 발송 서비스 (TenantMailService)', {
        x: 1.55, y: 2.75, w: 5, h: 0.3,
        fontSize: 13, bold: true, color: '166534', fontFace: 'Arial'
    });
    s3.addText('테넌트 설정 자동 적용  |  큐/즉시 발송  |  Fallback 전략  |  쿼터 확인', {
        x: 0.9, y: 3.15, w: 8.2, h: 0.35,
        fontSize: 9, color: C.gray600, fontFace: 'Arial'
    });

    // 화살표 2
    s3.addText('▼', {
        x: 4.5, y: 3.7, w: 1, h: 0.3,
        fontSize: 16, color: C.green, align: 'center', fontFace: 'Arial'
    });

    // Layer 3
    s3.addShape(pres.ShapeType.roundRect, {
        x: 0.5, y: 4.0, w: 9, h: 1.0, rectRadius: 0.12,
        fill: { color: C.purpleBg }, line: { color: C.purple, width: 1.5 }
    });
    s3.addShape(pres.ShapeType.roundRect, {
        x: 0.7, y: 4.05, w: 0.7, h: 0.25, rectRadius: 0.04,
        fill: { color: C.purple }
    });
    s3.addText('Layer 3', {
        x: 0.7, y: 4.05, w: 0.7, h: 0.25,
        fontSize: 8, bold: true, color: C.white, align: 'center', fontFace: 'Arial'
    });
    s3.addText('발송 기록/추적 (mail_logs)', {
        x: 1.55, y: 4.05, w: 5, h: 0.3,
        fontSize: 13, bold: true, color: '7c3aed', fontFace: 'Arial'
    });
    s3.addText('발송 이력  |  상태 추적 (queued/sent/failed/bounced)  |  일일 쿼터 관리  |  감사 로그', {
        x: 0.9, y: 4.45, w: 8.2, h: 0.35,
        fontSize: 9, color: C.gray600, fontFace: 'Arial'
    });

    addFooter(s3, 3, TOTAL);

    // ==============================
    // 슬라이드 4: 테넌트별 메일 설정
    // ==============================
    const s4 = pres.addSlide();
    addPageHeader(s4, '테넌트별 메일 설정', 'tenant_mail_configs 테이블 구조');

    // 왼쪽: 테이블 구조
    s4.addShape(pres.ShapeType.roundRect, {
        x: 0.5, y: 1.3, w: 4.5, h: 3.7, rectRadius: 0.1,
        fill: { color: C.navy }
    });
    s4.addText('tenant_mail_configs', {
        x: 0.7, y: 1.4, w: 4, h: 0.35,
        fontSize: 12, bold: true, color: C.blueLight, fontFace: 'Courier New'
    });
    // 구분선
    s4.addShape(pres.ShapeType.rect, {
        x: 0.7, y: 1.8, w: 4.1, h: 0.01, fill: { color: C.navyMid }
    });

    const fields = [
        ['tenant_id', 'FK', '테넌트 ID'],
        ['provider', 'ENUM', 'platform / smtp / ses / mailgun'],
        ['from_address', 'VARCHAR', '발신 이메일 주소'],
        ['from_name', 'VARCHAR', '발신자 표시명'],
        ['reply_to', 'VARCHAR', '회신 주소 (선택)'],
        ['is_verified', 'BOOL', '도메인 검증 여부'],
        ['daily_limit', 'INT', '일일 발송 한도 (기본 500)'],
        ['options', 'JSON', 'SMTP 설정, 브랜딩 정보'],
    ];

    fields.forEach((f, i) => {
        const fy = 1.9 + i * 0.38;
        s4.addText(f[0], {
            x: 0.7, y: fy, w: 1.6, h: 0.3,
            fontSize: 8, color: C.blueLight, fontFace: 'Courier New'
        });
        s4.addText(f[1], {
            x: 2.35, y: fy, w: 0.75, h: 0.3,
            fontSize: 7, color: C.gray400, fontFace: 'Arial'
        });
        s4.addText(f[2], {
            x: 3.15, y: fy, w: 1.8, h: 0.3,
            fontSize: 7, color: C.gray300, fontFace: 'Arial'
        });
    });

    // 오른쪽: Provider 카드
    const providers = [
        { name: 'Platform', desc: 'SAM 기본 SMTP\n(설정 불필요)', color: C.blue, bg: 'eff6ff' },
        { name: 'Custom SMTP', desc: '테넌트 자체\nSMTP 서버', color: C.green, bg: C.greenBg },
        { name: 'Amazon SES', desc: 'AWS 대량 발송\n서비스', color: C.amber, bg: C.amberBg },
        { name: 'Mailgun', desc: '이메일 API\n서비스', color: C.purple, bg: C.purpleBg },
    ];

    s4.addText('Provider 선택', {
        x: 5.3, y: 1.3, w: 4, h: 0.35,
        fontSize: 12, bold: true, color: C.navy, fontFace: 'Arial'
    });

    providers.forEach((p, i) => {
        const py = 1.8 + i * 0.85;
        s4.addShape(pres.ShapeType.roundRect, {
            x: 5.3, y: py, w: 4.2, h: 0.7, rectRadius: 0.08,
            fill: { color: p.bg }, line: { color: p.color, width: 0.5 }
        });
        s4.addShape(pres.ShapeType.ellipse, {
            x: 5.5, y: py + 0.15, w: 0.4, h: 0.4, fill: { color: p.color }
        });
        s4.addText(p.name.charAt(0), {
            x: 5.5, y: py + 0.15, w: 0.4, h: 0.4,
            fontSize: 12, bold: true, color: C.white,
            align: 'center', valign: 'middle', fontFace: 'Arial'
        });
        s4.addText(p.name, {
            x: 6.1, y: py + 0.05, w: 2, h: 0.3,
            fontSize: 10, bold: true, color: p.color, fontFace: 'Arial'
        });
        s4.addText(p.desc, {
            x: 6.1, y: py + 0.3, w: 3.2, h: 0.35,
            fontSize: 8, color: C.gray600, fontFace: 'Arial'
        });
    });

    addFooter(s4, 4, TOTAL);

    // ==============================
    // 슬라이드 5: 발송 흐름
    // ==============================
    const s5 = pres.addSlide();
    addPageHeader(s5, '발송 흐름', 'TenantMailService를 경유한 중앙 집중 발송');

    // 흐름 다이어그램 - 세로 플로우
    const flowSteps = [
        { label: 'Controller / Service', sub: '메일 발송 요청', color: C.gray600, bg: C.gray100 },
        { label: 'TenantMailService::send()', sub: '중앙 발송 서비스', color: C.blue, bg: 'eff6ff' },
        { label: '테넌트 설정 조회', sub: 'tenant_mail_configs', color: C.blueDark, bg: 'dbeafe' },
        { label: '쿼터 확인', sub: '일일 500건 한도 체크', color: C.amber, bg: C.amberBg },
        { label: 'Mailer 동적 구성', sub: 'SMTP/SES/Mailgun 설정 적용', color: C.green, bg: C.greenBg },
        { label: '발송 (sync / queue)', sub: 'OTP=즉시, 나머지=큐', color: C.purple, bg: C.purpleBg },
        { label: 'mail_logs 기록', sub: 'status: queued → sent', color: C.cyan, bg: C.cyanBg },
    ];

    flowSteps.forEach((step, i) => {
        const sy = 1.25 + i * 0.55;
        // 연결 화살표
        if (i > 0) {
            s5.addText('▼', {
                x: 2.1, y: sy - 0.2, w: 0.5, h: 0.2,
                fontSize: 8, color: C.gray400, align: 'center', fontFace: 'Arial'
            });
        }
        // 넘버
        addNumberCircle(s5, i + 1, 0.5, sy + 0.04, step.color);
        // 박스
        s5.addShape(pres.ShapeType.roundRect, {
            x: 1.0, y: sy, w: 3.7, h: 0.42, rectRadius: 0.06,
            fill: { color: step.bg }, line: { color: step.color, width: 0.5 }
        });
        s5.addText(step.label, {
            x: 1.15, y: sy, w: 2.2, h: 0.42,
            fontSize: 9, bold: true, color: step.color, valign: 'middle', fontFace: 'Arial'
        });
        s5.addText(step.sub, {
            x: 3.1, y: sy, w: 1.5, h: 0.42,
            fontSize: 7, color: C.gray500, valign: 'middle', fontFace: 'Arial'
        });
    });

    // 오른쪽: Fallback 전략
    s5.addShape(pres.ShapeType.roundRect, {
        x: 5.3, y: 1.25, w: 4.2, h: 3.6, rectRadius: 0.12,
        fill: { color: C.navy }
    });
    s5.addText('Fallback 전략', {
        x: 5.5, y: 1.35, w: 3.5, h: 0.35,
        fontSize: 13, bold: true, color: C.white, fontFace: 'Arial'
    });

    const fallbackItems = [
        { step: '1차', desc: '테넌트 자체 SMTP로 발송', status: '시도', color: C.blue },
        { step: '성공', desc: 'mail_logs (status: sent)', status: '', color: C.green },
        { step: '실패', desc: '플랫폼 기본 SMTP로 재시도', status: 'Fallback', color: C.amber },
        { step: '성공', desc: 'mail_logs (fallback_used: true)', status: '', color: C.green },
        { step: '실패', desc: 'mail_logs (status: failed)', status: '3회 재시도', color: C.red },
    ];

    fallbackItems.forEach((item, i) => {
        const fy = 1.85 + i * 0.6;
        // 연결선
        if (i > 0) {
            s5.addShape(pres.ShapeType.rect, {
                x: 6.0, y: fy - 0.15, w: 0.01, h: 0.15, fill: { color: C.navyMid }
            });
        }
        s5.addShape(pres.ShapeType.roundRect, {
            x: 5.6, y: fy, w: 0.6, h: 0.35, rectRadius: 0.04,
            fill: { color: item.color }
        });
        s5.addText(item.step, {
            x: 5.6, y: fy, w: 0.6, h: 0.35,
            fontSize: 7, bold: true, color: C.white,
            align: 'center', valign: 'middle', fontFace: 'Arial'
        });
        s5.addText(item.desc, {
            x: 6.35, y: fy, w: 2.5, h: 0.35,
            fontSize: 8, color: C.gray300, valign: 'middle', fontFace: 'Arial'
        });
        if (item.status) {
            s5.addText(item.status, {
                x: 8.7, y: fy, w: 0.7, h: 0.35,
                fontSize: 6, color: item.color, valign: 'middle', fontFace: 'Arial'
            });
        }
    });

    addFooter(s5, 5, TOTAL);

    // ==============================
    // 슬라이드 6: 발송 기록 (mail_logs)
    // ==============================
    const s6 = pres.addSlide();
    addPageHeader(s6, '발송 기록 (mail_logs)', '모든 발송을 기록하여 추적/감사/통계 지원');

    // 왼쪽: 테이블 구조
    s6.addShape(pres.ShapeType.roundRect, {
        x: 0.5, y: 1.3, w: 4.5, h: 3.7, rectRadius: 0.1,
        fill: { color: C.navy }
    });
    s6.addText('mail_logs', {
        x: 0.7, y: 1.4, w: 3, h: 0.35,
        fontSize: 12, bold: true, color: C.blueLight, fontFace: 'Courier New'
    });
    s6.addShape(pres.ShapeType.rect, {
        x: 0.7, y: 1.8, w: 4.1, h: 0.01, fill: { color: C.navyMid }
    });

    const logFields = [
        ['tenant_id', '테넌트 ID'],
        ['mailable_type', 'Mailable 클래스명'],
        ['to_address', '수신자 이메일'],
        ['from_address', '실제 발신 주소'],
        ['subject', '메일 제목'],
        ['status', 'queued / sent / failed / bounced'],
        ['sent_at', '발송 시각'],
        ['options', '에러메시지, 재시도횟수, 관련모델'],
    ];

    logFields.forEach((f, i) => {
        const fy = 1.9 + i * 0.38;
        s6.addText(f[0], {
            x: 0.7, y: fy, w: 1.6, h: 0.3,
            fontSize: 8, color: C.blueLight, fontFace: 'Courier New'
        });
        s6.addText(f[1], {
            x: 2.4, y: fy, w: 2.4, h: 0.3,
            fontSize: 8, color: C.gray300, fontFace: 'Arial'
        });
    });

    // 오른쪽: 상태 흐름 + 보안
    s6.addText('상태 흐름', {
        x: 5.3, y: 1.3, w: 3, h: 0.35,
        fontSize: 12, bold: true, color: C.navy, fontFace: 'Arial'
    });

    const statuses = [
        { name: 'queued', desc: '큐에 등록됨', color: C.blue, bg: 'eff6ff' },
        { name: 'sent', desc: '발송 완료', color: C.green, bg: C.greenBg },
        { name: 'failed', desc: '발송 실패', color: C.red, bg: C.redBg },
        { name: 'bounced', desc: '수신 거부/반송', color: C.amber, bg: C.amberBg },
    ];

    statuses.forEach((st, i) => {
        const sy = 1.8 + i * 0.55;
        s6.addShape(pres.ShapeType.roundRect, {
            x: 5.3, y: sy, w: 4.2, h: 0.42, rectRadius: 0.06,
            fill: { color: st.bg }, line: { color: st.color, width: 0.5 }
        });
        s6.addShape(pres.ShapeType.ellipse, {
            x: 5.45, y: sy + 0.08, w: 0.26, h: 0.26, fill: { color: st.color }
        });
        s6.addText(st.name, {
            x: 5.85, y: sy, w: 1.2, h: 0.42,
            fontSize: 9, bold: true, color: st.color, valign: 'middle', fontFace: 'Courier New'
        });
        s6.addText(st.desc, {
            x: 7.2, y: sy, w: 2, h: 0.42,
            fontSize: 9, color: C.gray600, valign: 'middle', fontFace: 'Arial'
        });
    });

    // 보안 주의사항
    s6.addShape(pres.ShapeType.roundRect, {
        x: 5.3, y: 4.15, w: 4.2, h: 0.8, rectRadius: 0.08,
        fill: { color: C.redBg }, line: { color: C.red, width: 0.5 }
    });
    s6.addText('개인정보 보호', {
        x: 5.5, y: 4.2, w: 3, h: 0.25,
        fontSize: 9, bold: true, color: C.red, fontFace: 'Arial'
    });
    s6.addText('mail_logs에 메일 본문(body) 저장 금지\n메타데이터(제목, 수신자, 상태)만 기록', {
        x: 5.5, y: 4.45, w: 3.8, h: 0.45,
        fontSize: 8, color: C.gray600, fontFace: 'Arial', lineSpacingMultiple: 1.3
    });

    addFooter(s6, 6, TOTAL);

    // ==============================
    // 슬라이드 7: 메일 타입 정리
    // ==============================
    const s7 = pres.addSlide();
    addPageHeader(s7, '메일 타입 정리', '5개 Mailable + sync/queue 구분');

    const mailTypes = [
        { name: 'EsignRequestMail', cat: '전자계약', trigger: '서명 요청', mode: 'queue', color: C.blue, modeColor: C.green },
        { name: 'EsignOtpMail', cat: '전자계약', trigger: 'OTP 인증', mode: 'sync', color: C.blue, modeColor: C.red },
        { name: 'EsignCompletedMail', cat: '전자계약', trigger: '서명 완료', mode: 'queue', color: C.blue, modeColor: C.green },
        { name: 'UserPasswordMail', cat: '인증', trigger: '계정/비번 초기화', mode: 'sync', color: C.purple, modeColor: C.red },
        { name: 'PayslipMail', cat: '급여', trigger: '급여명세서 발송', mode: 'queue', color: C.amber, modeColor: C.green },
    ];

    // 헤더 행
    s7.addShape(pres.ShapeType.roundRect, {
        x: 0.5, y: 1.3, w: 9, h: 0.45, rectRadius: 0.06,
        fill: { color: C.navy }
    });
    const headers = [
        { text: 'Mailable', x: 0.7, w: 2.5 },
        { text: '카테고리', x: 3.3, w: 1.2 },
        { text: '트리거', x: 4.6, w: 1.8 },
        { text: '발송 모드', x: 6.5, w: 1.0 },
        { text: '사유', x: 7.6, w: 1.8 },
    ];
    headers.forEach(h => {
        s7.addText(h.text, {
            x: h.x, y: 1.3, w: h.w, h: 0.45,
            fontSize: 9, bold: true, color: C.white,
            valign: 'middle', fontFace: 'Arial'
        });
    });

    mailTypes.forEach((mt, i) => {
        const ry = 1.85 + i * 0.55;
        // 행 배경 (짝수 행 약간 다르게)
        s7.addShape(pres.ShapeType.roundRect, {
            x: 0.5, y: ry, w: 9, h: 0.45, rectRadius: 0.06,
            fill: { color: i % 2 === 0 ? C.gray100 : C.white },
            line: { color: C.gray200, width: 0.3 }
        });
        s7.addText(mt.name, {
            x: 0.7, y: ry, w: 2.5, h: 0.45,
            fontSize: 9, bold: true, color: C.navy, valign: 'middle', fontFace: 'Courier New'
        });
        // 카테고리 배지
        s7.addShape(pres.ShapeType.roundRect, {
            x: 3.3, y: ry + 0.08, w: 0.9, h: 0.28, rectRadius: 0.04,
            fill: { color: mt.color }
        });
        s7.addText(mt.cat, {
            x: 3.3, y: ry + 0.08, w: 0.9, h: 0.28,
            fontSize: 7, bold: true, color: C.white,
            align: 'center', valign: 'middle', fontFace: 'Arial'
        });
        s7.addText(mt.trigger, {
            x: 4.6, y: ry, w: 1.8, h: 0.45,
            fontSize: 9, color: C.gray600, valign: 'middle', fontFace: 'Arial'
        });
        // 모드 배지
        s7.addShape(pres.ShapeType.roundRect, {
            x: 6.55, y: ry + 0.08, w: 0.7, h: 0.28, rectRadius: 0.04,
            fill: { color: mt.modeColor }
        });
        s7.addText(mt.mode, {
            x: 6.55, y: ry + 0.08, w: 0.7, h: 0.28,
            fontSize: 7, bold: true, color: C.white,
            align: 'center', valign: 'middle', fontFace: 'Arial'
        });
        s7.addText(mt.mode === 'sync' ? '시간 민감 (즉시)' : '비동기 발송 가능', {
            x: 7.6, y: ry, w: 1.8, h: 0.45,
            fontSize: 8, color: C.gray500, valign: 'middle', fontFace: 'Arial'
        });
    });

    // 하단 설명
    s7.addShape(pres.ShapeType.roundRect, {
        x: 0.5, y: 4.5, w: 4.3, h: 0.55, rectRadius: 0.06,
        fill: { color: C.redBg }, line: { color: C.red, width: 0.5 }
    });
    s7.addText([
        { text: 'sync', options: { bold: true, color: C.red, fontSize: 9 } },
        { text: ' = Mail::send() 즉시 발송 (OTP, 비밀번호)', options: { color: C.gray600, fontSize: 8 } }
    ], { x: 0.7, y: 4.5, w: 4, h: 0.55, valign: 'middle', fontFace: 'Arial' });

    s7.addShape(pres.ShapeType.roundRect, {
        x: 5.1, y: 4.5, w: 4.4, h: 0.55, rectRadius: 0.06,
        fill: { color: C.greenBg }, line: { color: C.green, width: 0.5 }
    });
    s7.addText([
        { text: 'queue', options: { bold: true, color: C.green, fontSize: 9 } },
        { text: ' = Mail::queue() Supervisor 큐 워커 처리', options: { color: C.gray600, fontSize: 8 } }
    ], { x: 5.3, y: 4.5, w: 4, h: 0.55, valign: 'middle', fontFace: 'Arial' });

    addFooter(s7, 7, TOTAL);

    // ==============================
    // 슬라이드 8: 템플릿 브랜딩
    // ==============================
    const s8 = pres.addSlide();
    addPageHeader(s8, '템플릿 브랜딩', '테넌트별 로고, 컬러, 서명 커스터마이징');

    // 이메일 레이아웃 시각화
    // 외곽 (이메일 프레임)
    s8.addShape(pres.ShapeType.roundRect, {
        x: 0.5, y: 1.3, w: 4.5, h: 3.8, rectRadius: 0.12,
        fill: { color: C.white }, line: { color: C.gray300, width: 1 }
    });

    // 헤더 영역
    s8.addShape(pres.ShapeType.rect, {
        x: 0.5, y: 1.3, w: 4.5, h: 0.8,
        fill: { color: 'eff6ff' }
    });
    s8.addShape(pres.ShapeType.roundRect, {
        x: 0.8, y: 1.45, w: 0.8, h: 0.5, rectRadius: 0.05,
        fill: { color: C.blue }
    });
    s8.addText('LOGO', {
        x: 0.8, y: 1.45, w: 0.8, h: 0.5,
        fontSize: 8, bold: true, color: C.white,
        align: 'center', valign: 'middle', fontFace: 'Arial'
    });
    s8.addText('{{ 테넌트명 }}', {
        x: 1.8, y: 1.45, w: 2.5, h: 0.5,
        fontSize: 11, bold: true, color: C.navy, valign: 'middle', fontFace: 'Arial'
    });

    // 본문 영역
    s8.addText('@yield(\'content\')', {
        x: 0.8, y: 2.3, w: 3.9, h: 0.35,
        fontSize: 9, color: C.blue, fontFace: 'Courier New'
    });
    s8.addShape(pres.ShapeType.rect, {
        x: 0.8, y: 2.7, w: 3.9, h: 0.15, fill: { color: C.gray200 }
    });
    s8.addShape(pres.ShapeType.rect, {
        x: 0.8, y: 2.95, w: 3.0, h: 0.12, fill: { color: C.gray200 }
    });
    s8.addShape(pres.ShapeType.rect, {
        x: 0.8, y: 3.15, w: 3.5, h: 0.12, fill: { color: C.gray200 }
    });
    s8.addText('(각 Mailable에서 제공하는 본문)', {
        x: 0.8, y: 3.4, w: 3.9, h: 0.3,
        fontSize: 7, italic: true, color: C.gray400, fontFace: 'Arial'
    });

    // 푸터 영역
    s8.addShape(pres.ShapeType.rect, {
        x: 0.5, y: 4.2, w: 4.5, h: 0.01, fill: { color: C.gray300 }
    });
    s8.addText('{{ 회사명 }} | {{ 주소 }} | {{ 연락처 }}', {
        x: 0.8, y: 4.3, w: 3.9, h: 0.25,
        fontSize: 7, color: C.gray500, align: 'center', fontFace: 'Arial'
    });
    s8.addText('"SAM 시스템에서 발송된 메일입니다"', {
        x: 0.8, y: 4.55, w: 3.9, h: 0.25,
        fontSize: 7, italic: true, color: C.gray400, align: 'center', fontFace: 'Arial'
    });

    // 라벨
    // 화살표 + 라벨
    s8.addText('헤더 ─', { x: 4.1, y: 1.55, w: 1, h: 0.3, fontSize: 8, color: C.blue, align: 'right', fontFace: 'Arial' });
    s8.addText('본문 ─', { x: 4.1, y: 2.9, w: 1, h: 0.3, fontSize: 8, color: C.blue, align: 'right', fontFace: 'Arial' });
    s8.addText('푸터 ─', { x: 4.1, y: 4.35, w: 1, h: 0.3, fontSize: 8, color: C.blue, align: 'right', fontFace: 'Arial' });

    // 오른쪽: 브랜딩 요소 카드
    s8.addText('커스터마이징 요소', {
        x: 5.3, y: 1.3, w: 4, h: 0.35,
        fontSize: 12, bold: true, color: C.navy, fontFace: 'Arial'
    });

    const brandItems = [
        { icon: 'IMG', label: '로고 이미지', key: 'options.branding.logo_url', def: 'SAM BI 로고' },
        { icon: 'Co.', label: '회사명', key: 'options.branding.company_name', def: '(주)코드브릿지엑스' },
        { icon: 'Adr', label: '주소', key: 'options.branding.company_address', def: '(없음)' },
        { icon: 'Tel', label: '연락처', key: 'options.branding.company_phone', def: '(없음)' },
        { icon: 'CLR', label: '테마 컬러', key: 'options.branding.primary_color', def: '#1a56db' },
        { icon: 'Txt', label: '푸터 문구', key: 'options.branding.footer_text', def: 'SAM 시스템에서...' },
    ];

    brandItems.forEach((bi, i) => {
        const by = 1.8 + i * 0.52;
        s8.addShape(pres.ShapeType.roundRect, {
            x: 5.3, y: by, w: 4.2, h: 0.42, rectRadius: 0.06,
            fill: { color: C.gray100 }
        });
        s8.addShape(pres.ShapeType.roundRect, {
            x: 5.4, y: by + 0.06, w: 0.45, h: 0.3, rectRadius: 0.04,
            fill: { color: C.blue }
        });
        s8.addText(bi.icon, {
            x: 5.4, y: by + 0.06, w: 0.45, h: 0.3,
            fontSize: 7, bold: true, color: C.white,
            align: 'center', valign: 'middle', fontFace: 'Arial'
        });
        s8.addText(bi.label, {
            x: 5.95, y: by, w: 1.2, h: 0.42,
            fontSize: 9, bold: true, color: C.navy, valign: 'middle', fontFace: 'Arial'
        });
        s8.addText(bi.def, {
            x: 7.3, y: by, w: 2, h: 0.42,
            fontSize: 7, color: C.gray500, valign: 'middle', fontFace: 'Arial'
        });
    });

    addFooter(s8, 8, TOTAL);

    // ==============================
    // 슬라이드 9: 코드 전환 예시
    // ==============================
    const s9 = pres.addSlide();
    addPageHeader(s9, '코드 전환 예시', 'Before (직접 발송) → After (서비스 경유)');

    // Before 코드
    s9.addText('BEFORE (현재)', {
        x: 0.5, y: 1.3, w: 4.3, h: 0.35,
        fontSize: 11, bold: true, color: C.red, fontFace: 'Arial'
    });
    s9.addShape(pres.ShapeType.roundRect, {
        x: 0.5, y: 1.7, w: 4.3, h: 1.6, rectRadius: 0.1,
        fill: { color: C.navy }
    });
    s9.addText([
        { text: '// 컨트롤러에서 직접 발송\n', options: { color: C.gray500, fontSize: 8 } },
        { text: 'Mail', options: { color: C.blueLight, fontSize: 9, bold: true } },
        { text: '::', options: { color: C.gray400, fontSize: 9 } },
        { text: 'to', options: { color: C.green, fontSize: 9 } },
        { text: '($signer->email)\n', options: { color: C.gray300, fontSize: 9 } },
        { text: '  ->', options: { color: C.gray400, fontSize: 9 } },
        { text: 'send', options: { color: C.green, fontSize: 9 } },
        { text: '(\n    ', options: { color: C.gray400, fontSize: 9 } },
        { text: 'new ', options: { color: C.purple, fontSize: 9 } },
        { text: 'EsignRequestMail', options: { color: C.amber, fontSize: 9 } },
        { text: '(...)\n  );', options: { color: C.gray300, fontSize: 9 } },
    ], { x: 0.7, y: 1.8, w: 3.9, h: 1.4, fontFace: 'Courier New', lineSpacingMultiple: 1.4 });

    // 문제점
    s9.addShape(pres.ShapeType.roundRect, {
        x: 0.5, y: 3.45, w: 4.3, h: 0.7, rectRadius: 0.06,
        fill: { color: C.redBg }, line: { color: C.red, width: 0.5 }
    });
    s9.addText([
        { text: 'X ', options: { bold: true, color: C.red, fontSize: 8 } },
        { text: '항상 .env SMTP 사용\n', options: { color: C.gray600, fontSize: 8 } },
        { text: 'X ', options: { bold: true, color: C.red, fontSize: 8 } },
        { text: '발송 기록 없음 / 쿼터 확인 없음', options: { color: C.gray600, fontSize: 8 } },
    ], { x: 0.7, y: 3.5, w: 3.9, h: 0.6, fontFace: 'Arial', lineSpacingMultiple: 1.3 });

    // 화살표
    s9.addText('>>>', {
        x: 4.5, y: 2.2, w: 1, h: 0.5,
        fontSize: 20, bold: true, color: C.blue, align: 'center', fontFace: 'Arial'
    });

    // After 코드
    s9.addText('AFTER (전환 후)', {
        x: 5.2, y: 1.3, w: 4.3, h: 0.35,
        fontSize: 11, bold: true, color: C.green, fontFace: 'Arial'
    });
    s9.addShape(pres.ShapeType.roundRect, {
        x: 5.2, y: 1.7, w: 4.3, h: 1.6, rectRadius: 0.1,
        fill: { color: C.navy }
    });
    s9.addText([
        { text: '// TenantMailService 경유\n', options: { color: C.gray500, fontSize: 8 } },
        { text: 'app', options: { color: C.blueLight, fontSize: 9 } },
        { text: '(TenantMailService', options: { color: C.amber, fontSize: 9 } },
        { text: '::class)\n', options: { color: C.gray300, fontSize: 9 } },
        { text: '  ->', options: { color: C.gray400, fontSize: 9 } },
        { text: 'send', options: { color: C.green, fontSize: 9, bold: true } },
        { text: '(\n', options: { color: C.gray400, fontSize: 9 } },
        { text: '    mailable: ', options: { color: C.purple, fontSize: 8 } },
        { text: 'new EsignRequestMail(...),\n', options: { color: C.gray300, fontSize: 8 } },
        { text: '    to: ', options: { color: C.purple, fontSize: 8 } },
        { text: '$signer->email\n  );', options: { color: C.gray300, fontSize: 8 } },
    ], { x: 5.4, y: 1.8, w: 3.9, h: 1.4, fontFace: 'Courier New', lineSpacingMultiple: 1.4 });

    // 장점
    s9.addShape(pres.ShapeType.roundRect, {
        x: 5.2, y: 3.45, w: 4.3, h: 0.7, rectRadius: 0.06,
        fill: { color: C.greenBg }, line: { color: C.green, width: 0.5 }
    });
    s9.addText([
        { text: 'O ', options: { bold: true, color: C.green, fontSize: 8 } },
        { text: '테넌트 SMTP 자동 적용 + 브랜딩 주입\n', options: { color: C.gray600, fontSize: 8 } },
        { text: 'O ', options: { bold: true, color: C.green, fontSize: 8 } },
        { text: 'mail_logs 자동 기록 + 쿼터 확인', options: { color: C.gray600, fontSize: 8 } },
    ], { x: 5.4, y: 3.5, w: 3.9, h: 0.6, fontFace: 'Arial', lineSpacingMultiple: 1.3 });

    // 하단 주의사항
    s9.addShape(pres.ShapeType.roundRect, {
        x: 0.5, y: 4.35, w: 9, h: 0.65, rectRadius: 0.08,
        fill: { color: C.amberBg }, line: { color: C.amber, width: 0.5 }
    });
    s9.addText([
        { text: 'tenantId 자동 감지: ', options: { bold: true, color: C.amber, fontSize: 9 } },
        { text: 'TenantScope와 동일하게 세션/헤더에서 tenant_id를 자동 추출합니다. 명시적 전달도 가능합니다.', options: { color: C.gray600, fontSize: 9 } },
    ], { x: 0.7, y: 4.4, w: 8.6, h: 0.55, valign: 'middle', fontFace: 'Arial' });

    addFooter(s9, 9, TOTAL);

    // ==============================
    // 슬라이드 10: 보안 규칙
    // ==============================
    const s10 = pres.addSlide();
    addPageHeader(s10, '보안 규칙', 'SMTP 자격증명, 개인정보, 테넌트 격리');

    // 필수 준수
    s10.addText('필수 준수 사항', {
        x: 0.5, y: 1.25, w: 4.3, h: 0.35,
        fontSize: 12, bold: true, color: C.green, fontFace: 'Arial'
    });

    const mustDo = [
        'SMTP 비밀번호는 encrypt()로 암호화 저장',
        'mail_logs에 메일 본문 저장 금지 (메타데이터만)',
        '급여명세서 등 민감 메일은 related_model/related_id만 기록',
        'tenant_mail_configs 조회 시 TenantScope 자동 적용',
        'API 응답에 SMTP 비밀번호 노출 금지 ($hidden 처리)',
    ];

    mustDo.forEach((item, i) => {
        const iy = 1.7 + i * 0.48;
        s10.addShape(pres.ShapeType.roundRect, {
            x: 0.5, y: iy, w: 4.3, h: 0.38, rectRadius: 0.06,
            fill: { color: C.greenBg }
        });
        s10.addText([
            { text: 'O  ', options: { bold: true, color: C.green, fontSize: 10 } },
            { text: item, options: { color: C.gray700, fontSize: 8 } },
        ], { x: 0.7, y: iy, w: 3.9, h: 0.38, valign: 'middle', fontFace: 'Arial' });
    });

    // 금지 사항
    s10.addText('금지 사항', {
        x: 5.2, y: 1.25, w: 4.3, h: 0.35,
        fontSize: 12, bold: true, color: C.red, fontFace: 'Arial'
    });

    const mustNot = [
        'Mail::to() 직접 호출 (TenantMailService 사용)',
        '.env SMTP에 운영 크리덴셜 하드코딩',
        '타 테넌트 mail_logs 조회 (TenantScope로 방지)',
        '이메일 본문에 비밀번호 평문 포함 (임시비번 제외)',
    ];

    mustNot.forEach((item, i) => {
        const iy = 1.7 + i * 0.48;
        s10.addShape(pres.ShapeType.roundRect, {
            x: 5.2, y: iy, w: 4.3, h: 0.38, rectRadius: 0.06,
            fill: { color: C.redBg }
        });
        s10.addText([
            { text: 'X  ', options: { bold: true, color: C.red, fontSize: 10 } },
            { text: item, options: { color: C.gray700, fontSize: 8 } },
        ], { x: 5.4, y: iy, w: 3.9, h: 0.38, valign: 'middle', fontFace: 'Arial' });
    });

    // 하단: 암호화 흐름
    s10.addShape(pres.ShapeType.roundRect, {
        x: 0.5, y: 4.1, w: 9, h: 0.9, rectRadius: 0.1,
        fill: { color: C.navy }
    });
    s10.addText('SMTP 자격증명 암호화 흐름', {
        x: 0.7, y: 4.15, w: 5, h: 0.3,
        fontSize: 10, bold: true, color: C.blueLight, fontFace: 'Arial'
    });
    s10.addText([
        { text: '저장: ', options: { color: C.gray400, fontSize: 9 } },
        { text: 'encrypt($password)', options: { color: C.green, fontSize: 9, bold: true } },
        { text: ' → DB에 암호화된 문자열 저장     ', options: { color: C.gray400, fontSize: 9 } },
        { text: '조회: ', options: { color: C.gray400, fontSize: 9 } },
        { text: 'decrypt($encrypted)', options: { color: C.amber, fontSize: 9, bold: true } },
        { text: ' → SMTP 설정 시 복호화 사용', options: { color: C.gray400, fontSize: 9 } },
    ], { x: 0.7, y: 4.5, w: 8.6, h: 0.4, fontFace: 'Courier New' });

    addFooter(s10, 10, TOTAL);

    // ==============================
    // 슬라이드 11: 구현 로드맵
    // ==============================
    const s11 = pres.addSlide();
    addPageHeader(s11, '구현 로드맵', '4단계 점진적 구현 계획');

    const phases = [
        {
            num: '1', title: '기반 구축', priority: '필수',
            color: C.blue, bg: 'eff6ff', prColor: C.red,
            items: [
                'tenant_mail_configs 마이그레이션',
                'mail_logs 마이그레이션',
                'TenantMailService 생성',
                'TenantMailConfig / MailLog 모델',
            ]
        },
        {
            num: '2', title: '기존 전환', priority: '필수',
            color: C.green, bg: C.greenBg, prColor: C.red,
            items: [
                '5개 Mailable → TenantMailService 경유',
                'API EsignRequestMail 중복 제거',
                'sync/queue 모드 적용',
                'Fallback 전략 구현',
            ]
        },
        {
            num: '3', title: '브랜딩', priority: '중요',
            color: C.amber, bg: C.amberBg, prColor: C.amber,
            items: [
                '공통 레이아웃 Blade 생성',
                '테넌트별 로고/컬러/서명 적용',
                'MNG 메일 설정 관리 화면',
                '도메인 검증 가이드',
            ]
        },
        {
            num: '4', title: '고급 기능', priority: '권장',
            color: C.purple, bg: C.purpleBg, prColor: C.green,
            items: [
                '실패 재시도 (queue retry)',
                '바운스 처리',
                '발송 통계 대시보드',
                'Amazon SES / Mailgun 연동',
            ]
        },
    ];

    phases.forEach((phase, i) => {
        const px = 0.5 + i * 2.3;
        // 카드 배경
        s11.addShape(pres.ShapeType.roundRect, {
            x: px, y: 1.3, w: 2.1, h: 3.6, rectRadius: 0.1,
            fill: { color: phase.bg }, line: { color: phase.color, width: 1 }
        });
        // Phase 넘버
        s11.addShape(pres.ShapeType.ellipse, {
            x: px + 0.15, y: 1.4, w: 0.45, h: 0.45,
            fill: { color: phase.color }
        });
        s11.addText(phase.num, {
            x: px + 0.15, y: 1.4, w: 0.45, h: 0.45,
            fontSize: 16, bold: true, color: C.white,
            align: 'center', valign: 'middle', fontFace: 'Arial'
        });
        // 제목
        s11.addText(phase.title, {
            x: px + 0.7, y: 1.42, w: 1.2, h: 0.4,
            fontSize: 13, bold: true, color: phase.color, fontFace: 'Arial'
        });
        // 우선순위 배지
        s11.addShape(pres.ShapeType.roundRect, {
            x: px + 0.15, y: 1.95, w: 0.65, h: 0.22, rectRadius: 0.04,
            fill: { color: phase.prColor }
        });
        s11.addText(phase.priority, {
            x: px + 0.15, y: 1.95, w: 0.65, h: 0.22,
            fontSize: 7, bold: true, color: C.white,
            align: 'center', valign: 'middle', fontFace: 'Arial'
        });

        // 항목들
        phase.items.forEach((item, j) => {
            const iy = 2.35 + j * 0.58;
            s11.addShape(pres.ShapeType.roundRect, {
                x: px + 0.1, y: iy, w: 1.9, h: 0.48, rectRadius: 0.06,
                fill: { color: C.white }
            });
            s11.addText(item, {
                x: px + 0.2, y: iy, w: 1.7, h: 0.48,
                fontSize: 7.5, color: C.gray700, valign: 'middle', fontFace: 'Arial'
            });
        });

        // 화살표 (마지막 제외)
        if (i < 3) {
            s11.addText('>', {
                x: px + 2.1, y: 2.8, w: 0.2, h: 0.4,
                fontSize: 16, bold: true, color: C.gray400,
                align: 'center', valign: 'middle', fontFace: 'Arial'
            });
        }
    });

    addFooter(s11, 11, TOTAL);

    // ==============================
    // 슬라이드 12: Q&A
    // ==============================
    const s12 = pres.addSlide();
    s12.background = { fill: C.navy };
    s12.addShape(pres.ShapeType.rect, {
        x: 0, y: 0, w: 10, h: 0.08, fill: { color: C.blue }
    });

    // BI 로고
    s12.addImage({
        path: biLogoPath,
        x: 4.0, y: 1.2, w: 2.0, h: 0.85
    });

    s12.addText('Q & A', {
        x: 1, y: 2.3, w: 8, h: 0.8,
        fontSize: 42, bold: true, color: C.white,
        align: 'center', fontFace: 'Arial'
    });

    s12.addText('질문 및 논의 사항을 공유해 주세요', {
        x: 1, y: 3.2, w: 8, h: 0.5,
        fontSize: 14, color: C.gray400,
        align: 'center', fontFace: 'Arial'
    });

    // 구분선
    s12.addShape(pres.ShapeType.rect, {
        x: 3.5, y: 3.9, w: 3, h: 0.03, fill: { color: C.navyMid }
    });

    // 참조 문서
    s12.addText([
        { text: '기술 문서: ', options: { color: C.gray500, fontSize: 9 } },
        { text: 'docs/dev/standards/email-policy.md', options: { color: C.blueLight, fontSize: 9 } },
    ], { x: 1, y: 4.2, w: 8, h: 0.3, align: 'center', fontFace: 'Arial' });

    s12.addText('(주)코드브릿지엑스', {
        x: 1, y: 4.8, w: 8, h: 0.3,
        fontSize: 9, color: C.gray500,
        align: 'center', fontFace: 'Arial'
    });

    // === 저장 ===
    const outputPath = '/home/aweso/sam/docs/presentations/sam-email-policy.pptx';
    await pres.writeFile({ fileName: outputPath });
    console.log('PPTX created:', outputPath);
}

main().catch(console.error);
