Skip to main content
Glama

FSS Pension MCP Server

by ddoriboo
money-briefing-analyzer.html209 kB
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>머니브리핑 타겟팅 분석 서비스</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 100vh; padding: 20px; } .container { max-width: 1400px; margin: 0 auto; background: white; border-radius: 20px; box-shadow: 0 20px 40px rgba(0,0,0,0.1); overflow: hidden; } .header { background: linear-gradient(135deg, #4CAF50 0%, #45a049 100%); color: white; padding: 30px; text-align: center; } .header h1 { font-size: 2.5em; margin-bottom: 10px; } .header p { font-size: 1.2em; opacity: 0.9; } .tab-navigation { display: flex; background: #f8f9fa; border-bottom: 2px solid #e9ecef; } .tab-button { flex: 1; padding: 20px; background: none; border: none; font-size: 16px; font-weight: 500; cursor: pointer; transition: all 0.3s ease; color: #6c757d; } .tab-button.active { background: white; color: #4CAF50; border-bottom: 3px solid #4CAF50; } .tab-button:hover { background: #e9ecef; } .tab-content { display: none; padding: 30px; min-height: 600px; } .tab-content.active { display: block; } /* 브리핑 소재 탭 스타일 */ .briefing-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; margin-bottom: 30px; } .stat-card { background: linear-gradient(135deg, #e3f2fd 0%, #f3e5f5 100%); padding: 20px; border-radius: 15px; text-align: center; border-left: 5px solid #4CAF50; } .stat-number { font-size: 2em; font-weight: bold; color: #2c3e50; margin-bottom: 5px; } .stat-label { color: #6c757d; font-size: 14px; } .filter-section { margin-bottom: 30px; padding: 20px; background: #f8f9fa; border-radius: 15px; } .filter-buttons { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 15px; } .filter-btn { padding: 8px 16px; border: 2px solid #e9ecef; background: white; border-radius: 20px; cursor: pointer; transition: all 0.3s ease; font-size: 14px; } .filter-btn.active { background: #4CAF50; color: white; border-color: #4CAF50; } .search-box { margin-top: 15px; } .search-input { width: 100%; padding: 12px 20px; border: 2px solid #e9ecef; border-radius: 25px; font-size: 16px; outline: none; transition: border-color 0.3s ease; } .search-input:focus { border-color: #4CAF50; } .briefing-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(400px, 1fr)); gap: 20px; } .briefing-card { background: white; border: 2px solid #e9ecef; border-radius: 15px; padding: 20px; transition: all 0.3s ease; cursor: pointer; } .briefing-card:hover { border-color: #4CAF50; transform: translateY(-2px); box-shadow: 0 8px 25px rgba(0,0,0,0.1); } .briefing-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 15px; } .briefing-title { font-size: 18px; font-weight: 600; color: #2c3e50; flex: 1; margin-right: 10px; } .status-badge { padding: 4px 12px; border-radius: 15px; font-size: 12px; font-weight: 500; } .status-active { background: #d4edda; color: #155724; } .status-inactive { background: #f8d7da; color: #721c24; } .briefing-meta { display: flex; gap: 15px; margin-bottom: 10px; font-size: 14px; color: #6c757d; } .briefing-category { background: #e9ecef; padding: 4px 8px; border-radius: 10px; font-size: 12px; } .briefing-details { display: none; margin-top: 20px; padding-top: 20px; border-top: 2px solid #f8f9fa; } .briefing-details.show { display: block; } .detail-section { margin-bottom: 15px; } .detail-label { font-weight: 600; color: #495057; margin-bottom: 5px; } .detail-content { color: #6c757d; line-height: 1.5; } /* CDP 탭 스타일 */ .cdp-search { margin-bottom: 30px; } .query-input-container { display: flex; gap: 15px; margin-bottom: 20px; } .query-input { flex: 1; padding: 15px 20px; border: 2px solid #e9ecef; border-radius: 25px; font-size: 16px; outline: none; transition: border-color 0.3s ease; } .query-input:focus { border-color: #4CAF50; } .query-button { padding: 15px 30px; background: #4CAF50; color: white; border: none; border-radius: 25px; font-size: 16px; font-weight: 500; cursor: pointer; transition: background 0.3s ease; } .query-button:hover { background: #45a049; } .example-queries { display: flex; flex-wrap: wrap; gap: 10px; } .example-tag { padding: 8px 15px; background: #f8f9fa; border: 2px solid #e9ecef; border-radius: 20px; cursor: pointer; font-size: 14px; transition: all 0.3s ease; } .example-tag:hover { background: #4CAF50; color: white; border-color: #4CAF50; } .cdp-columns { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 20px; } .column-card { background: white; border: 2px solid #e9ecef; border-radius: 15px; padding: 15px; transition: all 0.3s ease; } .column-card:hover { border-color: #4CAF50; transform: translateY(-2px); } .column-name { font-weight: 600; color: #2c3e50; margin-bottom: 8px; font-size: 14px; } .column-description { color: #6c757d; font-size: 13px; line-height: 1.4; } .column-category { display: inline-block; padding: 2px 8px; background: #e9ecef; border-radius: 10px; font-size: 11px; margin-bottom: 8px; } .loading { text-align: center; padding: 40px; display: none; } .spinner { border: 4px solid #f3f3f3; border-top: 4px solid #4CAF50; border-radius: 50%; width: 50px; height: 50px; animation: spin 1s linear infinite; margin: 0 auto 20px; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .results-container { margin-top: 30px; padding: 20px; background: #f8f9fa; border-radius: 15px; display: none; } .results-container.show { display: block; } .recommendation-card { background: white; border-left: 5px solid #4CAF50; padding: 20px; margin-bottom: 15px; border-radius: 10px; } .recommendation-title { font-weight: 600; color: #2c3e50; margin-bottom: 10px; } .recommendation-content { color: #6c757d; } /* 추가 UI 개선 스타일 */ .copy-button { background: #4CAF50; color: white; border: none; padding: 5px 10px; border-radius: 5px; cursor: pointer; font-size: 12px; margin-left: 10px; transition: background 0.3s ease; } .copy-button:hover { background: #45a049; } .tooltip { position: relative; display: inline-block; } .tooltip .tooltiptext { visibility: hidden; width: 140px; background-color: #555; color: #fff; text-align: center; border-radius: 6px; padding: 5px; position: absolute; z-index: 1; bottom: 125%; left: 50%; margin-left: -70px; opacity: 0; transition: opacity 0.3s; font-size: 12px; } .tooltip:hover .tooltiptext { visibility: visible; opacity: 1; } .highlight { background-color: #fff3cd; padding: 2px 4px; border-radius: 3px; font-weight: 500; } .quick-stats { display: flex; gap: 15px; margin-bottom: 20px; font-size: 14px; color: #6c757d; } .quick-stat { display: flex; align-items: center; gap: 5px; } .export-button { background: #17a2b8; color: white; border: none; padding: 10px 20px; border-radius: 20px; cursor: pointer; font-size: 14px; margin-left: 15px; transition: background 0.3s ease; } .export-button:hover { background: #138496; } /* 분석 모드 선택 스타일 */ .analysis-mode-container { display: flex; align-items: center; gap: 15px; margin: 20px 0; padding: 15px; background: #f8f9fa; border-radius: 10px; } .analysis-mode-label { font-weight: 600; color: #495057; font-size: 14px; } .analysis-mode-buttons { display: flex; gap: 10px; } .mode-btn { padding: 12px 20px; border: 2px solid #e9ecef; background: white; border-radius: 10px; cursor: pointer; transition: all 0.3s ease; font-size: 14px; font-weight: 500; display: flex; flex-direction: column; align-items: center; gap: 5px; min-width: 140px; } .mode-btn:hover { border-color: #4CAF50; background: #f8fff8; } .mode-btn.active { border-color: #4CAF50; background: #4CAF50; color: white; } .mode-desc { font-size: 12px; opacity: 0.8; font-weight: 400; } /* 반응형 디자인 */ @media (max-width: 768px) { .container { margin: 10px; border-radius: 15px; } .header { padding: 20px; } .header h1 { font-size: 1.8em; } .tab-content { padding: 20px; } .briefing-cards { grid-template-columns: 1fr; } .cdp-columns { grid-template-columns: 1fr; } .query-input-container { flex-direction: column; } } /* 브리핑 생성 탭 스타일 */ .generator-header { text-align: center; margin-bottom: 30px; } .generator-header h2 { color: #4CAF50; margin-bottom: 10px; } .generator-header p { color: #6c757d; font-size: 16px; } .generator-input-section { background: #f8f9fa; border-radius: 15px; padding: 30px; margin-bottom: 30px; } .generator-input-container { display: flex; gap: 15px; margin-bottom: 20px; } .generator-input { flex: 1; padding: 15px; border: 2px solid #e9ecef; border-radius: 10px; font-size: 16px; font-family: inherit; resize: vertical; min-height: 80px; } .generator-input:focus { outline: none; border-color: #4CAF50; box-shadow: 0 0 0 3px rgba(76, 175, 80, 0.1); } .generator-button { background: linear-gradient(135deg, #4CAF50 0%, #45a049 100%); color: white; border: none; padding: 15px 25px; border-radius: 10px; font-size: 16px; font-weight: 600; cursor: pointer; transition: all 0.3s ease; white-space: nowrap; } .generator-button:hover { background: linear-gradient(135deg, #45a049 0%, #3d8b40 100%); transform: translateY(-2px); box-shadow: 0 5px 15px rgba(76, 175, 80, 0.3); } .generator-examples { border-top: 1px solid #e9ecef; padding-top: 20px; } .example-category { margin-bottom: 15px; } .example-category strong { color: #495057; margin-right: 10px; } .generator-results { display: grid; grid-template-columns: repeat(auto-fit, minmax(450px, 1fr)); gap: 20px; margin-top: 20px; } .generated-briefing-card { background: white; border-radius: 15px; padding: 25px; box-shadow: 0 5px 15px rgba(0,0,0,0.1); border-left: 5px solid #4CAF50; transition: all 0.3s ease; } .generated-briefing-card:hover { transform: translateY(-5px); box-shadow: 0 10px 25px rgba(0,0,0,0.15); } .generated-briefing-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 15px; } .generated-briefing-title { font-size: 18px; font-weight: 600; color: #2c3e50; flex: 1; } .generated-briefing-category { background: linear-gradient(135deg, #e3f2fd 0%, #f3e5f5 100%); color: #4CAF50; padding: 5px 12px; border-radius: 20px; font-size: 12px; font-weight: 500; margin-left: 10px; } .generated-briefing-content { background: #f8f9fa; padding: 15px; border-radius: 10px; margin-bottom: 15px; line-height: 1.6; } .generated-briefing-meta { display: grid; grid-template-columns: 1fr 1fr; gap: 15px; margin-bottom: 15px; } .generated-briefing-field { background: #f8f9fa; padding: 10px; border-radius: 8px; } .generated-briefing-label { font-size: 12px; font-weight: 600; color: #6c757d; margin-bottom: 5px; } .generated-briefing-value { font-size: 14px; color: #2c3e50; } .generated-briefing-reason { background: #e8f5e8; padding: 15px; border-radius: 10px; border-left: 4px solid #4CAF50; } .generated-briefing-reason-title { font-size: 14px; font-weight: 600; color: #2c3e50; margin-bottom: 8px; } .generated-briefing-reason-content { font-size: 13px; color: #495057; line-height: 1.5; } .loading-progress { width: 100%; background: #e9ecef; border-radius: 10px; overflow: hidden; margin-top: 20px; } .progress-bar { height: 6px; background: #e9ecef; border-radius: 3px; overflow: hidden; position: relative; } .progress-fill { height: 100%; background: linear-gradient(90deg, #4CAF50, #45a049); width: 0%; border-radius: 3px; animation: progressAnimation 3s ease-in-out infinite; } @keyframes progressAnimation { 0% { width: 0%; } 50% { width: 70%; } 100% { width: 100%; } } /* 자산 변동 브리핑 탭 스타일 */ .asset-header { text-align: center; margin-bottom: 30px; } .asset-header h2 { color: #4CAF50; margin-bottom: 10px; } .asset-header p { color: #6c757d; font-size: 16px; } .asset-input-section { background: #f8f9fa; border-radius: 15px; padding: 30px; margin-bottom: 30px; } .asset-input-section h3 { color: #2c3e50; margin-bottom: 20px; text-align: center; } .asset-form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 30px; margin-bottom: 30px; } .asset-category { background: white; border-radius: 15px; padding: 20px; border: 2px solid #e9ecef; transition: all 0.3s ease; } .asset-category:hover { border-color: #4CAF50; transform: translateY(-2px); box-shadow: 0 8px 25px rgba(0,0,0,0.1); } .asset-category h4 { color: #4CAF50; margin-bottom: 15px; text-align: center; font-size: 16px; } .input-group { margin-bottom: 15px; } .input-group label { display: block; margin-bottom: 5px; color: #495057; font-weight: 500; font-size: 14px; } .input-group input { width: 100%; padding: 12px; border: 2px solid #e9ecef; border-radius: 8px; font-size: 16px; transition: border-color 0.3s ease; } .input-group input:focus { outline: none; border-color: #4CAF50; } .asset-actions { display: flex; gap: 20px; justify-content: center; flex-wrap: wrap; } .asset-calculate-btn, .asset-generate-btn { padding: 15px 30px; border: none; border-radius: 25px; font-size: 16px; font-weight: 500; cursor: pointer; transition: all 0.3s ease; min-width: 200px; } .asset-calculate-btn { background: #17a2b8; color: white; } .asset-calculate-btn:hover { background: #138496; transform: translateY(-2px); } .asset-generate-btn { background: #4CAF50; color: white; } .asset-generate-btn:hover { background: #45a049; transform: translateY(-2px); } .asset-summary { background: #f8f9fa; border-radius: 15px; padding: 30px; margin-bottom: 30px; border-left: 5px solid #4CAF50; } .asset-summary h3 { color: #2c3e50; margin-bottom: 20px; text-align: center; } .summary-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 20px; } .summary-card { background: white; border-radius: 15px; padding: 20px; text-align: center; border: 2px solid #e9ecef; transition: all 0.3s ease; } .summary-card:hover { transform: translateY(-2px); box-shadow: 0 8px 25px rgba(0,0,0,0.1); } .summary-card.total { border-color: #4CAF50; } .summary-card.positive { border-color: #28a745; } .summary-card.negative { border-color: #dc3545; } .summary-title { font-size: 14px; color: #6c757d; margin-bottom: 10px; font-weight: 500; } .summary-value { font-size: 18px; font-weight: bold; color: #2c3e50; margin-bottom: 5px; } .summary-rate { font-size: 16px; font-weight: 600; } .summary-card.total .summary-rate { color: #4CAF50; } .summary-card.positive .summary-rate { color: #28a745; } .summary-card.negative .summary-rate { color: #dc3545; } .asset-briefings-results { margin-top: 30px; } .asset-briefing-card { border-left: 5px solid #4CAF50; } .landing-page-btn { background: #4CAF50; color: white; border: none; padding: 8px 16px; border-radius: 20px; cursor: pointer; font-size: 14px; transition: all 0.3s ease; } .landing-page-btn:hover { background: #45a049; transform: translateY(-1px); } .landing-page-info { background: #e3f2fd; border-radius: 10px; padding: 15px; margin-top: 15px; } .landing-page-label { font-weight: 600; color: #1976d2; margin-bottom: 8px; font-size: 14px; } .landing-page-details { font-size: 13px; color: #495057; } .landing-page-details div { margin-bottom: 5px; } /* 반응형 디자인 - 자산 탭 */ @media (max-width: 768px) { .asset-form-grid { grid-template-columns: 1fr; gap: 20px; } .asset-actions { flex-direction: column; align-items: center; } .asset-calculate-btn, .asset-generate-btn { min-width: 250px; } .summary-cards { grid-template-columns: 1fr; } } /* 랜딩 페이지 모달 스타일 */ .modal { position: fixed; z-index: 1000; left: 0; top: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.5); backdrop-filter: blur(5px); } .modal-content { background-color: white; margin: 5% auto; padding: 0; border-radius: 20px; width: 90%; max-width: 900px; max-height: 80vh; overflow-y: auto; box-shadow: 0 20px 40px rgba(0,0,0,0.2); animation: modalSlideIn 0.3s ease-out; } @keyframes modalSlideIn { from { opacity: 0; transform: translateY(-50px); } to { opacity: 1; transform: translateY(0); } } .modal-header { background: linear-gradient(135deg, #4CAF50 0%, #45a049 100%); color: white; padding: 20px 30px; border-radius: 20px 20px 0 0; display: flex; justify-content: space-between; align-items: center; } .modal-header h2 { margin: 0; font-size: 1.5em; } .close { color: white; font-size: 28px; font-weight: bold; cursor: pointer; transition: color 0.3s ease; } .close:hover { color: #f0f0f0; } .modal-body { padding: 30px; } .chart-container { background: #f8f9fa; border-radius: 15px; padding: 20px; margin: 20px 0; text-align: center; border: 2px solid #e9ecef; } .chart-placeholder { width: 100%; height: 200px; background: linear-gradient(45deg, #e3f2fd, #f3e5f5); border-radius: 10px; display: flex; align-items: center; justify-content: center; color: #6c757d; font-size: 16px; margin-bottom: 10px; } .insight-card { background: white; border: 2px solid #e9ecef; border-radius: 15px; padding: 20px; margin: 15px 0; border-left: 5px solid #4CAF50; } .insight-title { font-weight: 600; color: #4CAF50; margin-bottom: 10px; } .insight-content { color: #495057; line-height: 1.5; } .modal-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; margin: 20px 0; } .modal-stat-card { background: linear-gradient(135deg, #e3f2fd, #f3e5f5); border-radius: 15px; padding: 20px; text-align: center; } .modal-stat-value { font-size: 24px; font-weight: bold; color: #4CAF50; margin-bottom: 5px; } .modal-stat-label { color: #6c757d; font-size: 14px; } /* 모달 반응형 */ @media (max-width: 768px) { .modal-content { width: 95%; margin: 10% auto; max-height: 85vh; } .modal-header { padding: 15px 20px; } .modal-body { padding: 20px; } .modal-stats { grid-template-columns: 1fr; } } /* AI 브리핑 아이디어 섹션 스타일 */ .ai-ideas-section { background: #f8f9fa; border-radius: 15px; padding: 30px; margin-top: 30px; border-left: 5px solid #ff6b35; } .ai-ideas-header { text-align: center; margin-bottom: 30px; } .ai-ideas-header h2 { color: #ff6b35; margin-bottom: 10px; } .ai-ideas-header p { color: #6c757d; font-size: 16px; } .user-profile-section { background: white; border-radius: 15px; padding: 25px; margin-bottom: 30px; border: 2px solid #e9ecef; } .user-profile-section h3 { color: #2c3e50; margin-bottom: 20px; text-align: center; } .profile-form { margin-bottom: 25px; } .profile-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; margin-bottom: 20px; } .profile-group { display: flex; flex-direction: column; } .profile-group label { margin-bottom: 8px; font-weight: 600; color: #495057; font-size: 14px; } .profile-group select { padding: 12px; border: 2px solid #e9ecef; border-radius: 8px; font-size: 14px; transition: border-color 0.3s ease; background: white; } .profile-group select:focus { outline: none; border-color: #ff6b35; } .profile-actions { text-align: center; } .generate-ideas-btn { background: linear-gradient(135deg, #ff6b35, #f7931e); color: white; border: none; padding: 15px 30px; border-radius: 25px; font-size: 16px; font-weight: 500; cursor: pointer; transition: all 0.3s ease; min-width: 250px; } .generate-ideas-btn:hover { transform: translateY(-2px); box-shadow: 0 8px 25px rgba(255, 107, 53, 0.3); } .ideas-results { margin-top: 30px; } .idea-card { background: white; border-radius: 15px; padding: 25px; margin-bottom: 20px; border: 2px solid #e9ecef; border-left: 5px solid #ff6b35; transition: all 0.3s ease; } .idea-card:hover { transform: translateY(-2px); box-shadow: 0 8px 25px rgba(0,0,0,0.1); border-color: #ff6b35; } .idea-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; } .idea-title { font-size: 18px; font-weight: 600; color: #2c3e50; } .idea-category { background: linear-gradient(135deg, #ff6b35, #f7931e); color: white; padding: 4px 12px; border-radius: 15px; font-size: 12px; font-weight: 500; } .idea-description { color: #495057; line-height: 1.6; margin-bottom: 15px; } .idea-features { background: #f8f9fa; border-radius: 10px; padding: 15px; margin-bottom: 15px; } .idea-features h4 { color: #ff6b35; margin-bottom: 10px; font-size: 14px; } .idea-features ul { list-style: none; padding: 0; margin: 0; } .idea-features li { padding: 3px 0; color: #6c757d; font-size: 13px; } .idea-features li:before { content: "▪ "; color: #ff6b35; font-weight: bold; } .idea-actions { display: flex; gap: 10px; justify-content: flex-end; } .implement-idea-btn { background: #ff6b35; color: white; border: none; padding: 8px 16px; border-radius: 20px; font-size: 13px; cursor: pointer; transition: all 0.3s ease; } .implement-idea-btn:hover { background: #e55a2b; transform: translateY(-1px); } .rate-idea-btn { background: transparent; color: #6c757d; border: 2px solid #e9ecef; padding: 8px 16px; border-radius: 20px; font-size: 13px; cursor: pointer; transition: all 0.3s ease; } .rate-idea-btn:hover { border-color: #ff6b35; color: #ff6b35; } .ai-ideas-toggle { text-align: center; margin: 30px 0; } /* 프로필 폼 반응형 */ @media (max-width: 768px) { .profile-row { grid-template-columns: 1fr; gap: 15px; } .generate-ideas-btn { min-width: 100%; } .idea-header { flex-direction: column; align-items: flex-start; gap: 10px; } .idea-actions { flex-direction: column; gap: 8px; } .implement-idea-btn, .rate-idea-btn { width: 100%; } } </style> </head> <body> <div class="container"> <div class="header"> <div style="display: flex; justify-content: space-between; align-items: center;"> <div> <h1>💰 머니브리핑 타겟팅 분석 서비스</h1> <p>네이버페이 머니브리핑 소재별 고객 타겟팅 최적화를 위한 분석 도구</p> </div> <button class="export-button" onclick="exportBriefingData()"> 📊 데이터 내보내기 </button> </div> </div> <div class="tab-navigation"> <button class="tab-button active" onclick="switchTab('briefings')"> 📋 브리핑 소재 분석 </button> <button class="tab-button" onclick="switchTab('cdp')"> 🎯 CDP 기반 타겟팅 </button> <button class="tab-button" onclick="switchTab('generator')"> ✨ 브리핑 생성 </button> <button class="tab-button" onclick="switchTab('asset')"> 💰 자산 변동 브리핑 </button> </div> <!-- 브리핑 소재 분석 탭 --> <div class="tab-content active" id="briefings-tab"> <div class="briefing-stats"> <div class="stat-card"> <div class="stat-number" id="totalBriefings">67</div> <div class="stat-label">총 브리핑 소재</div> </div> <div class="stat-card"> <div class="stat-number" id="activeBriefings">45</div> <div class="stat-label">현재 노출 중</div> </div> <div class="stat-card"> <div class="stat-number" id="inactiveBriefings">22</div> <div class="stat-label">노출 예정</div> </div> <div class="stat-card"> <div class="stat-number" id="completedBriefings">57</div> <div class="stat-label">개발 완료</div> </div> </div> <div class="filter-section"> <div class="filter-buttons"> <button class="filter-btn active" onclick="filterBriefings('all')">전체</button> <button class="filter-btn" onclick="filterBriefings('생활과 연관된 돈')">생활과 연관된 돈</button> <button class="filter-btn" onclick="filterBriefings('불린 돈')">불린 돈</button> <button class="filter-btn" onclick="filterBriefings('빌린 돈')">빌린 돈</button> <button class="filter-btn" onclick="filterBriefings('나간 돈')">나간 돈</button> <button class="filter-btn" onclick="filterBriefings('들어오는 돈')">들어오는 돈</button> <button class="filter-btn" onclick="filterBriefings('미래를 위한 돈')">미래를 위한 돈</button> <button class="filter-btn" onclick="filterBriefings('경제/자산컨텐츠')">경제/자산컨텐츠</button> </div> <div class="search-box"> <input type="text" class="search-input" placeholder="브리핑 제목이나 내용으로 검색..." onkeyup="searchBriefings(this.value)"> </div> </div> <div class="briefing-cards" id="briefingCards"> <!-- 브리핑 카드들이 여기에 동적으로 생성됩니다 --> </div> </div> <!-- CDP 기반 타겟팅 탭 --> <div class="tab-content" id="cdp-tab"> <div class="cdp-search"> <div class="query-input-container"> <input type="text" class="query-input" id="queryInput" placeholder="예: 대출 니즈가 높은 20-30대 여성 고객을 찾아주세요"> <button class="query-button" onclick="analyzeQuery()">🔍 분석</button> </div> <!-- 분석 모드 선택 --> <div class="analysis-mode-container"> <div class="analysis-mode-label">분석 모드:</div> <div class="analysis-mode-buttons"> <button class="mode-btn active" id="keywordMode" onclick="setAnalysisMode('keyword')"> 🔤 키워드 기반 <span class="mode-desc">빠르고 간단한 분석</span> </button> <button class="mode-btn" id="llmMode" onclick="setAnalysisMode('llm')"> 🤖 LLM 기반 <span class="mode-desc">정확하고 상세한 분석</span> </button> </div> </div> <div class="example-queries"> <div class="example-tag" onclick="setExampleQuery('대출 니즈가 높은 고객군')">💰 대출 니즈 고객</div> <div class="example-tag" onclick="setExampleQuery('20-30대 여성 중 뷰티에 관심이 많은 고객')">💄 뷰티 관심 여성</div> <div class="example-tag" onclick="setExampleQuery('고소득층 중 투자 상품에 관심있는 고객')">📈 투자 관심 고객</div> <div class="example-tag" onclick="setExampleQuery('해외여행을 자주 가는 고객')">✈️ 해외여행 고객</div> <div class="example-tag" onclick="setExampleQuery('1인 가구 중 배달음식을 자주 시키는 고객')">🏠 1인가구 배달족</div> <div class="example-tag" onclick="setExampleQuery('골프를 치는 프리미엄 고객')">⛳ 골프 VIP</div> </div> </div> <div class="loading" id="loadingSection"> <div class="spinner"></div> <p>🤖 CDP 데이터를 분석하여 최적의 고객 세그먼트를 찾고 있습니다...</p> </div> <div class="results-container" id="resultsContainer"> <div id="analysisResults"></div> </div> <div class="filter-section"> <h3>📊 CDP 컬럼 브라우저</h3> <div class="filter-buttons"> <button class="filter-btn active" onclick="filterColumns('all')">전체</button> <button class="filter-btn" onclick="filterColumns('interests')">관심사 지표</button> <button class="filter-btn" onclick="filterColumns('industries')">업종별 지표</button> <button class="filter-btn" onclick="filterColumns('scores')">예측 스코어</button> <button class="filter-btn" onclick="filterColumns('flags')">플래그 지표</button> </div> <div class="search-box"> <input type="text" class="search-input" placeholder="컬럼명이나 설명으로 검색..." onkeyup="searchColumns(this.value)"> </div> </div> <div class="cdp-columns" id="cdpColumns"> <!-- CDP 컬럼들이 여기에 동적으로 생성됩니다 --> </div> </div> <!-- 브리핑 생성 탭 --> <div class="tab-content" id="generator-tab"> <div class="generator-header"> <h2>✨ 새로운 브리핑 소재 생성</h2> <p>아이디어나 키워드를 입력하면 AI가 6개의 새로운 머니브리핑 소재를 생성해드립니다.</p> </div> <div class="generator-input-section"> <div class="generator-input-container"> <textarea class="generator-input" id="generatorInput" rows="3" placeholder="예: 겨울철 난방비 절약을 위한 브리핑 소재를 만들어주세요&#10;혹은: 20-30대 직장인을 위한 연말정산 관련 브리핑"></textarea> <button class="generator-button" onclick="generateBriefings()"> 🚀 브리핑 생성하기 </button> </div> <div class="generator-examples"> <div class="example-category"> <strong>💡 예시 아이디어:</strong> <div class="example-tag" onclick="setGeneratorExample('20-30대 직장인을 위한 연말정산 관련 브리핑')">📊 연말정산</div> <div class="example-tag" onclick="setGeneratorExample('겨울철 난방비 절약을 위한 브리핑')">🔥 난방비 절약</div> <div class="example-tag" onclick="setGeneratorExample('신혼부부를 위한 주택 관련 브리핑')">🏠 신혼부부 주택</div> <div class="example-tag" onclick="setGeneratorExample('대학생을 위한 용돈 관리 브리핑')">🎓 대학생 용돈</div> <div class="example-tag" onclick="setGeneratorExample('중년층을 위한 노후 준비 브리핑')">👴 노후 준비</div> <div class="example-tag" onclick="setGeneratorExample('1인 가구를 위한 절약 브리핑')">🏠 1인가구 절약</div> </div> </div> </div> <!-- 로딩 섹션 --> <div class="loading-section" id="generatorLoadingSection" style="display: none;"> <div class="loading-spinner">🤖</div> <p>AI가 새로운 브리핑 소재를 생성하고 있습니다...</p> <div class="loading-progress"> <div class="progress-bar"> <div class="progress-fill"></div> </div> </div> </div> <!-- 생성 결과 --> <div class="generator-results" id="generatorResults"> <!-- 생성된 브리핑들이 여기에 표시됩니다 --> </div> </div> <!-- 자산 변동 브리핑 탭 --> <div class="tab-content" id="asset-tab"> <div class="asset-header"> <h2>💰 자산 변동 브리핑</h2> <p>개인 자산 데이터를 입력하고 AI가 맞춤형 자산 변동 브리핑을 생성해드립니다.</p> </div> <!-- 자산 데이터 입력 섹션 --> <div class="asset-input-section"> <h3>자산 데이터 입력</h3> <div class="asset-form-grid"> <div class="asset-category"> <h4>💳 은행 자산</h4> <div class="input-group"> <label>현재 은행 잔액 (만원)</label> <input type="number" id="currBankValue" placeholder="5,000" value="5000"> </div> <div class="input-group"> <label>전일 은행 잔액 (만원)</label> <input type="number" id="prevBankValue" placeholder="4,800" value="4800"> </div> </div> <div class="asset-category"> <h4>📈 증권 자산</h4> <div class="input-group"> <label>현재 증권 평가액 (만원)</label> <input type="number" id="currStockValue" placeholder="8,000" value="8000"> </div> <div class="input-group"> <label>전일 증권 평가액 (만원)</label> <input type="number" id="prevStockValue" placeholder="7,500" value="7500"> </div> </div> <div class="asset-category"> <h4>🏠 부동산 자산</h4> <div class="input-group"> <label>현재 부동산 시세 (만원)</label> <input type="number" id="currRealestateValue" placeholder="50,000" value="50000"> </div> <div class="input-group"> <label>전일 부동산 시세 (만원)</label> <input type="number" id="prevRealestateValue" placeholder="49,500" value="49500"> </div> </div> <div class="asset-category"> <h4>🎯 연금/IRP</h4> <div class="input-group"> <label>현재 연금 평가액 (만원)</label> <input type="number" id="currPensionValue" placeholder="3,000" value="3000"> </div> <div class="input-group"> <label>전일 연금 평가액 (만원)</label> <input type="number" id="prevPensionValue" placeholder="2,950" value="2950"> </div> </div> <div class="asset-category"> <h4>💸 대출/카드</h4> <div class="input-group"> <label>현재 대출 잔액 (만원)</label> <input type="number" id="currLoanBalance" placeholder="15,000" value="15000"> </div> <div class="input-group"> <label>전일 대출 잔액 (만원)</label> <input type="number" id="prevLoanBalance" placeholder="15,100" value="15100"> </div> <div class="input-group"> <label>현재 카드 청구액 (만원)</label> <input type="number" id="currCardPaymentDue" placeholder="150" value="150"> </div> <div class="input-group"> <label>전일 카드 청구액 (만원)</label> <input type="number" id="prevCardPaymentDue" placeholder="200" value="200"> </div> </div> <div class="asset-category"> <h4>🚗 기타 자산</h4> <div class="input-group"> <label>현재 자동차 시세 (만원)</label> <input type="number" id="currCarValue" placeholder="2,500" value="2500"> </div> <div class="input-group"> <label>전일 자동차 시세 (만원)</label> <input type="number" id="prevCarValue" placeholder="2,500" value="2500"> </div> <div class="input-group"> <label>현재 포인트/머니 (만원)</label> <input type="number" id="currPointmoneyValue" placeholder="50" value="50"> </div> <div class="input-group"> <label>전일 포인트/머니 (만원)</label> <input type="number" id="prevPointmoneyValue" placeholder="45" value="45"> </div> </div> </div> <div class="asset-actions"> <button class="asset-calculate-btn" onclick="calculateAssetChanges()"> 📊 자산 변동 계산하기 </button> <button class="asset-generate-btn" onclick="generateAssetBriefings()"> 🤖 AI 브리핑 생성하기 </button> </div> </div> <!-- 자산 변동 요약 대시보드 --> <div class="asset-summary" id="assetSummary" style="display: none;"> <h3>자산 변동 요약</h3> <div class="summary-cards"> <div class="summary-card total"> <div class="summary-title">총 자산 변동</div> <div class="summary-value" id="totalAssetChange">+1,205만원</div> <div class="summary-rate" id="totalAssetChangeRate">+2.3%</div> </div> <div class="summary-card positive"> <div class="summary-title">가장 큰 증가</div> <div class="summary-value" id="biggestIncrease">주식 +500만원</div> <div class="summary-rate" id="biggestIncreaseRate">+6.7%</div> </div> <div class="summary-card negative"> <div class="summary-title">가장 큰 감소</div> <div class="summary-value" id="biggestDecrease">카드청구 -50만원</div> <div class="summary-rate" id="biggestDecreaseRate">-25%</div> </div> </div> </div> <!-- 로딩 섹션 --> <div class="loading-section" id="assetLoadingSection" style="display: none;"> <div class="loading-spinner">💰</div> <p>AI가 자산 변동을 분석하고 맞춤형 브리핑을 생성하고 있습니다...</p> <div class="loading-progress"> <div class="progress-bar"> <div class="progress-fill"></div> </div> </div> </div> <!-- 생성된 자산 브리핑 결과 --> <div class="asset-briefings-results" id="assetBriefingsResults"> <!-- 생성된 자산 브리핑들이 여기에 표시됩니다 --> </div> <!-- AI 브리핑 아이디어 섹션 --> <div class="ai-ideas-section" id="aiIdeasSection" style="display: none;"> <div class="ai-ideas-header"> <h2>💡 AI 브리핑 아이디어</h2> <p>당신의 자산 프로필을 분석하여 창의적이고 개인화된 브리핑 아이디어를 제안합니다.</p> </div> <!-- 사용자 프로필 입력 --> <div class="user-profile-section"> <h3>👤 사용자 프로필 설정</h3> <div class="profile-form"> <div class="profile-row"> <div class="profile-group"> <label>연령대</label> <select id="userAge"> <option value="20s">20대</option> <option value="30s" selected>30대</option> <option value="40s">40대</option> <option value="50s">50대</option> <option value="60s+">60대 이상</option> </select> </div> <div class="profile-group"> <label>직업군</label> <select id="userJob"> <option value="office_worker" selected>직장인</option> <option value="business_owner">사업자</option> <option value="freelancer">프리랜서</option> <option value="student">학생</option> <option value="housewife">주부</option> <option value="retiree">은퇴자</option> </select> </div> <div class="profile-group"> <label>투자 성향</label> <select id="investmentStyle"> <option value="conservative">안정형</option> <option value="moderate" selected>중간형</option> <option value="aggressive">적극형</option> <option value="speculative">투기형</option> </select> </div> </div> <div class="profile-row"> <div class="profile-group"> <label>라이프스타일</label> <select id="lifestyle"> <option value="frugal">절약형</option> <option value="balanced" selected>균형형</option> <option value="luxury">소비형</option> <option value="minimalist">미니멀형</option> </select> </div> <div class="profile-group"> <label>관심 분야</label> <select id="interests"> <option value="tech" selected>IT/기술</option> <option value="real_estate">부동산</option> <option value="stocks">주식투자</option> <option value="travel">여행</option> <option value="education">교육</option> <option value="health">건강</option> </select> </div> <div class="profile-group"> <label>금융 목표</label> <select id="financialGoal"> <option value="emergency_fund">비상자금 마련</option> <option value="house_purchase">내집마련</option> <option value="retirement" selected>노후준비</option> <option value="wealth_building">자산증대</option> <option value="debt_reduction">부채상환</option> </select> </div> </div> </div> <div class="profile-actions"> <button class="generate-ideas-btn" onclick="generateCreativeIdeas()"> 🧠 창의적 브리핑 아이디어 생성 </button> </div> </div> <!-- 로딩 섹션 --> <div class="loading-section" id="ideasLoadingSection" style="display: none;"> <div class="loading-spinner">🧠</div> <p>AI가 당신만의 특별한 브리핑 아이디어를 고민하고 있습니다...</p> <div class="loading-progress"> <div class="progress-bar"> <div class="progress-fill"></div> </div> </div> </div> <!-- 생성된 아이디어 결과 --> <div class="ideas-results" id="ideasResults"> <!-- 생성된 아이디어들이 여기에 표시됩니다 --> </div> </div> <!-- AI 아이디어 표시 버튼 --> <div class="ai-ideas-toggle" style="text-align: center; margin: 30px 0;"> <button class="asset-generate-btn" onclick="toggleAiIdeasSection()"> 💡 AI 브리핑 아이디어 보기 </button> </div> </div> </div> <!-- 랜딩 페이지 모달 --> <div id="landingPageModal" class="modal" style="display: none;"> <div class="modal-content"> <div class="modal-header"> <h2 id="modalTitle">랜딩 페이지</h2> <span class="close" onclick="closeLandingPage()">&times;</span> </div> <div class="modal-body" id="modalBody"> <!-- 동적으로 생성되는 랜딩 페이지 콘텐츠 --> </div> </div> </div> <script> // 머니브리핑 데이터 (전체 67개) const MONEY_BRIEFINGS = [ {"no": 1, "exposed": "O", "status": "완료", "type": "생활과 연관된 돈", "service": "내자산", "templateId": "expire_20250604150738", "title": "만기 연장 안내", "content": "28일전 : 00일 뒤에 자산연결이 종료돼요! 연장하지 않으면 자산확인이 어려워요.\n당일 : 오늘, 자산연결이 종료돼요! 연장하지 않으면 자산확인이 어려워요.", "button": "다시 연결하기", "target": "만기연장 자산이 있는 경우 15일 전에 브리핑 노출"}, {"no": 2, "exposed": "O", "status": "완료", "type": "생활과 연관된 돈", "service": "내자산", "templateId": "CARD_20250602123538", "title": "새 카드 발견", "content": "{카드명} 발급 완료! 내자산에 연결하고 이용내역 확인하세요.", "button": "새 카드 연결하기", "target": "새로운 카드 자산 발견 시"}, {"no": 3, "exposed": "O", "status": "완료", "type": "나간 돈", "service": "내자산", "templateId": "CARD_20250602124028", "title": "카드 청구서 도착", "content": "{청구월}월에 내야할 {금융사명} 결제금액은 {청구금액}원이에요.", "button": "청구서 확인하기", "target": "새로운 청구서 발행 시"}, {"no": 4, "exposed": "O", "status": "완료", "type": "나간 돈", "service": "내자산", "templateId": "CARD_20250602124341", "title": "카드 결제일", "content": "{청구금액}원이 오늘 내 계좌에서 빠져나갈 예정이에요.", "button": "청구서 확인하기", "target": "청구서의 결제일이 오늘일 경우"}, {"no": 5, "exposed": "O", "status": "완료", "type": "생활과 연관된 돈", "service": "내자산", "templateId": "POINT_20250604162215", "title": "포인트 사용 안내", "content": "Npay로 전환 가능한 포인트가 {금액} 있어요", "button": "전환가능 포인트 확인하기", "target": "전환 가능한 포인트가 500원 이상 있는 사용자"}, {"no": 6, "exposed": "X", "status": "완료", "type": "생활과 연관된 돈", "service": "내자산", "templateId": "POINT_20250604162405", "title": "포인트 사용 안내", "content": "소멸 예정인 포인트가 있어요!", "button": "내 포인트 확인하기", "target": "소멸 예정 포인트가 있는 사용자"}, {"no": 7, "exposed": "O", "status": "완료", "type": "불린 돈", "service": "내자산", "templateId": "BANK_20250602121139", "title": "예적금 만기 알림", "content": "{금융상품명} 만기일 7일전이에요. 만기 전에 가입 상품 확인해보세요.", "button": "내 상품 만기 확인하기", "target": "예적금 상품만기 7일전, 만기 당일"}, {"no": 8, "exposed": "O", "status": "완료", "type": "미래를 위한 돈", "service": "내자산", "templateId": "BANK_20250602122931", "title": "예적금 신규 가입", "content": "{금융상품명} 개설 완료! 내자산에 연결하고 한번에 확인하세요.", "button": "가입한 상품 확인하기", "target": "예적금 상품 가입 당일"}, {"no": 9, "exposed": "X", "status": "완료", "type": "나간 돈", "service": "내자산", "templateId": "BANK_20250602122729", "title": "거액 출금 발생", "content": "거액 출금이 발생했어요! 거래내역이 맞는지 확인해보세요.", "button": "출금 계좌 확인하기", "target": "300만원 이상 출금 발생 직후"}, {"no": 10, "exposed": "X", "status": "삭제", "type": "미래를 위한 돈", "service": "내자산", "templateId": "BANK_20250602115930", "title": "예상 이자 확인", "content": "제외", "button": "예상이자 확인하기", "target": "예적금 가입자 대상 월 1회"}, {"no": 11, "exposed": "X", "status": "완료", "type": "생활과 연관된 돈", "service": "내자산", "templateId": "BANK_20250602120924", "title": "숨은 돈 찾기", "content": "잊고 있던 내 계좌에서 숨은 돈을 찾아보세요!", "button": "계좌내역 확인하기", "target": "미사용 계좌가 있는 가입자 월 1회"}, {"no": 12, "exposed": "X", "status": "완료", "type": "미래를 위한 돈", "service": "내자산", "templateId": "PENSION_20250602125726", "title": "연금 개시 예정", "content": "{금융상품명} 연금 개시일이 {n}일전으로 다가 왔어요!", "button": "내 연금 확인하기", "target": "연금 개시일 도래 3개월 전, 7일 전"}, {"no": 13, "exposed": "X", "status": "삭제", "type": "미래를 위한 돈", "service": "내자산", "templateId": "PENSION_20250602125914", "title": "연금 미납 알림", "content": "제외", "button": "내 연금 확인하기", "target": "연금 미납 2개월 이상"}, {"no": 14, "exposed": "O", "status": "완료", "type": "불린 돈", "service": "내자산", "templateId": "STOCK_20250602130143", "title": "배당금 입금", "content": "{종목명}의 배당금이 계좌에 입금되었어요.", "button": "배당금 확인하기", "target": "마데 거래내역에서 배당금 텍스트 있는 사용자"}, {"no": 15, "exposed": "X", "status": "완료", "type": "불린 돈", "service": "내자산", "templateId": "STOCK_20250602130349", "title": "평가금액 변동", "content": "주식 평가금액이 3일전과 비교하여 변동되었네요.", "button": "내 종목내역 확인하기", "target": "계좌에서 주식 평가금액이 5% 이상 늘어난 사용자"}, {"no": 16, "exposed": "X", "status": "완료", "type": "미래를 위한 돈", "service": "내자산", "templateId": "STOCK_20250604151823", "title": "예수금 발견", "content": "내 주식 계좌에 {예수금금액} 원이 쌓여있어요!", "button": "미리 관리하러가기!", "target": "100만원 이상 예수금이 쌓여 있는 계좌가 있는 사용자"}, {"no": 17, "exposed": "O", "status": "완료", "type": "불린 돈", "service": "내자산", "templateId": "STOCK_20250602133502", "title": "새 증권계좌 발견", "content": "{금융기관명}의 신규 증권계좌 추가! 내 자산의 포트폴리오를 구성해보세요!", "button": "주식 계좌 확인하기", "target": "증권 서비스의 새로운 계좌가 있는 사용자"}, {"no": 18, "exposed": "O", "status": "완료", "type": "불린 돈", "service": "내자산", "templateId": "STOCK_20250604153239", "title": "청약일정 확인해보세요!", "content": "이번 주 청약 예정 종목 모아봤어요. 어떤 종목이 있는지 확인해보세요.", "button": "", "target": ""}, {"no": 19, "exposed": "O", "status": "완료", "type": "생활과 연관된 돈", "service": "내자산", "templateId": "PFMS_20250604131606", "title": "이번달 지출분석", "content": "이번달 지출이 가장 많은 곳을 알려드려요.", "button": "이번달 지출분석보기", "target": "월말 1회 타겟팅하여 머니브리핑 제공"}, {"no": 20, "exposed": "X", "status": "완료", "type": "생활과 연관된 돈", "service": "내자산", "templateId": "PFMS_20250604131446", "title": "수입지출 관련 소식", "content": "오늘의 행운글자 확인하고 포인트 받으세요!", "button": "포인트 받으러 가기", "target": "방문이 많지 않은 사용자 대상으로 행운글자 이벤트"}, {"no": 21, "exposed": "O", "status": "완료", "type": "생활과 연관된 돈", "service": "신용점수", "templateId": "CREDIT_20250602145632", "title": "신용점수 변동", "content": "신용점수가 최근에 바뀌었어요. 어떻게 변했는지 확인해보세요.", "button": "내 점수변동 📊 확인하기", "target": "신용점수 변동된 대상자"}, {"no": 22, "exposed": "O", "status": "완료", "type": "경제/자산컨텐츠", "service": "신용점수", "templateId": "CREDIT_20250602145426", "title": "대출리포트 발행", "content": "이번 달 대출리포트가 발행되었어요! 상세한 내용을 확인해보세요.", "button": "대출리포트 🧾 자세히보기", "target": "대출리포트 발행된 대상자"}, {"no": 23, "exposed": "O", "status": "완료", "type": "경제/자산컨텐츠", "service": "신용점수", "templateId": "CREDIT_20250602152021", "title": "최저금리 변동", "content": "이번 달 예상 대출 최저금리가 달라졌어요! 얼마나 변동됐는지 확인해보세요.", "button": "정확한 조건 🧾 비교하기", "target": "대출리포트 내 예상금리 변동 대상자"}, {"no": 24, "exposed": "O", "status": "완료", "type": "생활과 연관된 돈", "service": "신용점수", "templateId": "CREDIT_20250602152325", "title": "놓친 신용조회", "content": "{이름}님이 확인을 놓친 신용조회가 있어요!", "button": "놓친 조회 🔍 확인하기", "target": "신용조회 발생 후 확인하지 않은 대상자"}, {"no": 25, "exposed": "X", "status": "완료", "type": "생활과 연관된 돈", "service": "신용점수", "templateId": "CREDIT_20250602152449", "title": "놓친 신용변동", "content": "{이름}님이 확인을 놓친 신용변동이 있어요!", "button": "놓친 변동 🔍 확인하기", "target": "신용변동 내역 발생 후 확인하지 않은 대상자"}, {"no": 26, "exposed": "O", "status": "삭제", "type": "생활과 연관된 돈", "service": "신용점수", "templateId": "CREDIT_20250602152626", "title": "신용변동 발생", "content": "(개발x)", "button": "내 정보변동 확인", "target": "신용정보 변동내역 확인하지 않은 대상자"}, {"no": 27, "exposed": "O", "status": "완료", "type": "생활과 연관된 돈", "service": "신용점수", "templateId": "CREDIT_20250602152731", "title": "신용점수 올리기", "content": "{이름}님이 신용점수를 올릴 수 있는 기회가 생겼어요!", "button": "지금 📈 점수 올리기", "target": "신용점수 서비스 가입자 전체"}, {"no": 28, "exposed": "O", "status": "완료", "type": "빌린 돈", "service": "대출", "templateId": "LOAN_20250602152842", "title": "새로 추가된 대출 계좌", "content": "{금융사명}에서 새로 추가된 대출을 내자산에서 관리해보세요.", "button": "내 대출 확인하기", "target": "전일 기준 새로운 대출계좌가 개설이 된 사용자"}, {"no": 29, "exposed": "X", "status": "완료", "type": "경제/자산컨텐츠", "service": "대출", "templateId": "LOAN_20250602153132", "title": "대출 관련 소식", "content": "개발 진행 중", "button": "정부의 한도 축소 정책 알아보기", "target": "대출비교 서비스 이용자 전체"}, {"no": 30, "exposed": "X", "status": "완료", "type": "경제/자산컨텐츠", "service": "대출", "templateId": "LOAN_20250602153238", "title": "대출 관련 소식", "content": "개발 진행 중", "button": "정부의 한도 확대 소식 알아보기", "target": "대출비교 서비스 이용자 전체"}, {"no": 31, "exposed": "X", "status": "완료", "type": "경제/자산컨텐츠", "service": "대출", "templateId": "LOAN_20250602153617", "title": "대출 관련 소식", "content": "개발 진행 중", "button": "정부 지원 대출 알아보기", "target": "대출비교 서비스 이용자 전체"}, {"no": 32, "exposed": "X", "status": "완료", "type": "경제/자산컨텐츠", "service": "대출", "templateId": "LOAN_20250602154218", "title": "대출 관련 소식", "content": "개발 진행 중", "button": "변동 사항 확인하기", "target": "대출비교 서비스 이용자 전체"}, {"no": 33, "exposed": "O", "status": "완료", "type": "빌린 돈", "service": "대출", "templateId": "LOAN_20250602194218", "title": "대출 심사 결과", "content": "{이름}님의 신용대출 심사 결과, 최대한도 {n,nnn}만원, 최저금리 {nn.nn%} 상품을 확인하세요!", "button": "심사 결과 보기", "target": "신용대출비교 서비스 이용자"}, {"no": 34, "exposed": "O", "status": "완료", "type": "빌린 돈", "service": "대출", "templateId": "LOAN_20250602195616", "title": "신청 중인 대출", "content": "{이름}님 신청 중인 신용대출이 있습니다. 오늘이 지나면 조건이 달라질 수 있어요", "button": "신청 이어하기", "target": "신용대출비교 서비스 이용자"}, {"no": 35, "exposed": "X", "status": "완료", "type": "빌린 돈", "service": "대출", "templateId": "LOAN_20250602193623", "title": "대출 심사 결과", "content": "개발 진행 중", "button": "신청하러 가기", "target": "신용대출비교 서비스 이용자"}, {"no": 36, "exposed": "X", "status": "완료", "type": "빌린 돈", "service": "대출", "templateId": "LOAN_20250602200339", "title": "대출 관련 소식", "content": "개발 진행 중", "button": "단독 혜택 확인하기", "target": "대출비교 서비스 이용자 (직전 3개월)"}, {"no": 37, "exposed": "O", "status": "완료", "type": "빌린 돈", "service": "대출", "templateId": "LOAN_20250602200847", "title": "이자 납입일", "content": "{금융기관명}의 대출 이자 납입일 3일전이에요.", "button": "이번 달 이자 확인하기", "target": "마이데이터 내에서 대출 연동한 이용자"}, {"no": 38, "exposed": "O", "status": "완료", "type": "빌린 돈", "service": "대출", "templateId": "LOAN_20250602201013", "title": "대출 만기 예정", "content": "이용하고 있는 {금융기관}의 대출상품 만기가 00일 남았어여!", "button": "내 대출 보기", "target": "마이데이터 내에서 대출 연동한 이용자"}, {"no": 39, "exposed": "O", "status": "완료", "type": "빌린 돈", "service": "대출", "templateId": "rentloan_20250604095636", "title": "대출 심사 결과", "content": "{이름}님의 주택담보대출 심사 결과, 최대한도 {n,nnn}만원, 최저금리 {nn.nn%} 상품을 확인하세요!", "button": "비교 결과 확인하기", "target": "주택담보대출(신규/대환) 대출 비교 서비스 이용자"}, {"no": 40, "exposed": "X", "status": "완료", "type": "빌린 돈", "service": "대출", "templateId": "rentloan_20250602202229", "title": "대출 심사 결과", "content": "{이름}님의 전월세대출 심사 결과, 최대한도 {n,nnn}만원, 최저금리 {nn.nn%} 상품을 확인하세요!", "button": "비교 결과 확인하기", "target": "전월세대출(신규/대환) 대출 비교 서비스 이용자"}, {"no": 41, "exposed": "O", "status": "완료", "type": "빌린 돈", "service": "대출", "templateId": "houseloan_20250602202355", "title": "대출 심사 결과", "content": "오늘이 지나면 주택담보대출 조건이 달라질 수 있어요! 결과가 만료되기 전 다시 확인해 볼까요?", "button": "비교 결과 확인하기", "target": "주택담보대출(신규/대환) 대출 조회 결과 승인 1건 이상"}, {"no": 42, "exposed": "O", "status": "완료", "type": "빌린 돈", "service": "대출", "templateId": "rentloan_20250603114240", "title": "대출 심사 결과", "content": "오늘이 지나면 전월세대출 조건이 달라질 수 있어요! 결과가 만료되기 전 다시 확인해 볼까요?", "button": "비교 결과 확인하기", "target": "전월세대출(신규/대환) 대출 조회 결과 승인 1건 이상"}, {"no": 43, "exposed": "X", "status": "삭제", "type": "빌린 돈", "service": "대출", "templateId": "houseloan_20250603114345", "title": "대출 관련 소식", "content": "", "button": "주택담보대출 금리 확인하기", "target": "주택담보대출 대출 비교 서비스 이용 약관 동의 이후 90일"}, {"no": 44, "exposed": "X", "status": "삭제", "type": "빌린 돈", "service": "대출", "templateId": "houseloan_20250604092521", "title": "대출 관련 소식", "content": "", "button": "대출 갈아타고 이자 아끼기", "target": "마이데이터 내 주택담보대출 연동한 사용자"}, {"no": 45, "exposed": "O", "status": "삭제", "type": "빌린 돈", "service": "대출", "templateId": "houseloan_20250602201221", "title": "대출 관련 소식", "content": "", "button": "대출 갈아타고 이자 아끼기", "target": "마이데이터 내 전월세대출 연동한 사용자"}, {"no": 46, "exposed": "X", "status": "삭제", "type": "빌린 돈", "service": "대출", "templateId": "houseloan_20250604100424", "title": "대출 관련 소식", "content": "", "button": "주택담보대출 비교하기", "target": "주택담보대출(신규/대환) 신규 금융사 라이브"}, {"no": 47, "exposed": "X", "status": "삭제", "type": "빌린 돈", "service": "대출", "templateId": "rentloan_20250604121056", "title": "대출 관련 소식", "content": "", "button": "전월세대출 비교하기", "target": "전월세대출(신규/대환) 신규 금융사 라이브"}, {"no": 48, "exposed": "X", "status": "삭제", "type": "빌린 돈", "service": "대출", "templateId": "houseloan_20250604121211", "title": "대출 관련 소식", "content": "", "button": "내 대출 한도 확인하기", "target": "시세가 없는 관심부동산에 시세가 생성된 경우"}, {"no": 49, "exposed": "O", "status": "완료", "type": "경제/자산컨텐츠", "service": "대출", "templateId": "LOAN_20250627142856", "title": "대출 관련 소식", "content": "머니스토리 컨텐츠 (내용 그때 그때 달라짐)", "button": "대출규제 내용 확인하기", "target": "머니브리핑 게시물 발행"}, {"no": 50, "exposed": "X", "status": "완료", "type": "경제/자산컨텐츠", "service": "대출", "templateId": "LOAN_20250604155931", "title": "대출 관련 소식", "content": "머니스토리 대체", "button": "대출규제 내용 확인하기", "target": "머니브리핑 게시물 발행"}, {"no": 51, "exposed": "X", "status": "삭제", "type": "경제/자산컨텐츠", "service": "대출", "templateId": "rentloan_20250604125234", "title": "대출 관련 소식", "content": "", "button": "전월세대출 금리 확인하기", "target": "전월세대출 대출 비교 서비스 이용 약관 동의 이후 30일"}, {"no": 52, "exposed": "X", "status": "완료", "type": "나간 돈", "service": "보험", "templateId": "INSURANCE_20250604133400", "title": "보험 납입일", "content": "개발 진행 중", "button": "오늘 나갈 보험료💰 확인해보기", "target": "마이데이터 > 보험가입자"}, {"no": 53, "exposed": "X", "status": "완료", "type": "생활과 연관된 돈", "service": "보험", "templateId": "INSURANCE_20250604133732", "title": "자동차보험 만기 예정 / 만기일", "content": "30일 뒤에 {보험상품명} 보장이 끝나요. 갱신을 놓쳐서 과태료 내지 않도록 내 보험에서 관리해보세요.", "button": "보험 계약 갱신하기", "target": "자동차보험 갱신 이력 존재하는 경우"}, {"no": 54, "exposed": "O", "status": "완료", "type": "생활과 연관된 돈", "service": "보험", "templateId": "travelinsu_20250709111335", "title": "해외여행 준비", "content": "아직 준비 안했다면, [페이회원명]님 해외여행 [4박5일]동안 사고에 대비하세요.", "button": "안전여행 준비하기", "target": "해외여행보험 비교서비스 비교완료 후 이탈한 사용자"}, {"no": 55, "exposed": "X", "status": "완료", "type": "나간 돈", "service": "보험", "templateId": "INSURANCE_20250604134608", "title": "보험 납입 종료 예정", "content": "개발 진행 중", "button": "내 보험 확인해보기", "target": "보험 갱신 이력 존재하는 경우"}, {"no": 56, "exposed": "X", "status": "완료", "type": "생활과 연관된 돈", "service": "보험", "templateId": "INSURANCE_20250604135005", "title": "보험 만기 예정", "content": "개발 진행 중", "button": "만기된 내 보험 살펴보기", "target": "보험 갱신 이력 존재하는 경우"}, {"no": 57, "exposed": "X", "status": "완료", "type": "생활과 연관된 돈", "service": "보험", "templateId": "INSURANCE_20250604135244", "title": "보험 관련 소식", "content": "개발 진행중", "button": "내 보험 관리하기", "target": "같은 종류의 보험이 2개 이상인 고객"}, {"no": 58, "exposed": "O", "status": "완료", "type": "들어오는 돈", "service": "페이머니", "templateId": "payment_20250616172151", "title": "페이머니 충전 완료", "content": "예약하신 페이머니 {금액}원이 충전되었어요", "button": "예약 충전 확인하기", "target": "예약 충전된 금액이 충전된 사용자"}, {"no": 59, "exposed": "X", "status": "완료", "type": "들어오는 돈", "service": "페이머니", "templateId": "NPAY_20250604132751", "title": "머니통장 관련 소식", "content": "머니 통장-하나 {N}월 이자가 {금액}원 입금되었어요!", "button": "내 통장 이자 확인하기", "target": "머니 통장의 이자가 입금된 사용자"}, {"no": 60, "exposed": "X", "status": "완료", "type": "들어오는 돈", "service": "페이머니", "templateId": "NPAY_20250604133027", "title": "페이머니 관련 소식", "content": "0월 김페이님은 {포인트적립금액}원을 적립했어요!", "button": "Npay포인트 확인하기", "target": "매월 말일에 포인트 적립을 10,000원이상 쌓은 고객"}, {"no": 61, "exposed": "O", "status": "완료", "type": "들어오는 돈", "service": "송금", "templateId": "REMIT_20250604135509", "title": "송금 도착", "content": "{김페이}님이 {송금금액}원을 보냈어요. 돈을 받아주세요.", "button": "받을 송금 확인하러 가기", "target": ""}, {"no": 62, "exposed": "O", "status": "완료", "type": "나간 돈", "service": "송금", "templateId": "REMIT_20250604140006", "title": "예약송금 예정", "content": "내일 예약송금 {건수}건이 실행 예정입니다.", "button": "예약송금 확인하러 가기", "target": ""}, {"no": 63, "exposed": "O", "status": "완료", "type": "나간 돈", "service": "후불결제", "templateId": "PAYLATER_20250604140217", "title": "후불결제 납부", "content": "{**월 **일} 후불결제 납부금액은 {납부금액}원입니다. 납부 내역을 확인해 보세요.", "button": "후불결제 납부액 확인", "target": ""}, {"no": 64, "exposed": "O", "status": "완료", "type": "나간 돈", "service": "후불결제", "templateId": "PAYLATER_20250604140520", "title": "후불결제 연체", "content": "후불결제로 {연체금액}원 연체 중이에요. 이용에 어려움이 없도록 빠르게 납부하세요.", "button": "후불결제 연체액 확인", "target": ""}, {"no": 65, "exposed": "O", "status": "완료", "type": "미래를 위한 돈", "service": "우리집", "templateId": "MYHOUSE_20250604141759", "title": "신규 실거래가 알림", "content": "{단지명} {면적}㎡ {거래유형} 실거래가가 등록됐어요.", "button": "실거래가 보기", "target": "실거래가 등록 되었을때 발송"}, {"no": 66, "exposed": "O", "status": "완료", "type": "미래를 위한 돈", "service": "우리집", "templateId": "MYHOUSE_20250604142912", "title": "신규 시세 알림", "content": "{단지명} {면적}㎡ {거래유형} {데이터 수급처} 최신 시세가 등록됐어요.", "button": "시세 확인하기", "target": "최근 시세가 등록되었을 때 발송"}, {"no": 67, "exposed": "O", "status": "완료", "type": "경제/자산컨텐츠", "service": "머니스토리", "templateId": "mstory_20250604143012", "title": "머니스토리 컨텐츠", "content": "머니스토리 컨텐츠로 매일 다르게 발송 중", "button": "콘텐츠 더보기", "target": "현재 내자산 등록자 대상으로 발송 중"} ]; // CDP 컬럼 데이터 const CDP_COLUMNS = { basic: { 'mbr_id_no': '네이버 IDNO' }, interests: { 'fa_int_householdsingle': '최근 1개월 1인 가구 관련 상품 결제 또는 오피스텔/원룸 거주 추정 고객', 'fa_int_householdpet': '최근 1개월 동물용품/동물병원 결제 고객', 'fa_int_householdchild': '최근 1개월 어린이 관련 상품 결제 고객', 'fa_int_householdbaby': '최근 1개월 영유아 관련 상품 결제 또는 출산 정책지원금 수령 고객', 'fa_int_householdyouth': '최근 1개월 중고등학생 관련 상품 결제 고객', 'fa_int_publictransport': '최근 1개월 Npay 교통카드 이용 또는 교통비 결제 고객', 'fa_int_motorcycle': '최근 1개월 오토바이 관련 상품 결제 고객', 'fa_int_loan1stfinancial': '최근 1개월 1금융권에서 신용 대출 실행 고객', 'fa_int_loan2ndfinancial': '최근 1개월 저축은행, 카드사, 보험사, 증권사 등에서 신용 대출을 실행 고객', 'fa_int_loanpersonal': '최근 1개월 신용대출을 실행 고객', 'fa_int_saving': '최근 1개월 예적금 개설 고객', 'fa_int_jeonsemonthlyrent': '최근 24개월 계좌 및 대출이력을 통한 전월세 거주 추정 고객', 'fa_int_homeappliance': '최근 1개월 가전 상품 결제 고객', 'fa_int_luxury': '최근 1개월 100만원 이상 명품관련 결제 고객', 'fa_int_delivery': '최근 1개월 식비 목적의배달 결제 고객', 'fa_int_mutualaidservice': '최근 1개월 상조서비스 관련 결제 고객', 'fa_int_interior': '최근 1개월 인테리어 관련 상품 결제 고객', 'fa_int_carinsurance': '향후 1개월 자동차 보험 결제 예정으로 추정되는 고객(과거 동월 포함)', 'fa_int_carpurchase': '최근 1개월 마이카 및 오토론을 통한 차량 구매 추정 고객', 'fa_int_overseasshopping': '최근 1개월 해외직구 결제 고객', 'fa_int_traveldomestic': '최근 1개월 국내여행 관련 상품 결제 고객', 'fa_int_travelpackage': '최근 1개월 여행사 패키지 상품 결제 고객', 'fa_int_traveloverseas': '향후 1개월 내 해외 여행 목적의 출국 예정 추정 고객', 'fa_int_travelasia': '향후 1개월 내 아시아 지역으로 해외여행 목적의 출국 예정 추정 고객', 'fa_int_golf': '최근 1개월 골프용품/골프장 관련 상품 결제 고객', 'fa_int_running': '최근 1개월 러닝/마라톤 관련 상품 결제 고객', 'fa_int_swimming': '최근 1개월 수영 관련 상품 결제 고객', 'fa_int_pilatesyoga': '최근 1개월 필라테스/요가 관련 상품 결제 고객', 'fa_int_gym': '최근 1개월 피트니스/헬스장 가맹점 결제 고객', 'fa_int_wedding': '최근 1개월 결혼 준비 관련 상품 결제 및 활동 발생 고객', 'fa_int_retirement': '향후 24개월 내 은퇴 예정으로 추정되는 고객', 'fa_int_move': '최근 1개월 주소지 변경이력 존재 또는 이사 관련 상품 결제 고객', 'fa_int_childbirth': '최근 1개월 임신/출산 관련 상품 결제 고객', 'fa_int_highincome': '최근 12개월 Nice 추정소득 1억이상 고객', 'fa_int_homeowner': '최근 12개월 주택 소유 추정 고객', 'fa_int_business': '대출 등을 통한 사업자 추정 고객', 'fa_int_youngprofessional': '최근 1개월 급여입금을 통해 취직 추정 고객', 'fa_int_pharmaceutical': '최근 1개월 제약 B2B 가맹점 고객', 'fa_int_worker': '최근 2개월 정기적으로 급여 받는 고객', 'fa_int_fishing': '최근 1개월 낚시 관련 상품 결제 고객', 'fa_int_diet': '최근 1개월 다이어트 목적의 상품 결제 고객', 'fa_int_alcohol': '최근 1개월 주류 관련 상품 결제 고객', 'fa_int_ott': '최근 1개월 OTT 관련 결제 고객' }, industries: { 'fa_ind_education': '최근 1개월 업종>교육 결제 고객', 'fa_ind_academy': '최근 1개월 업종>교육>학원 결제 고객', 'fa_ind_technicacademy': '최근 1개월 업종>교육>학원>기능학원 결제 고객', 'fa_ind_languageacademy': '최근 1개월 업종>교육>학원>외국어학원 결제 고객', 'fa_ind_drivingacademy': '최근 1개월 업종>교육>학원>운전면허학원 결제 고객', 'fa_ind_codingacademy': '최근 1개월 업종>교육>학원>프로그래밍/코딩 결제 고객', 'fa_ind_transportation': '최근 1개월 업종>교통 결제 고객', 'fa_ind_rentcar': '최근 1개월 업종>교통>렌터카 결제 고객', 'fa_ind_taxi': '최근 1개월 업종>교통>택시 결제 고객', 'fa_ind_airsevice': '최근 1개월 업종>교통>항공 결제 고객', 'fa_ind_finance': '최근 1개월 업종>금융 결제 고객', 'fa_ind_insurance': '최근 1개월 업종>금융>보험 결제 고객', 'fa_ind_card': '최근 1개월 업종>금융>카드 결제 고객', 'fa_ind_mobility': '최근 1개월 업종>모빌리티 결제 고객', 'fa_ind_carwash': '최근 1개월 업종>모빌리티>모빌리티 서비스>세차장 결제 고객', 'fa_ind_parkinglot': '최근 1개월 업종>모빌리티>모빌리티 서비스>주차장 결제 고객', 'fa_ind_culturehobby': '최근 1개월 업종>문화/취미 결제 고객', 'fa_ind_golfcourse': '최근 1개월 업종>문화/취미>레포츠시설>골프장 결제 고객', 'fa_ind_fitness': '최근 1개월 업종>문화/취미>레포츠시설>피트니스 결제 고객', 'fa_ind_cinema': '최근 1개월 업종>문화/취미>영화/엔터>영화 결제 고객', 'fa_ind_game': '최근 1개월 업종>문화/취미>컨텐츠 서비스>게임 결제 고객', 'fa_ind_ott': '최근 1개월 업종>문화/취미>영상/음악>OTT/영상 결제 고객', 'fa_ind_beauty': '최근 1개월 업종>미용 결제 고객', 'fa_ind_beautysalon': '최근 1개월 업종>미용>미용실 결제 고객', 'fa_ind_massage': '최근 1개월 업종>미용>안마/스포츠마사지 결제 고객', 'fa_ind_medical': '최근 1개월 업종>의료 결제 고객', 'fa_ind_pharmacy': '최근 1개월 업종>의료>약국 결제 고객', 'fa_ind_specialtymall': '최근 1개월 업종>전문판매 결제 고객', 'fa_ind_cosmetic': '최근 1개월 업종>전문판매>뷰티 결제 고객', 'fa_ind_food': '최근 1개월 업종>전문판매>식품 결제 고객', 'fa_ind_golfequipmnt': '최근 1개월 업종>전문판매>아웃도어>골프 결제 고객', 'fa_ind_fashion': '최근 1개월 업종>전문판매>패션의류>패션의류 결제 고객', 'fa_ind_generalmall': '최근 1개월 업종>종합판매 결제 고객', 'fa_ind_departmentstr': '최근 1개월 업종>종합판매>백화점 결제 고객', 'fa_ind_conveniencestr': '최근 1개월 업종>종합판매>편의점 결제 고객', 'fa_ind_foodbeverage': '최근 1개월 업종>F&B 결제 고객', 'fa_ind_restaurant': '최근 1개월 업종>F&B>음식점 결제 고객', 'fa_ind_fastfood': '최근 1개월 업종>F&B>음식점>패스트푸드 결제 고객', 'fa_ind_cafe': '최근 1개월 업종>F&B>카페 결제 고객', 'fa_ind_koreancuisine': '최근 1개월 업종>F&B>음식점>한식 결제 고객' }, scores: { 'sc_int_householdsingle': '최근 1개월 1인 가구 관련 상품 결제 또는 오피스텔/원룸 거주 추정 고객 (예측스코어)', 'sc_int_householdpet': '최근 1개월 동물용품/동물병원 결제 고객 (예측스코어)', 'sc_int_loan1stfinancial': '최근 1개월 1금융권에서 신용 대출 실행 고객 (예측스코어)', 'sc_int_loanpersonal': '최근 1개월 신용대출 실행 고객 (예측스코어)', 'sc_int_saving': '최근 1개월 예적금 개설 고객 (예측스코어)', 'sc_int_luxury': '최근 1개월 100만원 이상 명품관련 결제 고객 (예측스코어)', 'sc_int_delivery': '최근 1개월 식비 목적의 배달 결제 고객 (예측스코어)', 'sc_int_traveloverseas': '향후 1개월 내 해외 여행 목적의 출국 예정 추정 고객 (예측스코어)', 'sc_int_golf': '최근 1개월 골프용품/골프장 관련 상품 결제 고객 (예측스코어)', 'sc_int_gym': '최근 1개월 피트니스/헬스장 가맹점 결제 고객 (예측스코어)', 'sc_int_wedding': '최근 1개월 결혼 준비 관련 상품 결제 및 활동 발생한 고객 (예측스코어)', 'sc_int_highincome': '최근 12개월 nice 추정소득 1억이상 고객 (예측스코어)', 'sc_int_homeowner': '최근 12개월 주택 소유 추정 고객 (예측스코어)', 'sc_int_business': '대출 등을 통한 사업자 추정 고객 (예측스코어)', 'sc_ind_beauty': '최근 1개월 업종>미용 결제 고객 (예측스코어)', 'sc_ind_golfcourse': '최근 1개월 업종>문화/취미>레포츠시설>골프장 결제 고객 (예측스코어)', 'sc_ind_cosmetic': '최근 1개월 업종>전문판매>뷰티 결제 고객 (예측스코어)', 'sc_ind_cafe': '최근 1개월 업종>F&B>카페 결제 고객 (예측스코어)', 'sc_ind_restaurant': '최근 1개월 업종>F&B>음식점 결제 고객 (예측스코어)' }, flags: { 'flag_young_adult': '20-35세 연령대 플래그', 'flag_middle_age': '36-50세 연령대 플래그', 'flag_senior': '51세 이상 연령대 플래그', 'flag_high_spender': '월 100만원 이상 고액 결제자 플래그', 'flag_frequent_user': '주 3회 이상 Npay 이용자 플래그', 'flag_new_user': '최근 3개월 내 신규 가입자 플래그', 'flag_dormant_user': '3개월 이상 미이용자 플래그', 'flag_premium_service': '프리미엄 서비스 이용자 플래그' } }; // 자산 데이터 구조 (만원 단위) let MOCK_ASSET_DATA = { current: { CURR_BANK_VALUE: 5000, // 5천만원 -> 5000만원 CURR_CAR_VALUE: 2500, // 2천5백만원 -> 2500만원 CURR_CARD_PAYMENT_DUE: 150, // 150만원 -> 150만원 CURR_LOAN_BALANCE: 15000, // 1억5천만원 -> 15000만원 CURR_PENSION_VALUE: 3000, // 3천만원 -> 3000만원 CURR_POINTMONEY_VALUE: 50, // 50만원 -> 50만원 CURR_REALESTATE_VALUE: 50000, // 5억원 -> 50000만원 CURR_STOCK_VALUE: 8000, // 8천만원 -> 8000만원 CURRENT_DATE: "2025-01-21", CURRENT_TOTAL_ASSET_VALUE: 0 // 계산으로 업데이트 }, previous: { PREV_BANK_VALUE: 4800, // 4천8백만원 -> 4800만원 PREV_CAR_VALUE: 2500, // 2천5백만원 -> 2500만원 PREV_CARD_PAYMENT_DUE: 200, // 200만원 -> 200만원 PREV_LOAN_BALANCE: 15100, // 1억5천1백만원 -> 15100만원 PREV_PENSION_VALUE: 2950, // 2천9백50만원 -> 2950만원 PREV_POINTMONEY_VALUE: 45, // 45만원 -> 45만원 PREV_REALESTATE_VALUE: 49500, // 4억9천5백만원 -> 49500만원 PREV_STOCK_VALUE: 7500, // 7천5백만원 -> 7500만원 PREVIOUS_DATE: "2025-01-20", PREVIOUS_TOTAL_ASSET_VALUE: 0 // 계산으로 업데이트 } }; let currentBriefings = MONEY_BRIEFINGS; let currentColumns = {}; let currentAnalysisMode = 'keyword'; // 기본값은 키워드 기반 let assetData = MOCK_ASSET_DATA; // 자산 데이터 상태 관리 // 탭 전환 함수 function switchTab(tabName) { // 모든 탭 버튼과 컨텐츠 비활성화 document.querySelectorAll('.tab-button').forEach(btn => btn.classList.remove('active')); document.querySelectorAll('.tab-content').forEach(content => content.classList.remove('active')); // 선택된 탭 활성화 document.querySelector(`[onclick="switchTab('${tabName}')"]`).classList.add('active'); document.getElementById(`${tabName}-tab`).classList.add('active'); if (tabName === 'briefings') { renderBriefingCards(); } else if (tabName === 'cdp') { renderCDPColumns(); } else if (tabName === 'generator') { // 브리핑 생성 탭 초기화 initializeGeneratorTab(); } else if (tabName === 'asset') { // 자산 변동 브리핑 탭 초기화 initializeAssetTab(); } } // 브리핑 카드 렌더링 function renderBriefingCards() { const container = document.getElementById('briefingCards'); container.innerHTML = ''; currentBriefings.forEach(briefing => { const card = document.createElement('div'); card.className = 'briefing-card'; card.innerHTML = ` <div class="briefing-header"> <div class="briefing-title">${briefing.title}</div> <div style="display: flex; align-items: center; gap: 10px;"> <div class="status-badge ${briefing.exposed === 'O' ? 'status-active' : 'status-inactive'}"> ${briefing.exposed === 'O' ? '노출 중' : '비노출'} </div> <button class="copy-button tooltip" onclick="copyBriefingInfo(${briefing.no})"> 📋 <span class="tooltiptext">브리핑 정보 복사</span> </button> </div> </div> <div class="briefing-meta"> <span>No. ${briefing.no}</span> <span>${briefing.service}</span> <span>${briefing.status}</span> </div> <div class="briefing-category">${briefing.type}</div> <div class="briefing-details" id="details-${briefing.no}"> <div class="detail-section"> <div class="detail-label">📝 브리핑 내용</div> <div class="detail-content">${briefing.content}</div> </div> <div class="detail-section"> <div class="detail-label">🎯 타겟 고객</div> <div class="detail-content">${briefing.target}</div> </div> <div class="detail-section"> <div class="detail-label">🔗 버튼 액션</div> <div class="detail-content">${briefing.button}</div> </div> <div class="detail-section"> <div class="detail-label">🏷️ 템플릿 ID</div> <div class="detail-content">${briefing.templateId}</div> </div> </div> `; card.addEventListener('click', () => { const details = document.getElementById(`details-${briefing.no}`); details.classList.toggle('show'); }); container.appendChild(card); }); } // 브리핑 필터링 function filterBriefings(type) { // 필터 버튼 활성화 상태 변경 document.querySelectorAll('.filter-btn').forEach(btn => btn.classList.remove('active')); event.target.classList.add('active'); if (type === 'all') { currentBriefings = MONEY_BRIEFINGS; } else { currentBriefings = MONEY_BRIEFINGS.filter(briefing => briefing.type === type); } renderBriefingCards(); } // 필터 버튼 텍스트 업데이트 (개수 포함) function updateFilterButtonCounts() { const typeCounts = {}; MONEY_BRIEFINGS.forEach(briefing => { typeCounts[briefing.type] = (typeCounts[briefing.type] || 0) + 1; }); // 필터 버튼 HTML 업데이트 const filterButtons = document.querySelector('.filter-buttons'); if (filterButtons) { filterButtons.innerHTML = ` <button class="filter-btn active" onclick="filterBriefings('all')">전체 (${MONEY_BRIEFINGS.length})</button> <button class="filter-btn" onclick="filterBriefings('생활과 연관된 돈')">생활과 연관된 돈 (${typeCounts['생활과 연관된 돈'] || 0})</button> <button class="filter-btn" onclick="filterBriefings('불린 돈')">불린 돈 (${typeCounts['불린 돈'] || 0})</button> <button class="filter-btn" onclick="filterBriefings('빌린 돈')">빌린 돈 (${typeCounts['빌린 돈'] || 0})</button> <button class="filter-btn" onclick="filterBriefings('나간 돈')">나간 돈 (${typeCounts['나간 돈'] || 0})</button> <button class="filter-btn" onclick="filterBriefings('들어오는 돈')">들어오는 돈 (${typeCounts['들어오는 돈'] || 0})</button> <button class="filter-btn" onclick="filterBriefings('미래를 위한 돈')">미래를 위한 돈 (${typeCounts['미래를 위한 돈'] || 0})</button> <button class="filter-btn" onclick="filterBriefings('경제/자산컨텐츠')">경제/자산컨텐츠 (${typeCounts['경제/자산컨텐츠'] || 0})</button> `; } } // 브리핑 검색 function searchBriefings(query) { if (!query) { currentBriefings = MONEY_BRIEFINGS; } else { currentBriefings = MONEY_BRIEFINGS.filter(briefing => briefing.title.toLowerCase().includes(query.toLowerCase()) || briefing.content.toLowerCase().includes(query.toLowerCase()) || briefing.target.toLowerCase().includes(query.toLowerCase()) ); } renderBriefingCards(); } // CDP 컬럼 렌더링 function renderCDPColumns() { const container = document.getElementById('cdpColumns'); container.innerHTML = ''; Object.keys(currentColumns).forEach(category => { Object.keys(currentColumns[category]).forEach(columnName => { const card = document.createElement('div'); card.className = 'column-card'; card.innerHTML = ` <div class="column-category">${getCategoryName(category)}</div> <div class="column-name">${columnName}</div> <div class="column-description">${currentColumns[category][columnName]}</div> `; container.appendChild(card); }); }); } function getCategoryName(category) { const names = { 'basic': '기본 정보', 'interests': '관심사 지표', 'industries': '업종별 지표', 'scores': '예측 스코어', 'flags': '플래그 지표' }; return names[category] || category; } // CDP 컬럼 필터링 function filterColumns(category) { // 필터 버튼 활성화 상태 변경 document.querySelectorAll('#cdp-tab .filter-btn').forEach(btn => btn.classList.remove('active')); event.target.classList.add('active'); if (category === 'all') { currentColumns = CDP_COLUMNS; } else { currentColumns = { [category]: CDP_COLUMNS[category] }; } renderCDPColumns(); } // CDP 컬럼 검색 function searchColumns(query) { if (!query) { currentColumns = CDP_COLUMNS; } else { currentColumns = {}; Object.keys(CDP_COLUMNS).forEach(category => { const filteredColumns = {}; Object.keys(CDP_COLUMNS[category]).forEach(columnName => { if (columnName.toLowerCase().includes(query.toLowerCase()) || CDP_COLUMNS[category][columnName].toLowerCase().includes(query.toLowerCase())) { filteredColumns[columnName] = CDP_COLUMNS[category][columnName]; } }); if (Object.keys(filteredColumns).length > 0) { currentColumns[category] = filteredColumns; } }); } renderCDPColumns(); } // 예시 쿼리 설정 function setExampleQuery(query) { document.getElementById('queryInput').value = query; } // 분석 모드 설정 function setAnalysisMode(mode) { currentAnalysisMode = mode; // 버튼 활성화 상태 변경 document.querySelectorAll('.mode-btn').forEach(btn => btn.classList.remove('active')); document.getElementById(mode + 'Mode').classList.add('active'); // 로딩 텍스트 변경 const loadingText = document.querySelector('#loadingSection p'); if (mode === 'keyword') { loadingText.textContent = '🔤 키워드 기반으로 CDP 데이터를 분석하고 있습니다...'; } else { loadingText.textContent = '🤖 LLM이 CDP 데이터를 심층 분석하여 최적의 고객 세그먼트를 찾고 있습니다...'; } } // 쿼리 분석 function analyzeQuery() { const query = document.getElementById('queryInput').value; if (!query) return; const loadingSection = document.getElementById('loadingSection'); const resultsContainer = document.getElementById('resultsContainer'); const analysisResults = document.getElementById('analysisResults'); loadingSection.style.display = 'block'; resultsContainer.classList.remove('show'); if (currentAnalysisMode === 'keyword') { // 키워드 기반 분석 (빠름) setTimeout(() => { loadingSection.style.display = 'none'; const recommendations = generateKeywordRecommendations(query); analysisResults.innerHTML = recommendations; resultsContainer.classList.add('show'); }, 1000); } else { // LLM 기반 분석 (정확함) generateLLMRecommendations(query).then(recommendations => { loadingSection.style.display = 'none'; analysisResults.innerHTML = recommendations; resultsContainer.classList.add('show'); }).catch(error => { console.error('LLM 분석 실패:', error); loadingSection.style.display = 'none'; // Fallback to keyword-based analysis const fallbackRecommendations = ` <div class="recommendation-card"> <div class="recommendation-title">⚠️ LLM 분석 실패 - 키워드 기반으로 분석</div> <div class="recommendation-content"> LLM 분석에 실패했습니다. 키워드 기반 분석 결과를 제공합니다. </div> </div> ${generateKeywordRecommendations(query)} `; analysisResults.innerHTML = fallbackRecommendations; resultsContainer.classList.add('show'); }); } } // LLM 기반 추천 생성 (OpenAI GPT-4o) async function generateLLMRecommendations(query) { const apiKey = 'YOUR_OPENAI_API_KEY_HERE'; const model = 'gpt-4o-2024-11-20'; // CDP 스키마를 문자열로 변환 const cdpSchema = Object.entries(CDP_COLUMNS).map(([category, columns]) => { const columnList = Object.entries(columns).map(([key, desc]) => `${key}: ${desc}`).join('\n'); return `${category}:\n${columnList}`; }).join('\n\n'); // 머니브리핑 소재 요약 const briefingSummary = MONEY_BRIEFINGS.map(b => `No.${b.no} ${b.title} (${b.type}) - ${b.target}` ).join('\n'); const systemPrompt = `You are a financial marketing expert specializing in customer segmentation for money management services. You must respond with valid JSON only. Given a user query about target customer segments, analyze the query and recommend: 1. Relevant CDP (Customer Data Platform) columns to identify the target audience 2. Suitable money briefing materials to engage these customers CDP Schema Available: ${cdpSchema} Money Briefing Materials Available: ${briefingSummary} IMPORTANT: You must respond with ONLY a valid JSON object, no additional text before or after. Response format (Korean content): { "analysis": "Brief analysis of the query in Korean", "recommended_columns": [ {"column": "column_name", "reason": "why this column is relevant in Korean"}, {"column": "column_name", "reason": "why this column is relevant in Korean"} ], "recommended_briefings": [ {"no": briefing_number, "title": "briefing_title", "reason": "why this briefing fits in Korean"}, {"no": briefing_number, "title": "briefing_title", "reason": "why this briefing fits in Korean"} ], "targeting_strategy": "Overall strategy for targeting this segment in Korean" }`; const userPrompt = `Target customer query: "${query}" Please analyze this query and recommend the most relevant CDP columns and money briefing materials for targeting the described customer segment.`; try { const response = await fetch('https://api.openai.com/v1/chat/completions', { method: 'POST', headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ model: model, messages: [ { role: 'system', content: systemPrompt }, { role: 'user', content: userPrompt } ], temperature: 0.7, max_tokens: 2000, response_format: { type: "json_object" } }) }); if (!response.ok) { throw new Error(`OpenAI API error: ${response.status} ${response.statusText}`); } const data = await response.json(); const llmResponse = data.choices[0].message.content; // JSON 파싱 시도 (더 견고한 처리) let parsedResponse; try { // JSON 블록 추출 시도 const jsonMatch = llmResponse.match(/\{[\s\S]*\}/); const jsonStr = jsonMatch ? jsonMatch[0] : llmResponse; parsedResponse = JSON.parse(jsonStr); } catch (e) { console.error('JSON 파싱 실패, 원본 응답:', llmResponse); console.error('파싱 에러:', e.message); // JSON 파싱 실패 시 텍스트 기반 처리 const textRecommendations = ` <div class="recommendation-card"> <div class="recommendation-title">🤖 LLM 분석 결과: "${query}"</div> <div class="recommendation-content"> <strong>OpenAI 응답:</strong><br> ${llmResponse.replace(/\n/g, '<br>')} </div> </div> <div class="recommendation-card"> <div class="recommendation-title">⚠️ 디버깅 정보</div> <div class="recommendation-content"> JSON 파싱 실패: ${e.message}<br> 키워드 기반 분석으로 자동 전환하시거나, 콘솔에서 원본 응답을 확인하세요. </div> </div> `; return textRecommendations; } // HTML 형태로 변환 let recommendations = ` <div class="recommendation-card"> <div class="recommendation-title">🤖 LLM 분석 결과: "${query}"</div> <div class="recommendation-content"> ${parsedResponse.analysis} </div> </div> `; if (parsedResponse.recommended_columns && parsedResponse.recommended_columns.length > 0) { recommendations += ` <div class="recommendation-card"> <div class="recommendation-title">📊 추천 CDP 컬럼</div> <div class="recommendation-content"> ${parsedResponse.recommended_columns.map(col => `• <strong>${col.column}</strong>: ${col.reason}` ).join('<br>')} </div> </div> `; } if (parsedResponse.recommended_briefings && parsedResponse.recommended_briefings.length > 0) { recommendations += ` <div class="recommendation-card"> <div class="recommendation-title">💡 추천 브리핑 소재</div> <div class="recommendation-content"> ${parsedResponse.recommended_briefings.map(brief => `• <strong>No.${brief.no} ${brief.title}</strong>: ${brief.reason}` ).join('<br>')} </div> </div> `; } if (parsedResponse.targeting_strategy) { recommendations += ` <div class="recommendation-card"> <div class="recommendation-title">🎯 타겟팅 전략</div> <div class="recommendation-content"> ${parsedResponse.targeting_strategy} </div> </div> `; } return recommendations; } catch (error) { console.error('OpenAI API 호출 실패:', error); throw error; } } // 키워드 기반 추천 생성 (기존 로직) function generateKeywordRecommendations(query) { const lowerQuery = query.toLowerCase(); let recommendations = ` <div class="recommendation-card"> <div class="recommendation-title">🔤 키워드 분석 결과: "${query}"</div> <div class="recommendation-content"> 키워드 매칭을 통해 분석한 결과, 다음과 같은 CDP 컬럼 조합과 브리핑 소재를 추천합니다: </div> </div> `; const keywordMappings = { '대출': { columns: [ 'fa_int_loan1stfinancial: 1금융권 신용대출 고객', 'fa_int_loan2ndfinancial: 2금융권 신용대출 고객', 'sc_int_loanpersonal: 신용대출 예측 스코어', 'fa_int_highincome: 고소득층 (대출 승인률 높음)' ], briefings: [ '신용대출 심사 결과 (No. 33)', '주택담보대출 심사 결과 (No. 39)', '대출 이자 납입일 (No. 37)', '대출 만기 예정 (No. 38)', '새로 추가된 대출 계좌 (No. 28)' ] }, '뷰티': { columns: [ 'fa_ind_beauty: 미용 업종 결제 고객', 'fa_ind_cosmetic: 화장품 전문판매 고객', 'fa_ind_beautysalon: 미용실 결제 고객', 'sc_ind_cosmetic: 뷰티 관련 예측 스코어' ], briefings: [ '카드 청구서 도착 (No. 3) - 뷰티 소비 알림용', '이번달 지출분석 (No. 19) - 뷰티 지출 분석' ] }, '골프': { columns: [ 'fa_int_golf: 골프용품/골프장 결제 고객', 'sc_int_golf: 골프 관련 예측 스코어', 'fa_ind_golfcourse: 골프장 업종 결제 고객', 'fa_int_highincome: 고소득층 (골프 고객 특성)' ], briefings: [ '카드 청구서 도착 (No. 3) - 골프 소비 알림용', '이번달 지출분석 (No. 19) - 골프 지출 분석', '신용점수 올리기 (No. 27) - 프리미엄 고객 대상' ] }, '여행': { columns: [ 'fa_int_traveloverseas: 해외여행 예정 고객', 'fa_int_traveldomestic: 국내여행 관련 결제 고객', 'sc_int_traveloverseas: 해외여행 예측 스코어', 'fa_ind_airsevice: 항공 업종 결제 고객' ], briefings: [ '해외여행 준비 (No. 54)', '카드 청구서 도착 (No. 3) - 여행 소비 알림용', '이번달 지출분석 (No. 19) - 여행 지출 분석' ] }, '1인가구': { columns: [ 'fa_int_householdsingle: 1인 가구 관련 결제 고객', 'sc_int_householdsingle: 1인 가구 예측 스코어', 'fa_int_delivery: 배달 결제 고객', 'fa_int_jeonsemonthlyrent: 전월세 거주 추정 고객' ], briefings: [ '이번달 지출분석 (No. 19) - 1인가구 지출 패턴', '카드 청구서 도착 (No. 3) - 생활비 관리', '포인트 사용 안내 (No. 5) - 절약형 혜택' ] }, '투자': { columns: [ 'fa_int_saving: 예적금 개설 고객', 'fa_int_highincome: 고소득층', 'sc_int_saving: 예적금 예측 스코어', 'sc_int_business: 사업자 예측 스코어' ], briefings: [ '예적금 신규 가입 (No. 8)', '예적금 만기 알림 (No. 7)', '배당금 입금 (No. 14)', '새 증권계좌 발견 (No. 17)', '청약일정 확인해보세요! (No. 18)' ] }, '보험': { columns: [ 'fa_ind_insurance: 보험 업종 결제 고객', 'fa_int_carinsurance: 자동차보험 결제 예정 고객', 'fa_int_traveloverseas: 해외여행 예정 고객 (여행자보험)' ], briefings: [ '해외여행 준비 (No. 54)', '자동차보험 만기 예정 (No. 53)', '보험 납입일 (No. 52)' ] } }; // 키워드 매칭 및 추천 생성 let foundMappings = []; for (const [keyword, mapping] of Object.entries(keywordMappings)) { if (lowerQuery.includes(keyword) || query.includes(keyword)) { foundMappings.push({ keyword, ...mapping }); } } // 연령대 분석 if (lowerQuery.includes('20대') || lowerQuery.includes('30대') || lowerQuery.includes('젊은')) { recommendations += ` <div class="recommendation-card"> <div class="recommendation-title">👥 연령대 분석</div> <div class="recommendation-content"> • flag_young_adult: 20-35세 연령대 플래그<br> • fa_int_youngprofessional: 취직 추정 고객<br> • fa_int_jeonsemonthlyrent: 전월세 거주 추정 고객 </div> </div> `; } // 고소득층 분석 if (lowerQuery.includes('고소득') || lowerQuery.includes('프리미엄') || lowerQuery.includes('vip')) { recommendations += ` <div class="recommendation-card"> <div class="recommendation-title">💰 고소득층 분석</div> <div class="recommendation-content"> • fa_int_highincome: Nice 추정소득 1억이상 고객<br> • sc_int_highincome: 고소득층 예측 스코어<br> • fa_int_luxury: 명품 관련 결제 고객<br> • flag_high_spender: 월 100만원 이상 고액 결제자 </div> </div> `; } // 매핑된 추천 결과 추가 foundMappings.forEach(mapping => { recommendations += ` <div class="recommendation-card"> <div class="recommendation-title">📊 ${mapping.keyword} 관련 추천 컬럼</div> <div class="recommendation-content"> ${mapping.columns.map(col => `• ${col}`).join('<br>')} </div> </div> <div class="recommendation-card"> <div class="recommendation-title">💡 추천 브리핑 소재</div> <div class="recommendation-content"> ${mapping.briefings.map(brief => `• ${brief}`).join('<br>')} </div> </div> `; }); // 매핑이 없는 경우 일반적인 추천 if (foundMappings.length === 0) { recommendations += ` <div class="recommendation-card"> <div class="recommendation-title">💡 일반 추천</div> <div class="recommendation-content"> 질의에 적합한 구체적인 키워드를 포함해보세요:<br> • 관심사: 대출, 투자, 뷰티, 골프, 여행 등<br> • 연령대: 20대, 30대, 젊은, 중년 등<br> • 소득수준: 고소득, 프리미엄, VIP 등<br> • 생활패턴: 1인가구, 배달, 운동 등 </div> </div> `; } return recommendations; } // 추천 결과 생성 (개선된 분석 로직) function generateRecommendations(query) { const lowerQuery = query.toLowerCase(); let recommendations = ` <div class="recommendation-card"> <div class="recommendation-title">🎯 분석 결과: "${query}"</div> <div class="recommendation-content"> 질의를 분석한 결과, 다음과 같은 CDP 컬럼 조합과 브리핑 소재를 추천합니다: </div> </div> `; const keywordMappings = { '대출': { columns: [ 'fa_int_loan1stfinancial: 1금융권 신용대출 고객', 'fa_int_loan2ndfinancial: 2금융권 신용대출 고객', 'sc_int_loanpersonal: 신용대출 예측 스코어', 'fa_int_highincome: 고소득층 (대출 승인률 높음)' ], briefings: [ '신용대출 심사 결과 (No. 33)', '주택담보대출 심사 결과 (No. 39)', '대출 이자 납입일 (No. 37)', '대출 만기 예정 (No. 38)', '새로 추가된 대출 계좌 (No. 28)' ] }, '뷰티': { columns: [ 'fa_ind_beauty: 미용 업종 결제 고객', 'fa_ind_cosmetic: 화장품 전문판매 고객', 'fa_ind_beautysalon: 미용실 결제 고객', 'sc_ind_cosmetic: 뷰티 관련 예측 스코어' ], briefings: [ '카드 청구서 도착 (No. 3) - 뷰티 소비 알림용', '이번달 지출분석 (No. 19) - 뷰티 지출 분석' ] }, '골프': { columns: [ 'fa_int_golf: 골프용품/골프장 결제 고객', 'sc_int_golf: 골프 관련 예측 스코어', 'fa_ind_golfcourse: 골프장 업종 결제 고객', 'fa_int_highincome: 고소득층 (골프 고객 특성)' ], briefings: [ '카드 청구서 도착 (No. 3) - 골프 소비 알림용', '이번달 지출분석 (No. 19) - 골프 지출 분석', '신용점수 올리기 (No. 27) - 프리미엄 고객 대상' ] }, '여행': { columns: [ 'fa_int_traveloverseas: 해외여행 예정 고객', 'fa_int_traveldomestic: 국내여행 관련 결제 고객', 'sc_int_traveloverseas: 해외여행 예측 스코어', 'fa_ind_airsevice: 항공 업종 결제 고객' ], briefings: [ '해외여행 준비 (No. 54)', '카드 청구서 도착 (No. 3) - 여행 소비 알림용', '이번달 지출분석 (No. 19) - 여행 지출 분석' ] }, '1인가구': { columns: [ 'fa_int_householdsingle: 1인 가구 관련 결제 고객', 'sc_int_householdsingle: 1인 가구 예측 스코어', 'fa_int_delivery: 배달 결제 고객', 'fa_int_jeonsemonthlyrent: 전월세 거주 추정 고객' ], briefings: [ '이번달 지출분석 (No. 19) - 1인가구 지출 패턴', '카드 청구서 도착 (No. 3) - 생활비 관리', '포인트 사용 안내 (No. 5) - 절약형 혜택' ] }, '투자': { columns: [ 'fa_int_saving: 예적금 개설 고객', 'fa_int_highincome: 고소득층', 'sc_int_saving: 예적금 예측 스코어', 'sc_int_business: 사업자 예측 스코어' ], briefings: [ '예적금 신규 가입 (No. 8)', '예적금 만기 알림 (No. 7)', '배당금 입금 (No. 14)', '새 증권계좌 발견 (No. 17)', '청약일정 확인해보세요! (No. 18)' ] }, '보험': { columns: [ 'fa_ind_insurance: 보험 업종 결제 고객', 'fa_int_carinsurance: 자동차보험 결제 예정 고객', 'fa_int_traveloverseas: 해외여행 예정 고객 (여행자보험)' ], briefings: [ '해외여행 준비 (No. 54)', '자동차보험 만기 예정 (No. 53)', '보험 납입일 (No. 52)' ] } }; // 키워드 매칭 및 추천 생성 let foundMappings = []; for (const [keyword, mapping] of Object.entries(keywordMappings)) { if (lowerQuery.includes(keyword) || query.includes(keyword)) { foundMappings.push({ keyword, ...mapping }); } } // 연령대 분석 if (lowerQuery.includes('20대') || lowerQuery.includes('30대') || lowerQuery.includes('젊은')) { recommendations += ` <div class="recommendation-card"> <div class="recommendation-title">👥 연령대 분석</div> <div class="recommendation-content"> • flag_young_adult: 20-35세 연령대 플래그<br> • fa_int_youngprofessional: 취직 추정 고객<br> • fa_int_jeonsemonthlyrent: 전월세 거주 추정 고객 </div> </div> `; } // 고소득층 분석 if (lowerQuery.includes('고소득') || lowerQuery.includes('프리미엄') || lowerQuery.includes('vip')) { recommendations += ` <div class="recommendation-card"> <div class="recommendation-title">💰 고소득층 분석</div> <div class="recommendation-content"> • fa_int_highincome: Nice 추정소득 1억이상 고객<br> • sc_int_highincome: 고소득층 예측 스코어<br> • fa_int_luxury: 명품 관련 결제 고객<br> • flag_high_spender: 월 100만원 이상 고액 결제자 </div> </div> `; } // 매핑된 추천 결과 추가 foundMappings.forEach(mapping => { recommendations += ` <div class="recommendation-card"> <div class="recommendation-title">📊 ${mapping.keyword} 관련 추천 컬럼</div> <div class="recommendation-content"> ${mapping.columns.map(col => `• ${col}`).join('<br>')} </div> </div> <div class="recommendation-card"> <div class="recommendation-title">💡 추천 브리핑 소재</div> <div class="recommendation-content"> ${mapping.briefings.map(brief => `• ${brief}`).join('<br>')} </div> </div> `; }); // 매핑이 없는 경우 일반적인 추천 if (foundMappings.length === 0) { recommendations += ` <div class="recommendation-card"> <div class="recommendation-title">💡 일반 추천</div> <div class="recommendation-content"> 질의에 적합한 구체적인 키워드를 포함해보세요:<br> • 관심사: 대출, 투자, 뷰티, 골프, 여행 등<br> • 연령대: 20대, 30대, 젊은, 중년 등<br> • 소득수준: 고소득, 프리미엄, VIP 등<br> • 생활패턴: 1인가구, 배달, 운동 등 </div> </div> `; } return recommendations; } // 통계 계산 및 업데이트 function updateBriefingStats() { const total = MONEY_BRIEFINGS.length; const active = MONEY_BRIEFINGS.filter(b => b.exposed === 'O').length; const inactive = MONEY_BRIEFINGS.filter(b => b.exposed === 'X').length; const completed = MONEY_BRIEFINGS.filter(b => b.status === '완료').length; document.getElementById('totalBriefings').textContent = total; document.getElementById('activeBriefings').textContent = active; document.getElementById('inactiveBriefings').textContent = inactive; document.getElementById('completedBriefings').textContent = completed; } // 브리핑 정보 복사 기능 function copyBriefingInfo(briefingNo) { const briefing = MONEY_BRIEFINGS.find(b => b.no === briefingNo); if (!briefing) return; const info = ` 📋 머니브리핑 소재 정보 • 제목: ${briefing.title} • 번호: No. ${briefing.no} • 유형: ${briefing.type} • 서비스: ${briefing.service} • 노출상태: ${briefing.exposed === 'O' ? '노출 중' : '비노출'} • 상태: ${briefing.status} • 타겟: ${briefing.target} • 버튼: ${briefing.button} • 내용: ${briefing.content} • 템플릿ID: ${briefing.templateId} `; navigator.clipboard.writeText(info.trim()).then(() => { showNotification('브리핑 정보가 복사되었습니다.'); }).catch(() => { showNotification('복사에 실패했습니다.'); }); } // 알림 표시 기능 function showNotification(message) { const notification = document.createElement('div'); notification.style.cssText = ` position: fixed; top: 20px; right: 20px; background: #4CAF50; color: white; padding: 15px 20px; border-radius: 5px; z-index: 1000; box-shadow: 0 4px 12px rgba(0,0,0,0.15); transform: translateX(100%); transition: transform 0.3s ease; `; notification.textContent = message; document.body.appendChild(notification); setTimeout(() => notification.style.transform = 'translateX(0)', 100); setTimeout(() => { notification.style.transform = 'translateX(100%)'; setTimeout(() => document.body.removeChild(notification), 300); }, 3000); } // 데이터 내보내기 기능 function exportBriefingData() { const data = { summary: { total: MONEY_BRIEFINGS.length, active: MONEY_BRIEFINGS.filter(b => b.exposed === 'O').length, inactive: MONEY_BRIEFINGS.filter(b => b.exposed === 'X').length, completed: MONEY_BRIEFINGS.filter(b => b.status === '완료').length }, briefings: currentBriefings, exportDate: new Date().toISOString() }; const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `money-briefing-analysis-${new Date().toISOString().split('T')[0]}.json`; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); showNotification('데이터가 내보내졌습니다.'); } // 키보드 단축키 document.addEventListener('keydown', function(e) { // Ctrl+1: 첫 번째 탭 if (e.ctrlKey && e.key === '1') { e.preventDefault(); switchTab('briefings'); } // Ctrl+2: 두 번째 탭 if (e.ctrlKey && e.key === '2') { e.preventDefault(); switchTab('cdp'); } // Ctrl+3: 세 번째 탭 if (e.ctrlKey && e.key === '3') { e.preventDefault(); switchTab('generator'); } // Ctrl+4: 네 번째 탭 (자산 변동 브리핑) if (e.ctrlKey && e.key === '4') { e.preventDefault(); switchTab('asset'); } // Ctrl+Enter: 쿼리 분석 (CDP 탭에서) if (e.ctrlKey && e.key === 'Enter' && document.getElementById('cdp-tab').classList.contains('active')) { e.preventDefault(); analyzeQuery(); } }); // 검색 입력 시 Enter 키 처리 function handleKeyPress(event) { if (event.key === 'Enter') { analyzeQuery(); } } // 통계 정보 표시 function getQuickStats() { const totalColumns = Object.values(CDP_COLUMNS).reduce((acc, category) => acc + Object.keys(category).length, 0); const activeFilters = document.querySelectorAll('.filter-btn.active').length; return { totalColumns, activeFilters, currentResults: Object.values(currentColumns).reduce((acc, category) => acc + Object.keys(category).length, 0) }; } // 브리핑 생성 관련 함수들 function initializeGeneratorTab() { // 브리핑 생성 탭 초기화 로직 document.getElementById('generatorInput').value = ''; document.getElementById('generatorResults').innerHTML = ''; document.getElementById('generatorLoadingSection').style.display = 'none'; } function setGeneratorExample(example) { document.getElementById('generatorInput').value = example; } // 브리핑 생성 메인 함수 async function generateBriefings() { const input = document.getElementById('generatorInput').value.trim(); if (!input) { showNotification('아이디어나 키워드를 입력해주세요.'); return; } const loadingSection = document.getElementById('generatorLoadingSection'); const resultsContainer = document.getElementById('generatorResults'); // 로딩 시작 loadingSection.style.display = 'block'; resultsContainer.innerHTML = ''; try { const briefings = await generateBriefingsWithLLM(input); loadingSection.style.display = 'none'; displayGeneratedBriefings(briefings); } catch (error) { console.error('브리핑 생성 실패:', error); loadingSection.style.display = 'none'; showNotification('브리핑 생성에 실패했습니다. 다시 시도해주세요.'); } } // LLM을 사용한 브리핑 생성 async function generateBriefingsWithLLM(input) { const apiKey = 'YOUR_OPENAI_API_KEY_HERE'; const model = 'gpt-4o-2024-11-20'; // 기존 브리핑 패턴 분석 const briefingExamples = MONEY_BRIEFINGS.slice(0, 10).map(b => `제목: ${b.title}\n분류: ${b.type}\n내용: ${b.content}\n타겟: ${b.target}\n버튼: ${b.button}` ).join('\n\n'); // CDP 컬럼 요약 const cdpSummary = Object.entries(CDP_COLUMNS).map(([category, columns]) => { const sampleColumns = Object.entries(columns).slice(0, 5).map(([key, desc]) => `${key}: ${desc}`).join('\n'); return `${category}:\n${sampleColumns}`; }).join('\n\n'); const systemPrompt = `당신은 네이버페이 머니브리핑 소재를 전문으로 만드는 마케터입니다. 사용자가 제공한 아이디어를 바탕으로 6개의 새로운 브리핑 소재를 생성해야 합니다. 기존 브리핑 패턴 (참고용): ${briefingExamples} 브리핑 분류 (7가지 중 선택): 1. 생활과 연관된 돈 - 일상생활과 관련된 금전 관리 2. 불린 돈 - 투자, 수익, 자산 증가 관련 3. 나간 돈 - 지출, 결제, 소비 관련 4. 들어오는 돈 - 수입, 송금, 적립 관련 5. 미래를 위한 돈 - 저축, 투자, 노후 준비 관련 6. 빌린 돈 - 대출, 신용, 금융 관련 7. 경제/자산컨텐츠 - 경제 동향, 금융 정보 관련 CDP 컬럼 (타겟팅용): ${cdpSummary} 반드시 JSON 형식으로 응답하세요: { "briefings": [ { "title": "브리핑 제목", "category": "분류 (위 7가지 중 선택)", "content": "브리핑 내용 (구체적이고 개인화된 메시지)", "target": "타겟 고객 (CDP 컬럼 기반으로 구체적으로)", "button": "버튼 텍스트", "reason": "이 브리핑이 적절한 이유와 기대 효과" } ] }`; const userPrompt = `아이디어: "${input}" 이 아이디어를 바탕으로 6개의 다양한 머니브리핑 소재를 생성해주세요. 각 브리핑은 서로 다른 관점과 타겟을 가져야 합니다.`; try { const response = await fetch('https://api.openai.com/v1/chat/completions', { method: 'POST', headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ model: model, messages: [ { role: 'system', content: systemPrompt }, { role: 'user', content: userPrompt } ], temperature: 0.8, max_tokens: 3000, response_format: { type: "json_object" } }) }); if (!response.ok) { throw new Error(`OpenAI API error: ${response.status} ${response.statusText}`); } const data = await response.json(); const llmResponse = data.choices[0].message.content; try { const parsedResponse = JSON.parse(llmResponse); return parsedResponse.briefings || []; } catch (e) { console.error('JSON 파싱 실패:', e); throw new Error('LLM 응답을 파싱할 수 없습니다.'); } } catch (error) { console.error('OpenAI API 호출 실패:', error); throw error; } } // 생성된 브리핑 표시 function displayGeneratedBriefings(briefings) { const container = document.getElementById('generatorResults'); if (!briefings || briefings.length === 0) { container.innerHTML = '<p>브리핑을 생성하지 못했습니다.</p>'; return; } container.innerHTML = briefings.map(briefing => ` <div class="generated-briefing-card"> <div class="generated-briefing-header"> <div class="generated-briefing-title">${briefing.title}</div> <div class="generated-briefing-category">${briefing.category}</div> </div> <div class="generated-briefing-content"> ${briefing.content} </div> <div class="generated-briefing-meta"> <div class="generated-briefing-field"> <div class="generated-briefing-label">🎯 타겟 고객</div> <div class="generated-briefing-value">${briefing.target}</div> </div> <div class="generated-briefing-field"> <div class="generated-briefing-label">🔗 버튼 액션</div> <div class="generated-briefing-value">${briefing.button}</div> </div> </div> <div class="generated-briefing-reason"> <div class="generated-briefing-reason-title">💡 제안 이유</div> <div class="generated-briefing-reason-content">${briefing.reason}</div> </div> </div> `).join(''); } // ===== 자산 변동 브리핑 관련 함수들 ===== // 만원 단위 포맷팅 함수 function formatWonUnit(value) { if (value === 0) return '0만원'; return `${value.toLocaleString()}만원`; } // 변동 포맷팅 함수 (+ 또는 - 표시 포함) function formatChangeWonUnit(value) { if (value === 0) return '0만원'; const sign = value >= 0 ? '+' : ''; return `${sign}${value.toLocaleString()}만원`; } // 자산 탭 초기화 function initializeAssetTab() { updateAssetFormFromData(); } // 자산 폼 데이터 업데이트 function updateAssetFormFromData() { document.getElementById('currBankValue').value = assetData.current.CURR_BANK_VALUE; document.getElementById('prevBankValue').value = assetData.previous.PREV_BANK_VALUE; document.getElementById('currStockValue').value = assetData.current.CURR_STOCK_VALUE; document.getElementById('prevStockValue').value = assetData.previous.PREV_STOCK_VALUE; document.getElementById('currRealestateValue').value = assetData.current.CURR_REALESTATE_VALUE; document.getElementById('prevRealestateValue').value = assetData.previous.PREV_REALESTATE_VALUE; document.getElementById('currPensionValue').value = assetData.current.CURR_PENSION_VALUE; document.getElementById('prevPensionValue').value = assetData.previous.PREV_PENSION_VALUE; document.getElementById('currLoanBalance').value = assetData.current.CURR_LOAN_BALANCE; document.getElementById('prevLoanBalance').value = assetData.previous.PREV_LOAN_BALANCE; document.getElementById('currCardPaymentDue').value = assetData.current.CURR_CARD_PAYMENT_DUE; document.getElementById('prevCardPaymentDue').value = assetData.previous.PREV_CARD_PAYMENT_DUE; document.getElementById('currCarValue').value = assetData.current.CURR_CAR_VALUE; document.getElementById('prevCarValue').value = assetData.previous.PREV_CAR_VALUE; document.getElementById('currPointmoneyValue').value = assetData.current.CURR_POINTMONEY_VALUE; document.getElementById('prevPointmoneyValue').value = assetData.previous.PREV_POINTMONEY_VALUE; } // 폼에서 자산 데이터 읽기 function readAssetDataFromForm() { assetData.current.CURR_BANK_VALUE = parseInt(document.getElementById('currBankValue').value) || 0; assetData.previous.PREV_BANK_VALUE = parseInt(document.getElementById('prevBankValue').value) || 0; assetData.current.CURR_STOCK_VALUE = parseInt(document.getElementById('currStockValue').value) || 0; assetData.previous.PREV_STOCK_VALUE = parseInt(document.getElementById('prevStockValue').value) || 0; assetData.current.CURR_REALESTATE_VALUE = parseInt(document.getElementById('currRealestateValue').value) || 0; assetData.previous.PREV_REALESTATE_VALUE = parseInt(document.getElementById('prevRealestateValue').value) || 0; assetData.current.CURR_PENSION_VALUE = parseInt(document.getElementById('currPensionValue').value) || 0; assetData.previous.PREV_PENSION_VALUE = parseInt(document.getElementById('prevPensionValue').value) || 0; assetData.current.CURR_LOAN_BALANCE = parseInt(document.getElementById('currLoanBalance').value) || 0; assetData.previous.PREV_LOAN_BALANCE = parseInt(document.getElementById('prevLoanBalance').value) || 0; assetData.current.CURR_CARD_PAYMENT_DUE = parseInt(document.getElementById('currCardPaymentDue').value) || 0; assetData.previous.PREV_CARD_PAYMENT_DUE = parseInt(document.getElementById('prevCardPaymentDue').value) || 0; assetData.current.CURR_CAR_VALUE = parseInt(document.getElementById('currCarValue').value) || 0; assetData.previous.PREV_CAR_VALUE = parseInt(document.getElementById('prevCarValue').value) || 0; assetData.current.CURR_POINTMONEY_VALUE = parseInt(document.getElementById('currPointmoneyValue').value) || 0; assetData.previous.PREV_POINTMONEY_VALUE = parseInt(document.getElementById('prevPointmoneyValue').value) || 0; } // 자산 변동 계산 function calculateAssetChanges() { readAssetDataFromForm(); // 총자산 계산 (부채 제외) const currentAssets = assetData.current.CURR_BANK_VALUE + assetData.current.CURR_STOCK_VALUE + assetData.current.CURR_REALESTATE_VALUE + assetData.current.CURR_PENSION_VALUE + assetData.current.CURR_CAR_VALUE + assetData.current.CURR_POINTMONEY_VALUE; const previousAssets = assetData.previous.PREV_BANK_VALUE + assetData.previous.PREV_STOCK_VALUE + assetData.previous.PREV_REALESTATE_VALUE + assetData.previous.PREV_PENSION_VALUE + assetData.previous.PREV_CAR_VALUE + assetData.previous.PREV_POINTMONEY_VALUE; // 순자산 계산 (부채 차감) const currentNetAssets = currentAssets - assetData.current.CURR_LOAN_BALANCE - assetData.current.CURR_CARD_PAYMENT_DUE; const previousNetAssets = previousAssets - assetData.previous.PREV_LOAN_BALANCE - assetData.previous.PREV_CARD_PAYMENT_DUE; assetData.current.CURRENT_TOTAL_ASSET_VALUE = currentNetAssets; assetData.previous.PREVIOUS_TOTAL_ASSET_VALUE = previousNetAssets; const totalChange = currentNetAssets - previousNetAssets; const totalChangeRate = previousNetAssets !== 0 ? (totalChange / previousNetAssets * 100) : 0; // 개별 항목 변동 계산 const changes = [ { name: '은행', change: assetData.current.CURR_BANK_VALUE - assetData.previous.PREV_BANK_VALUE, rate: assetData.previous.PREV_BANK_VALUE !== 0 ? ((assetData.current.CURR_BANK_VALUE - assetData.previous.PREV_BANK_VALUE) / assetData.previous.PREV_BANK_VALUE * 100) : 0 }, { name: '증권', change: assetData.current.CURR_STOCK_VALUE - assetData.previous.PREV_STOCK_VALUE, rate: assetData.previous.PREV_STOCK_VALUE !== 0 ? ((assetData.current.CURR_STOCK_VALUE - assetData.previous.PREV_STOCK_VALUE) / assetData.previous.PREV_STOCK_VALUE * 100) : 0 }, { name: '부동산', change: assetData.current.CURR_REALESTATE_VALUE - assetData.previous.PREV_REALESTATE_VALUE, rate: assetData.previous.PREV_REALESTATE_VALUE !== 0 ? ((assetData.current.CURR_REALESTATE_VALUE - assetData.previous.PREV_REALESTATE_VALUE) / assetData.previous.PREV_REALESTATE_VALUE * 100) : 0 }, { name: '연금', change: assetData.current.CURR_PENSION_VALUE - assetData.previous.PREV_PENSION_VALUE, rate: assetData.previous.PREV_PENSION_VALUE !== 0 ? ((assetData.current.CURR_PENSION_VALUE - assetData.previous.PREV_PENSION_VALUE) / assetData.previous.PREV_PENSION_VALUE * 100) : 0 }, { name: '대출', change: assetData.previous.PREV_LOAN_BALANCE - assetData.current.CURR_LOAN_BALANCE, // 대출은 감소가 좋음 rate: assetData.previous.PREV_LOAN_BALANCE !== 0 ? ((assetData.previous.PREV_LOAN_BALANCE - assetData.current.CURR_LOAN_BALANCE) / assetData.previous.PREV_LOAN_BALANCE * 100) : 0 }, { name: '카드청구', change: assetData.previous.PREV_CARD_PAYMENT_DUE - assetData.current.CURR_CARD_PAYMENT_DUE, // 청구액 감소가 좋음 rate: assetData.previous.PREV_CARD_PAYMENT_DUE !== 0 ? ((assetData.previous.PREV_CARD_PAYMENT_DUE - assetData.current.CURR_CARD_PAYMENT_DUE) / assetData.previous.PREV_CARD_PAYMENT_DUE * 100) : 0 } ]; // 가장 큰 증가/감소 찾기 const positiveChanges = changes.filter(c => c.change > 0).sort((a, b) => b.change - a.change); const negativeChanges = changes.filter(c => c.change < 0).sort((a, b) => a.change - b.change); const biggestIncrease = positiveChanges[0] || { name: '없음', change: 0, rate: 0 }; const biggestDecrease = negativeChanges[0] || { name: '없음', change: 0, rate: 0 }; // UI 업데이트 document.getElementById('totalAssetChange').textContent = formatChangeWonUnit(totalChange); document.getElementById('totalAssetChangeRate').textContent = `${totalChangeRate >= 0 ? '+' : ''}${totalChangeRate.toFixed(1)}%`; document.getElementById('biggestIncrease').textContent = `${biggestIncrease.name} ${formatChangeWonUnit(biggestIncrease.change)}`; document.getElementById('biggestIncreaseRate').textContent = `+${biggestIncrease.rate.toFixed(1)}%`; document.getElementById('biggestDecrease').textContent = `${biggestDecrease.name} ${formatChangeWonUnit(biggestDecrease.change)}`; document.getElementById('biggestDecreaseRate').textContent = `${biggestDecrease.rate.toFixed(1)}%`; // 요약 섹션 표시 document.getElementById('assetSummary').style.display = 'block'; showNotification('💰 자산 변동이 계산되었습니다!'); } // 자산 브리핑 생성 async function generateAssetBriefings() { readAssetDataFromForm(); // 로딩 시작 document.getElementById('assetLoadingSection').style.display = 'block'; document.getElementById('assetBriefingsResults').innerHTML = ''; try { // 자산 변동 계산 calculateAssetChanges(); const briefings = await generateAssetBriefingsWithLLM(); displayAssetBriefings(briefings); } catch (error) { console.error('자산 브리핑 생성 오류:', error); showNotification('❌ 자산 브리핑 생성 중 오류가 발생했습니다.'); } finally { document.getElementById('assetLoadingSection').style.display = 'none'; } } // 추천용 자산 변동 계산 function calculateAssetChangesForRecommendation() { readAssetDataFromForm(); return { '은행': { change: assetData.current.CURR_BANK_VALUE - assetData.previous.PREV_BANK_VALUE, rate: assetData.previous.PREV_BANK_VALUE !== 0 ? ((assetData.current.CURR_BANK_VALUE - assetData.previous.PREV_BANK_VALUE) / assetData.previous.PREV_BANK_VALUE * 100) : 0 }, '증권': { change: assetData.current.CURR_STOCK_VALUE - assetData.previous.PREV_STOCK_VALUE, rate: assetData.previous.PREV_STOCK_VALUE !== 0 ? ((assetData.current.CURR_STOCK_VALUE - assetData.previous.PREV_STOCK_VALUE) / assetData.previous.PREV_STOCK_VALUE * 100) : 0 }, '부동산': { change: assetData.current.CURR_REALESTATE_VALUE - assetData.previous.PREV_REALESTATE_VALUE, rate: assetData.previous.PREV_REALESTATE_VALUE !== 0 ? ((assetData.current.CURR_REALESTATE_VALUE - assetData.previous.PREV_REALESTATE_VALUE) / assetData.previous.PREV_REALESTATE_VALUE * 100) : 0 }, '연금': { change: assetData.current.CURR_PENSION_VALUE - assetData.previous.PREV_PENSION_VALUE, rate: assetData.previous.PREV_PENSION_VALUE !== 0 ? ((assetData.current.CURR_PENSION_VALUE - assetData.previous.PREV_PENSION_VALUE) / assetData.previous.PREV_PENSION_VALUE * 100) : 0 }, '대출': { change: assetData.previous.PREV_LOAN_BALANCE - assetData.current.CURR_LOAN_BALANCE, // 대출은 감소가 좋음 rate: assetData.previous.PREV_LOAN_BALANCE !== 0 ? ((assetData.previous.PREV_LOAN_BALANCE - assetData.current.CURR_LOAN_BALANCE) / assetData.previous.PREV_LOAN_BALANCE * 100) : 0 }, '카드청구': { change: assetData.previous.PREV_CARD_PAYMENT_DUE - assetData.current.CURR_CARD_PAYMENT_DUE, // 청구액 감소가 좋음 rate: assetData.previous.PREV_CARD_PAYMENT_DUE !== 0 ? ((assetData.previous.PREV_CARD_PAYMENT_DUE - assetData.current.CURR_CARD_PAYMENT_DUE) / assetData.previous.PREV_CARD_PAYMENT_DUE * 100) : 0 } }; } // 기존 브리핑 추천 알고리즘 function getRelatedBriefings(assetChanges) { const relatedBriefings = []; // 자산 변동에 따른 기존 브리핑 매핑 const assetMapping = { bank_increase: [1, 11, 19], // 은행 증가 -> 만기연장, 숨은돈찾기, 지출분석 stock_increase: [14, 15, 17, 18], // 증권 증가 -> 배당금, 평가금액변동, 신규계좌, 청약일정 stock_decrease: [16], // 증권 감소 -> 예수금 발견 realestate_increase: [65, 66], // 부동산 증가 -> 실거래가, 시세알림 pension_increase: [12, 13], // 연금 증가 -> 연금개시, 연금미납 loan_decrease: [28, 37, 38], // 대출 감소 -> 신규대출계좌, 이자납입일, 대출만기 card_decrease: [3, 4], // 카드 감소 -> 청구서도착, 카드결제일 general_asset: [19, 49, 67] // 종합 자산 -> 지출분석, 대출소식, 머니스토리 }; // 변동이 큰 항목에 따른 브리핑 추천 Object.keys(assetChanges).forEach(key => { const change = assetChanges[key]; if (Math.abs(change.change) > 100) { // 100만원 이상 변동 switch (key) { case '은행': if (change.change > 0) relatedBriefings.push(...assetMapping.bank_increase); break; case '증권': if (change.change > 0) relatedBriefings.push(...assetMapping.stock_increase); else relatedBriefings.push(...assetMapping.stock_decrease); break; case '부동산': if (change.change > 0) relatedBriefings.push(...assetMapping.realestate_increase); break; case '연금': if (change.change > 0) relatedBriefings.push(...assetMapping.pension_increase); break; case '대출': if (change.change > 0) relatedBriefings.push(...assetMapping.loan_decrease); // 대출 감소가 좋음 break; case '카드청구': if (change.change > 0) relatedBriefings.push(...assetMapping.card_decrease); // 청구액 감소가 좋음 break; } } }); // 기본 추천 브리핑 (항상 포함) relatedBriefings.push(...assetMapping.general_asset); // 중복 제거 및 실제 브리핑 데이터 반환 const uniqueBriefingNos = [...new Set(relatedBriefings)]; return MONEY_BRIEFINGS.filter(briefing => uniqueBriefingNos.includes(briefing.no)).slice(0, 5); } // GPT-4를 활용한 자산 브리핑 생성 async function generateAssetBriefingsWithLLM() { const apiKey = 'YOUR_OPENAI_API_KEY_HERE'; // 자산 변동 요약 생성 const assetSummary = generateAssetSummary(); // 관련 기존 브리핑 찾기 const assetChanges = calculateAssetChangesForRecommendation(); const relatedBriefings = getRelatedBriefings(assetChanges); const briefingSummary = relatedBriefings.map(b => `- ${b.title}: ${b.content.substring(0, 100)}...`).join('\n'); const prompt = `당신은 네이버페이 개인 자산 변동 브리핑을 전문으로 만드는 AI 어시스턴트입니다. 사용자의 자산 변동 데이터: ${assetSummary} 관련 기존 브리핑 (참고용): ${briefingSummary} 위 자산 변동 데이터와 기존 브리핑을 참고하여 6-8개의 맞춤형 자산 변동 브리핑을 생성해주세요. 기존 브리핑의 패턴과 톤을 참고하되, 사용자의 실제 자산 변동에 맞게 개인화해주세요. 각 브리핑은 다음 7가지 분류 중 하나여야 합니다: 1. 생활과 연관된 돈 - 일상생활과 관련된 금전 관리 2. 불린 돈 - 투자, 수익, 자산 증가 관련 3. 나간 돈 - 지출, 결제, 소비 관련 4. 들어오는 돈 - 수입, 송금, 적립 관련 5. 미래를 위한 돈 - 저축, 투자, 노후 준비 관련 6. 빌린 돈 - 대출, 신용, 금융 관련 7. 경제/자산컨텐츠 - 경제 동향, 금융 정보 관련 응답은 반드시 다음 JSON 형식으로 해주세요: { "briefings": [ { "title": "브리핑 제목 (감정적, 개인화된 메시지)", "category": "분류 (위 7가지 중 선택)", "content": "브리핑 내용 (구체적인 금액과 개인화된 메시지, 2-3문장)", "target": "타겟 고객 (자산 변동 패턴 기반으로 구체적으로)", "button": "버튼 텍스트 (액션 유도)", "landing_page": { "type": "페이지 타입 (예: stock_performance, loan_tracker, asset_report 등)", "charts": ["차트1", "차트2", "차트3"], "insights": ["인사이트1", "인사이트2"] }, "reason": "이 브리핑이 적절한 이유와 기대 효과" } ] }`; try { const response = await fetch('https://api.openai.com/v1/chat/completions', { method: 'POST', headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ model: 'gpt-4o-2024-11-20', messages: [ { role: 'system', content: '당신은 네이버페이 개인 자산 변동 브리핑을 전문으로 만드는 AI 어시스턴트입니다. 사용자의 자산 변동을 분석하여 맞춤형 브리핑을 생성합니다.' }, { role: 'user', content: prompt } ], temperature: 0.8, max_tokens: 3000, response_format: { type: "json_object" } }) }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); const content = data.choices[0].message.content; try { const parsed = JSON.parse(content); return parsed.briefings || []; } catch (parseError) { console.error('JSON 파싱 오류:', parseError); return []; } } catch (error) { console.error('API 호출 오류:', error); throw error; } } // 자산 변동 요약 생성 function generateAssetSummary() { const currentTotal = assetData.current.CURRENT_TOTAL_ASSET_VALUE || 0; const previousTotal = assetData.previous.PREVIOUS_TOTAL_ASSET_VALUE || 0; const totalChange = currentTotal - previousTotal; const totalChangeRate = previousTotal !== 0 ? (totalChange / previousTotal * 100) : 0; return ` - 총자산: ${formatWonUnit(previousTotal)} → ${formatWonUnit(currentTotal)} (${totalChangeRate >= 0 ? '+' : ''}${totalChangeRate.toFixed(1)}%, ${formatChangeWonUnit(totalChange)}) - 은행: ${formatWonUnit(assetData.previous.PREV_BANK_VALUE)} → ${formatWonUnit(assetData.current.CURR_BANK_VALUE)} - 증권: ${formatWonUnit(assetData.previous.PREV_STOCK_VALUE)} → ${formatWonUnit(assetData.current.CURR_STOCK_VALUE)} - 부동산: ${formatWonUnit(assetData.previous.PREV_REALESTATE_VALUE)} → ${formatWonUnit(assetData.current.CURR_REALESTATE_VALUE)} - 연금: ${formatWonUnit(assetData.previous.PREV_PENSION_VALUE)} → ${formatWonUnit(assetData.current.CURR_PENSION_VALUE)} - 대출: ${formatWonUnit(assetData.previous.PREV_LOAN_BALANCE)} → ${formatWonUnit(assetData.current.CURR_LOAN_BALANCE)} - 카드청구: ${formatWonUnit(assetData.previous.PREV_CARD_PAYMENT_DUE)} → ${formatWonUnit(assetData.current.CURR_CARD_PAYMENT_DUE)} - 자동차: ${formatWonUnit(assetData.previous.PREV_CAR_VALUE)} → ${formatWonUnit(assetData.current.CURR_CAR_VALUE)} - 포인트/머니: ${formatWonUnit(assetData.previous.PREV_POINTMONEY_VALUE)} → ${formatWonUnit(assetData.current.CURR_POINTMONEY_VALUE)} `.trim(); } // 생성된 자산 브리핑 표시 function displayAssetBriefings(briefings) { const container = document.getElementById('assetBriefingsResults'); if (!briefings || briefings.length === 0) { container.innerHTML = '<p>자산 브리핑을 생성하지 못했습니다.</p>'; return; } // 관련 기존 브리핑도 같이 표시 const assetChanges = calculateAssetChangesForRecommendation(); const relatedBriefings = getRelatedBriefings(assetChanges); container.innerHTML = ` <!-- AI 생성 브리핑 --> <div class="generated-briefings-section"> <h3>🤖 AI 생성 자산 변동 브리핑</h3> ${briefings.map(briefing => ` <div class="generated-briefing-card asset-briefing-card"> <div class="generated-briefing-header"> <div class="generated-briefing-title">${briefing.title}</div> <div class="generated-briefing-category">${briefing.category}</div> </div> <div class="generated-briefing-content"> ${briefing.content} </div> <div class="generated-briefing-meta"> <div class="generated-briefing-field"> <div class="generated-briefing-label">🎯 타겟 고객</div> <div class="generated-briefing-value">${briefing.target}</div> </div> <div class="generated-briefing-field"> <div class="generated-briefing-label">🔗 버튼 액션</div> <div class="generated-briefing-value"> <button class="landing-page-btn" onclick="showLandingPage('${briefing.landing_page?.type || 'default'}', '${briefing.title}')"> ${briefing.button} </button> </div> </div> </div> ${briefing.landing_page ? ` <div class="landing-page-info"> <div class="landing-page-label">📊 랜딩 페이지 구성</div> <div class="landing-page-details"> <div>차트: ${briefing.landing_page.charts?.join(', ') || '없음'}</div> <div>인사이트: ${briefing.landing_page.insights?.join(', ') || '없음'}</div> </div> </div> ` : ''} <div class="generated-briefing-reason"> <div class="generated-briefing-reason-title">💡 제안 이유</div> <div class="generated-briefing-reason-content">${briefing.reason}</div> </div> </div> `).join('')} </div> <!-- 관련 기존 브리핑 --> ${relatedBriefings.length > 0 ? ` <div class="related-briefings-section" style="margin-top: 40px;"> <h3>📋 자산 변동 관련 기존 브리핑</h3> <p style="color: #6c757d; margin-bottom: 20px;">현재 자산 상황에 맞는 기존 브리핑들을 추천드립니다.</p> ${relatedBriefings.map(briefing => ` <div class="briefing-card related-briefing" style="margin-bottom: 15px;"> <div class="briefing-header"> <div class="briefing-title">${briefing.title}</div> <div style="display: flex; align-items: center; gap: 10px;"> <div class="briefing-category">${briefing.type}</div> <div class="status-badge ${briefing.exposed === 'O' ? 'status-active' : 'status-inactive'}"> ${briefing.exposed === 'O' ? '노출 중' : '비노출'} </div> </div> </div> <div class="briefing-content" style="margin: 10px 0; color: #495057;"> ${briefing.content} </div> <div class="briefing-meta"> <span style="background: #e9ecef; padding: 4px 8px; border-radius: 10px; font-size: 12px;"> ${briefing.button} </span> <span style="margin-left: 10px; color: #6c757d; font-size: 12px;"> 타겟: ${briefing.target} </span> </div> </div> `).join('')} </div> ` : ''} `; showNotification('🎉 자산 변동 브리핑이 생성되었습니다!'); } // 랜딩 페이지 모달 표시 function showLandingPage(pageType, title) { const modal = document.getElementById('landingPageModal'); const modalTitle = document.getElementById('modalTitle'); const modalBody = document.getElementById('modalBody'); modalTitle.textContent = title; // 페이지 타입에 따른 콘텐츠 생성 let content = generateLandingPageContent(pageType, title); modalBody.innerHTML = content; modal.style.display = 'block'; // 모달 외부 클릭 시 닫기 modal.onclick = function(event) { if (event.target === modal) { closeLandingPage(); } }; } // 랜딩 페이지 콘텐츠 생성 function generateLandingPageContent(pageType, title) { const mockData = { stock_performance: { stats: [ { label: '총 수익률', value: '+6.7%' }, { label: '수익 금액', value: '+500만원' }, { label: '평가 금액', value: '8,000만원' } ], charts: ['수익률 추이', '종목별 수익', '포트폴리오 구성'], insights: [ { title: '최고 수익 종목', content: '삼성전자가 +15.3%로 가장 높은 수익률을 기록했습니다.' }, { title: '투자 성과 분석', content: 'IT 섹터의 강세로 전체 포트폴리오가 시장 대비 우수한 성과를 보이고 있습니다.' } ] }, loan_tracker: { stats: [ { label: '상환 진행률', value: '32.5%' }, { label: '남은 원금', value: '14,900만원' }, { label: '예상 완납일', value: '2029년 6월' } ], charts: ['상환 진행률', '예상 완납일', '이자 절감액'], insights: [ { title: '월별 상환 추이', content: '꾸준한 원금 상환으로 이자 부담이 점진적으로 감소하고 있습니다.' }, { title: '추가 상환 시뮬레이션', content: '월 50만원 추가 상환 시 2년 단축, 약 1,200만원 이자 절약 가능합니다.' } ] }, asset_report: { stats: [ { label: '총 자산 증가', value: '+1,205만원' }, { label: '증가율', value: '+2.3%' }, { label: '현재 총 자산', value: '53,500만원' } ], charts: ['자산 구성 파이차트', '월별 변동 추이', '카테고리별 성과'], insights: [ { title: '자산 배분 조언', content: '부동산 비중이 높으니 증권 투자를 늘려 포트폴리오를 다양화하는 것을 권장합니다.' }, { title: '다음 달 전망', content: '현재 추세가 지속될 경우 연말까지 약 5% 추가 성장이 예상됩니다.' } ] }, expense_analysis: { stats: [ { label: '이번 달 지출', value: '150만원' }, { label: '전월 대비', value: '+50만원' }, { label: '평균 일일 지출', value: '4.8만원' } ], charts: ['카테고리별 지출', '일별 지출 패턴', '전월 비교'], insights: [ { title: '주요 지출 항목', content: '식비와 쇼핑 지출이 전월 대비 크게 증가했습니다.' }, { title: '절약 가능 영역', content: '구독 서비스와 배달음식 지출을 줄이면 월 20만원 절약 가능합니다.' } ] }, real_estate_value: { stats: [ { label: '현재 시세', value: '50,050만원' }, { label: '전일 대비', value: '+500만원' }, { label: '수익률', value: '+1.0%' } ], charts: ['시세 변동 추이', '지역 평균 비교', '매매/전세 동향'], insights: [ { title: '투자 수익률', content: '최근 3개월간 꾸준한 상승세로 연 12% 수익률을 기록 중입니다.' }, { title: '시장 전망', content: '해당 지역의 재개발 소식으로 향후 6개월간 추가 상승이 예상됩니다.' } ] } }; const data = mockData[pageType] || mockData.asset_report; return ` <div class="modal-stats"> ${data.stats.map(stat => ` <div class="modal-stat-card"> <div class="modal-stat-value">${stat.value}</div> <div class="modal-stat-label">${stat.label}</div> </div> `).join('')} </div> <div class="chart-container"> <h3>📊 차트 분석</h3> ${data.charts.map(chart => ` <div class="chart-placeholder"> ${chart} (실제 차트는 Chart.js로 구현 예정) </div> `).join('')} </div> <div class="insights-section"> <h3>💡 AI 인사이트</h3> ${data.insights.map(insight => ` <div class="insight-card"> <div class="insight-title">${insight.title}</div> <div class="insight-content">${insight.content}</div> </div> `).join('')} </div> <div class="chart-container"> <h4>🔗 관련 액션</h4> <button class="asset-generate-btn" onclick="showNotification('관련 서비스로 이동합니다.')"> 서비스 바로가기 </button> </div> `; } // AI 아이디어 섹션 토글 함수 function toggleAiIdeasSection() { const section = document.getElementById('aiIdeasSection'); if (section.style.display === 'none' || section.style.display === '') { section.style.display = 'block'; // 부드러운 스크롤 효과 section.scrollIntoView({ behavior: 'smooth' }); } else { section.style.display = 'none'; } } // 창의적 브리핑 아이디어 생성 함수 async function generateCreativeIdeas() { // 사용자 프로필 데이터 수집 const userProfile = { age: document.getElementById('userAge').value, job: document.getElementById('userJob').value, investmentStyle: document.getElementById('investmentStyle').value, lifestyle: document.getElementById('lifestyle').value, interests: document.getElementById('interests').value, financialGoal: document.getElementById('financialGoal').value }; // 현재 자산 데이터 수집 const currentAssets = collectCurrentAssetData(); // 로딩 섹션 표시 const loadingSection = document.getElementById('ideasLoadingSection'); const resultsSection = document.getElementById('ideasResults'); loadingSection.style.display = 'block'; resultsSection.innerHTML = ''; try { // AI 아이디어 생성 (실제 API 호출 시뮬레이션) const ideas = await generatePersonalizedIdeas(userProfile, currentAssets); // 결과 표시 displayCreativeIdeas(ideas); } catch (error) { console.error('아이디어 생성 중 오류 발생:', error); showNotification('❌ 아이디어 생성 중 오류가 발생했습니다.'); // 에러 발생 시 모의 데이터로 표시 const mockIdeas = generateMockCreativeIdeas(userProfile); displayCreativeIdeas(mockIdeas); } finally { loadingSection.style.display = 'none'; } } // 현재 자산 데이터 수집 function collectCurrentAssetData() { return { bankValue: parseInt(document.getElementById('currBankValue').value) || 0, stockValue: parseInt(document.getElementById('currStockValue').value) || 0, realEstateValue: parseInt(document.getElementById('currRealEstateValue').value) || 0, pensionValue: parseInt(document.getElementById('currPensionValue').value) || 0, savingsValue: parseInt(document.getElementById('currSavingsValue').value) || 0, insuranceValue: parseInt(document.getElementById('currInsuranceValue').value) || 0, loanBalance: parseInt(document.getElementById('currLoanBalance').value) || 0, carValue: parseInt(document.getElementById('currCarValue').value) || 0, totalAssets: 0 }; } // 개인화된 아이디어 생성 (AI API 시뮬레이션) async function generatePersonalizedIdeas(userProfile, assetData) { // 실제 구현에서는 OpenAI API 호출 return new Promise((resolve) => { setTimeout(() => { const ideas = generateMockCreativeIdeas(userProfile, assetData); resolve(ideas); }, 2000); }); } // 모의 창의적 아이디어 생성 function generateMockCreativeIdeas(userProfile, assetData = {}) { const personalizedIdeas = []; // 연령대별 맞춤 아이디어 const ageIdeas = { '20s': [ { title: "첫 직장인을 위한 '월급관리 마스터' 브리핑", content: "매월 급여일에 자동으로 생활비, 저축, 투자 비율을 분석해주는 개인화된 가이드", category: "생활과 연관된 돈", target: "20-30대 신입 직장인", button: "월급관리 시작하기", uniqueness: "연령대 특화", reason: "20대는 첫 경제활동 시작 시기로 올바른 자산관리 습관 형성이 중요" }, { title: "청년 투자자를 위한 '작은 돈 큰 수익' 챌린지", content: "소액으로 시작하는 분산투자 전략과 매주 성과 리포트", category: "불린 돈", target: "20-30대 투자 입문자", button: "투자 챌린지 참여", uniqueness: "연령대 특화", reason: "젊은 층의 장기투자 시작을 독려하고 성취감을 제공" } ], '30s': [ { title: "30대 직장인을 위한 '내집마련 로드맵' 브리핑", content: "현재 자산 기준 주택 구입 가능 시기와 전략을 시뮬레이션", category: "미래를 위한 돈", target: "30대 무주택자", button: "내집마련 계획보기", uniqueness: "연령대 특화", reason: "30대는 주택 구입을 본격 검토하는 시기" } ], '40s': [ { title: "40대를 위한 '중년 재테크 리밸런싱' 가이드", content: "자녀 교육비와 노후자금을 동시에 준비하는 포트폴리오 전략", category: "미래를 위한 돈", target: "40대 가장", button: "재테크 전략보기", uniqueness: "연령대 특화", reason: "교육비 부담과 노후준비를 병행해야 하는 시기" } ] }; // 직업군별 맞춤 아이디어 const jobIdeas = { 'office_worker': { title: "직장인 전용 '보너스 활용법' 브리핑", content: "상여금, 성과급 등 불규칙한 수입을 효율적으로 활용하는 전략", category: "들어오는 돈", target: "직장인", button: "보너스 활용전략보기", uniqueness: "직업 특화" }, 'business_owner': { title: "사업자를 위한 '세금 최적화' 브리핑", content: "사업 소득과 개인 자산을 분리한 효율적인 세무 전략", category: "나간 돈", target: "개인사업자/법인사업자", button: "세무전략 확인하기", uniqueness: "직업 특화" }, 'freelancer': { title: "프리랜서를 위한 '불규칙 소득 관리법'", content: "월마다 다른 수입에 맞춘 유연한 가계부 시스템", category: "생활과 연관된 돈", target: "프리랜서", button: "소득관리 시작하기", uniqueness: "직업 특화" } }; // 투자성향별 아이디어 const investmentIdeas = { 'conservative': { title: "안정형 투자자를 위한 '리스크 제로 수익 창출법'", content: "예금금리보다 높으면서도 원금보장이 되는 상품들의 조합 전략", category: "불린 돈", target: "보수적 투자자", button: "안정투자 상품보기", uniqueness: "투자성향 특화" }, 'aggressive': { title: "적극형 투자자를 위한 '하이리스크 하이리턴' 포트폴리오", content: "새로운 투자 기회와 위험 관리 전략을 결합한 공격적 투자법", category: "불린 돈", target: "적극적 투자자", button: "고수익 전략보기", uniqueness: "투자성향 특화" } }; // 라이프스타일별 아이디어 const lifestyleIdeas = { 'frugal': { title: "절약왕을 위한 '숨은 지출 찾기' 브리핑", content: "생활 속 불필요한 지출을 찾아내는 AI 분석과 절약 팁", category: "나간 돈", target: "절약 지향 고객", button: "숨은지출 분석하기", uniqueness: "라이프스타일 특화" }, 'luxury': { title: "프리미엄 라이프를 위한 '럭셔리 투자' 가이드", content: "고가 소비와 투자를 균형있게 관리하는 방법", category: "생활과 연관된 돈", target: "고소비층", button: "프리미엄 전략보기", uniqueness: "라이프스타일 특화" } }; // 관심분야별 아이디어 const interestIdeas = { 'tech': { title: "테크 전문가를 위한 'IT 주식 투자' 인사이트", content: "기술 트렌드를 활용한 투자 기회 발굴과 포트폴리오 구성", category: "불린 돈", target: "IT 관심층", button: "테크 투자전략보기", uniqueness: "관심분야 특화" }, 'real_estate': { title: "부동산 통을 위한 '지역별 투자 기회' 브리핑", content: "현재 보유 부동산 기준 추가 투자 지역과 타이밍 분석", category: "불린 돈", target: "부동산 투자자", button: "투자지역 분석보기", uniqueness: "관심분야 특화" } }; // 선택된 프로필에 따른 아이디어 선별 if (ageIdeas[userProfile.age]) { personalizedIdeas.push(...ageIdeas[userProfile.age]); } if (jobIdeas[userProfile.job]) { personalizedIdeas.push(jobIdeas[userProfile.job]); } if (investmentIdeas[userProfile.investmentStyle]) { personalizedIdeas.push(investmentIdeas[userProfile.investmentStyle]); } if (lifestyleIdeas[userProfile.lifestyle]) { personalizedIdeas.push(lifestyleIdeas[userProfile.lifestyle]); } if (interestIdeas[userProfile.interests]) { personalizedIdeas.push(interestIdeas[userProfile.interests]); } // 추가 범용 창의적 아이디어 const universalIdeas = [ { title: "AI 개인비서 '머니메이트' - 24시간 자산 모니터링", content: "챗봇 형태로 언제든 자산 현황과 투자 조언을 받을 수 있는 개인화 서비스", category: "경제/자산컨텐츠", target: "모든 연령층", button: "AI 비서 체험하기", uniqueness: "AI 융합", reason: "개인화된 AI 서비스는 차별화된 고객 경험을 제공" }, { title: "가족 자산 공유 '패밀리 월렛' 대시보드", content: "가족 구성원별 자산 현황을 통합 관리하고 목표 달성을 함께 추진", category: "생활과 연관된 돈", target: "가족 단위 고객", button: "패밀리 대시보드 보기", uniqueness: "가족 단위 서비스", reason: "가족 중심의 재테크는 새로운 시장 니즈" } ]; personalizedIdeas.push(...universalIdeas); return personalizedIdeas.slice(0, 6); // 최대 6개 아이디어 반환 } // 창의적 아이디어 결과 표시 function displayCreativeIdeas(ideas) { const resultsDiv = document.getElementById('ideasResults'); if (ideas.length === 0) { resultsDiv.innerHTML = ` <div class="no-ideas"> <h3>💡 아이디어를 생성할 수 없습니다</h3> <p>프로필 정보를 다시 확인해보세요.</p> </div> `; return; } resultsDiv.innerHTML = ` <div class="ideas-header"> <h3>🧠 맞춤형 브리핑 아이디어 (${ideas.length}개)</h3> <p>당신의 프로필을 분석하여 생성된 창의적인 브리핑 아이디어입니다.</p> </div> <div class="ideas-grid"> ${ideas.map((idea, index) => ` <div class="idea-card" data-idea-index="${index}"> <div class="idea-header"> <div class="idea-title">${idea.title}</div> <div class="idea-category">${idea.category}</div> </div> <div class="idea-content"> ${idea.content} </div> <div class="idea-meta"> <div class="idea-target">🎯 타겟: ${idea.target}</div> <div class="idea-button">📱 버튼: ${idea.button}</div> ${idea.uniqueness ? `<div class="idea-uniqueness">✨ ${idea.uniqueness}</div>` : ''} </div> ${idea.reason ? ` <div class="idea-reason"> <strong>💡 추천 이유:</strong> ${idea.reason} </div> ` : ''} <div class="idea-actions"> <button class="rate-idea-btn" onclick="rateIdea(${index}, 'like')"> 👍 좋아요 </button> <button class="implement-idea-btn" onclick="implementIdea(${index})"> 🚀 브리핑으로 구현 </button> </div> </div> `).join('')} </div> <div class="ideas-summary"> <h4>📊 아이디어 분석 요약</h4> <div class="summary-stats"> <div class="summary-stat"> <span class="stat-label">가장 많은 카테고리:</span> <span class="stat-value">${getMostCommonCategory(ideas)}</span> </div> <div class="summary-stat"> <span class="stat-label">개인화 레벨:</span> <span class="stat-value">높음 (프로필 기반 생성)</span> </div> </div> </div> `; showNotification('🎉 창의적인 브리핑 아이디어가 생성되었습니다!'); } // 가장 많은 카테고리 찾기 function getMostCommonCategory(ideas) { const categories = ideas.map(idea => idea.category); const counts = {}; categories.forEach(cat => counts[cat] = (counts[cat] || 0) + 1); return Object.keys(counts).reduce((a, b) => counts[a] > counts[b] ? a : b); } // 아이디어 평가 함수 function rateIdea(ideaIndex, rating) { showNotification(`💝 아이디어 #${ideaIndex + 1}에 ${rating === 'like' ? '좋아요' : '별로'}를 표시했습니다!`); // 실제 구현에서는 사용자 피드백을 서버로 전송 console.log(`아이디어 평가: Index ${ideaIndex}, Rating: ${rating}`); } // 아이디어를 실제 브리핑으로 구현하는 함수 function implementIdea(ideaIndex) { const ideaCards = document.querySelectorAll('.idea-card'); const selectedCard = ideaCards[ideaIndex]; if (!selectedCard) return; const ideaTitle = selectedCard.querySelector('.idea-title').textContent; const ideaContent = selectedCard.querySelector('.idea-content').textContent; const ideaCategory = selectedCard.querySelector('.idea-category').textContent; const ideaTarget = selectedCard.querySelector('.idea-target').textContent.replace('🎯 타겟: ', ''); const ideaButton = selectedCard.querySelector('.idea-button').textContent.replace('📱 버튼: ', ''); // 실제 브리핑으로 변환 const newBriefing = { title: ideaTitle, content: ideaContent, category: ideaCategory, target: ideaTarget, button: ideaButton, reason: `사용자 프로필 기반 AI 생성 아이디어를 브리핑으로 구현`, source: 'AI_CREATIVE_IDEAS' }; // 자산 브리핑 결과에 추가 addCreatedBriefingToResults(newBriefing); showNotification(`🚀 "${ideaTitle}"가 브리핑으로 생성되었습니다!`); // 자산 브리핑 결과 섹션으로 스크롤 document.getElementById('assetBriefingsResults').scrollIntoView({ behavior: 'smooth' }); } // 생성된 브리핑을 결과 영역에 추가 function addCreatedBriefingToResults(briefing) { const resultsDiv = document.getElementById('assetBriefingsResults'); // 기존 결과가 있으면 추가, 없으면 새로 생성 const existingContent = resultsDiv.innerHTML; const newBriefingHTML = ` <div class="briefing-result-section" style="margin-top: 20px;"> <h3>🧠 AI 창의 아이디어로 생성된 브리핑</h3> <div class="briefing-card created-from-idea"> <div class="briefing-header"> <div class="briefing-title">${briefing.title}</div> <div class="briefing-category">${briefing.category}</div> </div> <div class="briefing-content" style="margin: 10px 0; color: #495057;"> ${briefing.content} </div> <div class="briefing-meta"> <span style="background: #ff6b35; color: white; padding: 4px 8px; border-radius: 10px; font-size: 12px;"> ${briefing.button} </span> <span style="margin-left: 10px; color: #6c757d; font-size: 12px;"> 타겟: ${briefing.target} </span> </div> <div class="briefing-reason" style="margin-top: 10px; font-size: 13px; color: #6c757d; font-style: italic;"> 💡 ${briefing.reason} </div> </div> </div> `; if (existingContent.trim()) { resultsDiv.innerHTML = existingContent + newBriefingHTML; } else { resultsDiv.innerHTML = newBriefingHTML; } } // 모달 닫기 function closeLandingPage() { document.getElementById('landingPageModal').style.display = 'none'; } // 초기화 document.addEventListener('DOMContentLoaded', function() { currentColumns = CDP_COLUMNS; updateBriefingStats(); updateFilterButtonCounts(); renderBriefingCards(); renderCDPColumns(); // 도움말 표시 showNotification('💡 팁: Ctrl+1/2/3/4로 탭 전환, Ctrl+Enter로 분석 실행'); }); </script> </body> </html>

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ddoriboo/pension-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server