UNPKG

requirements-analysis

Version:

简化的需求分析MCP服务 - 基于AI软件工程(优化版)6步流程

228 lines (182 loc) 6.25 kB
/** * 文件存储管理 */ import { promises as fs } from 'fs'; import { join, dirname } from 'path'; import { StepResult, AnalysisSession } from '../types'; import { Logger } from '../utils/logger'; export class FileStorage { private baseDir: string; private logger: Logger; constructor(baseDir: string = './outputs', logger: Logger) { this.baseDir = baseDir; this.logger = logger; } /** * 确保目录存在 */ private async ensureDir(dirPath: string): Promise<void> { try { await fs.access(dirPath); } catch { await fs.mkdir(dirPath, { recursive: true }); } } /** * 获取项目输出目录 */ getProjectDir(projectName: string): string { // 清理项目名称,移除特殊字符 const cleanName = projectName.replace(/[<>:"/\\|?*]/g, '-').trim(); return join(this.baseDir, cleanName); } /** * 保存步骤结果 */ async saveStepResult(session: AnalysisSession, stepResult: StepResult): Promise<string> { const projectDir = this.getProjectDir(session.projectInfo.projectName); this.logger.info( `准备保存步骤${stepResult.stepNumber}结果`, session.sessionId, stepResult.stepNumber, { projectDir, fileName: stepResult.filePath } ); await this.ensureDir(projectDir); const filePath = join(projectDir, stepResult.filePath); // 生成文档内容 const content = this.generateStepDocument(session, stepResult); this.logger.info( `生成文档内容完成`, session.sessionId, stepResult.stepNumber, { filePath, contentLength: content.length } ); try { await fs.writeFile(filePath, content, 'utf-8'); // 验证文件是否真的被创建 const stats = await fs.stat(filePath); this.logger.info( `步骤${stepResult.stepNumber}结果已保存`, session.sessionId, stepResult.stepNumber, { filePath, fileSize: stats.size, absolutePath: require('path').resolve(filePath) } ); return filePath; } catch (error) { this.logger.error( `保存步骤${stepResult.stepNumber}结果失败`, session.sessionId, stepResult.stepNumber, { error: error instanceof Error ? error.message : String(error), filePath } ); throw error; } } /** * 生成步骤文档内容(优化版:只保存结果) */ private generateStepDocument(session: AnalysisSession, stepResult: StepResult): string { const timestamp = stepResult.timestamp.toLocaleString('zh-CN'); return `# ${stepResult.stepName} ${stepResult.result} --- *生成时间: ${timestamp} | 项目: ${session.projectInfo.projectName} | 步骤: ${stepResult.stepNumber}/6* `; } /** * 读取步骤结果 */ async readStepResult(projectName: string, stepNumber: number): Promise<string | null> { const projectDir = this.getProjectDir(projectName); const fileName = `step${stepNumber}-*.md`; try { const files = await fs.readdir(projectDir); const stepFile = files.find(file => file.startsWith(`step${stepNumber}-`)); if (!stepFile) { return null; } const filePath = join(projectDir, stepFile); return await fs.readFile(filePath, 'utf-8'); } catch { return null; } } /** * 列出项目文件 */ async listProjectFiles(projectName: string): Promise<string[]> { const projectDir = this.getProjectDir(projectName); try { const files = await fs.readdir(projectDir); return files.filter(file => file.endsWith('.md')).sort(); } catch { return []; } } /** * 获取所有项目 */ async listProjects(): Promise<string[]> { try { await this.ensureDir(this.baseDir); const dirs = await fs.readdir(this.baseDir, { withFileTypes: true }); return dirs .filter(dirent => dirent.isDirectory()) .map(dirent => dirent.name) .sort(); } catch { return []; } } /** * 保存项目摘要 */ async saveProjectSummary(session: AnalysisSession): Promise<void> { const projectDir = this.getProjectDir(session.projectInfo.projectName); await this.ensureDir(projectDir); const summaryPath = join(projectDir, 'README.md'); const content = this.generateProjectSummary(session); await fs.writeFile(summaryPath, content, 'utf-8'); this.logger.info( '项目摘要已保存', session.sessionId, undefined, { summaryPath } ); } /** * 生成项目摘要 */ private generateProjectSummary(session: AnalysisSession): string { const completedSteps = Array.from(session.stepResults.keys()).sort(); const progress = Math.round((completedSteps.length / session.totalSteps) * 100); return `# ${session.projectInfo.projectName} - 需求分析报告 ## 📋 项目信息 - **项目名称**: ${session.projectInfo.projectName} - **项目类型**: ${session.projectInfo.projectType} - **所属行业**: ${session.projectInfo.industry} - **开始时间**: ${session.startTime.toLocaleString('zh-CN')} - **最后更新**: ${session.lastUpdateTime.toLocaleString('zh-CN')} - **完成进度**: ${progress}% (${completedSteps.length}/${session.totalSteps}) - **状态**: ${session.isComplete ? '已完成' : '进行中'} ## 🎯 项目背景 ${session.projectInfo.background} ## 🚀 核心目标 ${session.projectInfo.objectives} ## 📁 文档列表 ${completedSteps.map(stepNum => { const stepResult = session.stepResults.get(stepNum); return `- [第${stepNum}步:${stepResult?.stepName}](${stepResult?.filePath})`; }).join('\n')} ## 📊 分析流程 1. ✅ 项目基础信息填写 (5分钟) 2. ${completedSteps.includes(2) ? '✅' : '⏳'} AI智能分析项目全貌 (10分钟) 3. ${completedSteps.includes(3) ? '✅' : '⏳'} 生成需求分析文档初版 (10分钟) 4. ${completedSteps.includes(4) ? '✅' : '⏳'} AI质量分析 (8分钟) 5. ${completedSteps.includes(5) ? '✅' : '⏳'} 生成改进建议 (5分钟) 6. ${completedSteps.includes(6) ? '✅' : '⏳'} 生成最终文档 (10分钟) --- *此报告由需求分析MCP服务自动生成* `; } }