UNPKG

claude-data-academy

Version:

Claude Code용 데이터 학습 선생님 에이전트 NPX 설치 도구

334 lines (277 loc) 11.8 kB
const fs = require('fs-extra'); const path = require('path'); const chalk = require('chalk'); const { getInstalledTeachers } = require('./validator'); const { readJsonFile, getTeacherInfo, createProgressBar, getCurrentDate } = require('./utils'); /** * 설치된 선생님 목록 표시 * @param {string} agentsPath - agents 디렉토리 경로 */ async function listInstalledTeachers(agentsPath) { console.log(chalk.blue('\n📋 설치된 선생님 목록\n')); try { const installedTeachers = await getInstalledTeachers(agentsPath); if (installedTeachers.length === 0) { console.log(chalk.yellow('설치된 선생님이 없습니다.')); console.log(chalk.gray('npx claude-data-learning-teachers를 실행하여 선생님을 설치하세요.')); return; } // 진도 정보 로드 const progressPath = path.join(agentsPath, 'progress.json'); const progressData = await readJsonFile(progressPath); installedTeachers.forEach(teacher => { const teacherInfo = getTeacherInfo(teacher.name); const teacherKey = teacher.name.replace('-', '_'); const progress = progressData?.teachers?.[teacherKey]; console.log(`${teacherInfo.emoji} ${chalk.cyan(teacherInfo.name)}`); console.log(` ${chalk.gray(teacherInfo.description)}`); if (progress) { console.log(` 진도: ${createProgressBar(progress.progress)} ${progress.progress}%`); console.log(` 현재 주제: ${chalk.yellow(progress.currentTopic)}`); console.log(` 완료 과제: ${progress.completedTasks}/${progress.totalTasks}`); } console.log(` 파일: ${chalk.gray(teacher.fileName)}`); console.log(); }); // 학습 통계 if (progressData) { displayLearningStats(progressData); } } catch (error) { console.error(chalk.red('❌ 선생님 목록을 가져오는 중 오류가 발생했습니다:'), error.message); } } /** * 학습 통계 표시 * @param {Object} progressData - 진도 데이터 */ function displayLearningStats(progressData) { console.log(chalk.blue('📊 학습 통계')); console.log(`학습 시작일: ${chalk.cyan(progressData.learner.startDate)}`); console.log(`현재 주차: ${chalk.cyan(progressData.learner.currentWeek)}주차`); console.log(`학습 수준: ${chalk.cyan(progressData.learner.level)}`); const totalTeachers = Object.keys(progressData.teachers).length; const totalProgress = Object.values(progressData.teachers) .reduce((sum, teacher) => sum + teacher.progress, 0) / totalTeachers; console.log(`전체 진도: ${createProgressBar(totalProgress)} ${totalProgress.toFixed(1)}%`); if (progressData.achievements && progressData.achievements.length > 0) { console.log('\n🏆 달성 기록:'); progressData.achievements.slice(-3).forEach(achievement => { console.log(` ${chalk.green('✅')} ${achievement.title} (${achievement.date})`); }); } } /** * 학습 로드맵 생성 * @param {string} agentsPath - agents 디렉토리 경로 */ async function generateLearningRoadmap(agentsPath) { console.log(chalk.blue('\n🗺️ 개인 맞춤 학습 로드맵 생성\n')); try { const installedTeachers = await getInstalledTeachers(agentsPath); const progressPath = path.join(agentsPath, 'progress.json'); const progressData = await readJsonFile(progressPath); if (!progressData) { console.log(chalk.yellow('진도 데이터가 없습니다. 먼저 선생님을 설치해주세요.')); return; } const roadmapPath = path.join(agentsPath, 'LEARNING_ROADMAP.md'); const roadmapContent = await generateRoadmapContent(installedTeachers, progressData); await fs.writeFile(roadmapPath, roadmapContent, 'utf-8'); console.log(chalk.green('✅ 학습 로드맵이 생성되었습니다!')); console.log(chalk.gray(`📄 파일 위치: ${roadmapPath}`)); // 로드맵 미리보기 console.log(chalk.blue('\n📋 로드맵 미리보기:')); await displayRoadmapPreview(installedTeachers, progressData); } catch (error) { console.error(chalk.red('❌ 로드맵 생성 중 오류가 발생했습니다:'), error.message); } } /** * 로드맵 내용 생성 * @param {Array} installedTeachers - 설치된 선생님 목록 * @param {Object} progressData - 진도 데이터 * @returns {string} 로드맵 마크다운 내용 */ async function generateRoadmapContent(installedTeachers, progressData) { const currentDate = getCurrentDate(); const level = progressData.learner.level; let content = `# 🗺️ 개인 맞춤 학습 로드맵 생성일: ${currentDate} 학습자 수준: ${level} 설치된 선생님: ${installedTeachers.length}명 ## 📊 현재 학습 현황 `; // 각 선생님별 현황 installedTeachers.forEach(teacher => { const teacherInfo = getTeacherInfo(teacher.name); const teacherKey = teacher.name.replace('-', '_'); const progress = progressData.teachers[teacherKey]; content += `### ${teacherInfo.emoji} ${teacherInfo.name} **현재 진도**: ${createProgressBar(progress.progress)} ${progress.progress}% **현재 주제**: ${progress.currentTopic} **완료 과제**: ${progress.completedTasks}/${progress.totalTasks} `; }); content += `## 🎯 추천 학습 순서 `; // 학습 순서 추천 const recommendedOrder = getRecommendedLearningOrder(installedTeachers, level); recommendedOrder.forEach((step, index) => { content += `### ${index + 1}단계: ${step.emoji} ${step.name} **예상 기간**: ${step.duration} **주요 학습 목표**: ${step.goals.map(goal => `- ${goal}`).join('\n')} **핵심 과제**: ${step.tasks.map(task => `- [ ] ${task}`).join('\n')} `; }); content += `## 📅 학습 계획 ### 주차별 목표 `; // 주차별 계획 for (let week = 1; week <= 12; week++) { const weeklyPlan = getWeeklyPlan(week, level, installedTeachers); content += `**${week}주차**: ${weeklyPlan.title} - ${weeklyPlan.description} `; } content += `## 🏆 마일스톤 `; // 마일스톤 정의 const milestones = getMilestones(level); milestones.forEach(milestone => { const completed = progressData.achievements.some(a => a.title.includes(milestone.title)); const status = completed ? '✅' : '⭕'; content += `${status} **${milestone.title}** (${milestone.week}주차) ${milestone.description} `; }); return content; } /** * 로드맵 미리보기 표시 * @param {Array} installedTeachers - 설치된 선생님 목록 * @param {Object} progressData - 진도 데이터 */ async function displayRoadmapPreview(installedTeachers, progressData) { const level = progressData.learner.level; const recommendedOrder = getRecommendedLearningOrder(installedTeachers, level); console.log(chalk.yellow('🎯 추천 학습 순서:')); recommendedOrder.slice(0, 3).forEach((step, index) => { console.log(` ${index + 1}. ${step.emoji} ${step.name} (${step.duration})`); }); console.log(chalk.yellow('\n📅 이번 주 목표:')); const currentWeek = progressData.learner.currentWeek; const weeklyPlan = getWeeklyPlan(currentWeek, level, installedTeachers); console.log(` ${weeklyPlan.title}`); console.log(` ${chalk.gray(weeklyPlan.description)}`); } /** * 추천 학습 순서 생성 * @param {Array} installedTeachers - 설치된 선생님 목록 * @param {string} level - 학습 수준 * @returns {Array} 추천 순서 */ function getRecommendedLearningOrder(installedTeachers, level) { const orderTemplates = { 'beginner': [ { name: '데이터 엔지니어링 기초', emoji: '📊', duration: '2-3주', goals: ['ETL 개념 이해', '파이프라인 기초 구현'], tasks: ['CSV to Database ETL 스크립트', '간단한 데이터 검증 로직'] }, { name: '데이터 분석 기초', emoji: '📈', duration: '2-3주', goals: ['SQL 기초 마스터', '탐색적 데이터 분석'], tasks: ['복잡한 JOIN 쿼리 작성', '데이터 시각화 대시보드'] }, { name: '데이터 아키텍처 설계', emoji: '🏗️', duration: '3-4주', goals: ['ERD 설계', '데이터 모델링'], tasks: ['실제 비즈니스 ERD 설계', '정규화/비정규화 결정'] } ], 'intermediate': [ { name: '실시간 데이터 처리', emoji: '📊', duration: '3-4주', goals: ['Kafka 마스터', '스트림 처리 구현'], tasks: ['실시간 로그 처리 파이프라인', 'Kafka Connect 설정'] }, { name: 'ML 파이프라인 구축', emoji: '🔬', duration: '4-5주', goals: ['MLOps 기초', '모델 배포'], tasks: ['Feature Store 구축', '모델 서빙 API'] } ], 'advanced': [ { name: '분산 시스템 아키텍처', emoji: '🏗️', duration: '4-6주', goals: ['대용량 처리 설계', '성능 최적화'], tasks: ['샤딩 전략 설계', '분산 캐시 구현'] } ] }; return orderTemplates[level] || orderTemplates['intermediate']; } /** * 주차별 계획 생성 * @param {number} week - 주차 * @param {string} level - 학습 수준 * @param {Array} installedTeachers - 설치된 선생님 목록 * @returns {Object} 주차별 계획 */ function getWeeklyPlan(week, level, installedTeachers) { const plans = { 1: { title: '학습 환경 설정 및 기초 개념', description: '개발 환경 구축과 기본 개념 이해' }, 2: { title: '첫 번째 실습 프로젝트', description: '간단한 ETL 파이프라인 구축' }, 3: { title: '데이터 품질 관리', description: '데이터 검증 및 클렌징 로직 구현' }, 4: { title: 'SQL 심화 학습', description: '복잡한 쿼리 작성 및 최적화' }, 5: { title: '데이터 시각화', description: '대시보드 구축 및 인사이트 도출' }, 6: { title: 'API 연동 및 자동화', description: '외부 API 데이터 수집 자동화' }, 7: { title: '실시간 처리 입문', description: 'Kafka 기초 및 스트림 처리' }, 8: { title: '클라우드 서비스 활용', description: 'AWS/GCP 데이터 서비스 활용' }, 9: { title: '머신러닝 파이프라인', description: 'ML 모델 훈련 및 배포' }, 10: { title: '모니터링 및 알람', description: '시스템 모니터링 구축' }, 11: { title: '성능 최적화', description: '파이프라인 성능 튜닝' }, 12: { title: '프로젝트 완성 및 리뷰', description: '전체 프로젝트 통합 및 회고' } }; return plans[week] || { title: '심화 학습', description: '개인별 관심 분야 심화 학습' }; } /** * 마일스톤 정의 * @param {string} level - 학습 수준 * @returns {Array} 마일스톤 목록 */ function getMilestones(level) { return [ { title: '첫 ETL 스크립트 완성', week: 2, description: 'CSV 파일을 데이터베이스로 전송하는 스크립트 완성' }, { title: '첫 대시보드 구축', week: 5, description: '실제 데이터를 활용한 시각화 대시보드 완성' }, { title: '실시간 파이프라인 구축', week: 8, description: 'Kafka를 활용한 실시간 데이터 처리 파이프라인 완성' }, { title: 'ML 모델 배포', week: 10, description: '머신러닝 모델을 실제 서비스에 배포' }, { title: '전체 프로젝트 완성', week: 12, description: '엔드투엔드 데이터 플랫폼 구축 완성' } ]; } module.exports = { listInstalledTeachers, generateLearningRoadmap, displayLearningStats, displayRoadmapPreview };