speccore 6.33.0 → 6.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1665,47 +1665,56 @@ async function generateSpecsFromRequirements(reqPaths, iteration, specDir) {
1665
1665
  const now = new Date().toISOString().split('T')[0];
1666
1666
  // 3. 生成各 Spec 文件
1667
1667
  const files = [];
1668
- // REQUIREMENT.md — 结构化需求规格
1668
+ // ── 全局文档(跨端通用)──
1669
+ // REQUIREMENT.md — 结构化需求规格(业务功能 + API + 数据模型 + 业务规则)
1669
1670
  files.push({
1670
1671
  filename: 'REQUIREMENT.md',
1671
1672
  content: buildRequirementSpec(iteration, now, features, apis, dataModels, businessRules),
1672
1673
  });
1673
- // TECH.md — 技术方案
1674
- files.push({
1675
- filename: 'TECH.md',
1676
- content: buildTechSpec(iteration, now, apis, dataModels, archImpact, platforms, features, uiPatterns),
1677
- });
1678
- // TEST.md — 测试计划
1674
+ // ANALYSIS.md — 需求分析报告(完整性检查 + 架构影响 + 待确认清单)
1675
+ const issues = scanCompleteness(fullContent);
1676
+ const archImpactForAnalysis = await analyzeArchitectureImpact(fullContent);
1679
1677
  files.push({
1680
- filename: 'TEST.md',
1681
- content: buildTestSpec(iteration, now, features, apis),
1678
+ filename: 'ANALYSIS.md',
1679
+ content: buildIterationReqReport({}, issues, archImpactForAnalysis, {}),
1682
1680
  });
1683
- // REVIEW.md — 评审清单
1681
+ // DEPS.md — 依赖清单(全局公共依赖)
1684
1682
  files.push({
1685
- filename: 'REVIEW.md',
1686
- content: buildReviewSpec(iteration, now, apis, archImpact),
1683
+ filename: 'DEPS.md',
1684
+ content: buildDepsSpec(iteration, now, archImpact),
1687
1685
  });
1688
- // RISK.md — 风险评估
1686
+ // RISK.md — 风险评估(全局风险)
1689
1687
  files.push({
1690
1688
  filename: 'RISK.md',
1691
1689
  content: buildRiskSpec(iteration, now, archImpact),
1692
1690
  });
1693
- // DEPS.md — 依赖清单
1694
- files.push({
1695
- filename: 'DEPS.md',
1696
- content: buildDepsSpec(iteration, now, archImpact),
1697
- });
1698
- // MONITOR.md — 监控指标
1691
+ // MONITOR.md — 监控指标(全局指标)
1699
1692
  files.push({
1700
1693
  filename: 'MONITOR.md',
1701
1694
  content: buildMonitorSpec(iteration, now, apis, features),
1702
1695
  });
1703
- // UI_SPEC.md — 前端 UI 规格
1696
+ // REVIEW.md — 评审清单(全局评审要点)
1704
1697
  files.push({
1705
- filename: 'UI_SPEC.md',
1706
- content: buildUISpec(iteration, now, uiPatterns),
1698
+ filename: 'REVIEW.md',
1699
+ content: buildReviewSpec(iteration, now, apis, archImpact),
1707
1700
  });
1708
- // 4. 写入文件(覆盖空模板,不覆盖已有实质内容的文件)
1701
+ // ── 各端专属文档 ──
1702
+ for (const platform of platforms) {
1703
+ const platformDir = (0, path_1.join)(specDir, platform);
1704
+ await (0, fs_extra_1.ensureDir)(platformDir);
1705
+ // TECH.md — 该端技术方案
1706
+ const techContent = buildTechSpecForPlatform(iteration, now, apis, dataModels, archImpact, platform, features, uiPatterns);
1707
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(platformDir, 'TECH.md'), techContent);
1708
+ // TEST.md — 该端测试计划
1709
+ const testContent = buildTestSpecForPlatform(iteration, now, features, apis, platform);
1710
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(platformDir, 'TEST.md'), testContent);
1711
+ // UI_SPEC.md — 该端 UI 规格(仅前端)
1712
+ if (!isBackendPlatform(platform)) {
1713
+ const uiContent = buildUISpecForPlatform(iteration, now, uiPatterns, platform);
1714
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(platformDir, 'UI_SPEC.md'), uiContent);
1715
+ }
1716
+ }
1717
+ // 4. 写入全局文件(覆盖空模板,不覆盖已有实质内容的文件)
1709
1718
  let withContent = 0;
1710
1719
  let skipped = 0;
1711
1720
  await (0, fs_extra_1.ensureDir)(specDir);
@@ -1725,7 +1734,7 @@ async function generateSpecsFromRequirements(reqPaths, iteration, specDir) {
1725
1734
  }
1726
1735
  return {
1727
1736
  files,
1728
- summary: { total: files.length, withContent, skipped },
1737
+ summary: { total: files.length + platforms.length * 3, withContent, skipped },
1729
1738
  };
1730
1739
  }
1731
1740
  // ── 信息提取工具函数 ──
@@ -1829,6 +1838,10 @@ function extractBusinessRules(content) {
1829
1838
  }
1830
1839
  return rules.slice(0, 15);
1831
1840
  }
1841
+ // ── 辅助函数:判断是否为后端平台 ──
1842
+ function isBackendPlatform(platform) {
1843
+ return platform === 'backend' || platform.startsWith('后台') || platform.includes('服务');
1844
+ }
1832
1845
  function stripTemplateNoise(content) {
1833
1846
  // 移除模板占位符后计算有效内容长度
1834
1847
  return content
@@ -1952,7 +1965,148 @@ function buildTechSpec(iter, now, apis, models, archImpact, platforms, features,
1952
1965
  }
1953
1966
  return md;
1954
1967
  }
1955
- // ── UI 规格提取与构建 ──
1968
+ // ── 按端专属文档构建器 ──
1969
+ /**
1970
+ * 生成指定端的技术方案(该端专属内容)
1971
+ */
1972
+ function buildTechSpecForPlatform(iter, now, apis, models, archImpact, platform, features, uiPatterns) {
1973
+ let md = `# ${platform} 端技术方案\n\n> 迭代: ${iter} | 端: ${platform} | 生成: ${now}\n\n`;
1974
+ if (isBackendPlatform(platform)) {
1975
+ // 后端专属内容
1976
+ md += `## 1. 接口设计\n\n`;
1977
+ const backendApis = apis.filter(a => !a.path.startsWith('/h5') && !a.path.startsWith('/admin'));
1978
+ if (backendApis.length > 0) {
1979
+ md += `| 方法 | 路径 | 说明 |\n| :--- | :--- | :--- |\n`;
1980
+ backendApis.forEach(a => { md += `| ${a.method} | \`${a.path}\` | ${a.desc || '—'} |\n`; });
1981
+ }
1982
+ else {
1983
+ md += `_未检测到后端 API,需根据需求补充。_\n`;
1984
+ }
1985
+ md += `\n## 2. 数据模型\n\n`;
1986
+ if (models.length > 0) {
1987
+ md += `| 表名 | 字段 | 说明 |\n| :--- | :--- | :--- |\n`;
1988
+ models.forEach(m => { md += `| \`${m.table}\` | ${m.fields || '待补充'} | ${m.desc} |\n`; });
1989
+ }
1990
+ else {
1991
+ md += `_需求中未检测到数据模型,需根据功能需求推导。_\n`;
1992
+ }
1993
+ md += `\n## 3. 业务逻辑\n\n`;
1994
+ md += `_待 AI 分析各功能的实现细节、事务约束、异常处理。_\n`;
1995
+ }
1996
+ else {
1997
+ // 前端专属内容
1998
+ md += `## 1. 页面结构\n\n`;
1999
+ const platformPages = uiPatterns.pages.filter(p => p.route.includes(`/${platform}`) || p.name.includes(platform));
2000
+ if (platformPages.length > 0) {
2001
+ md += `| 页面 | 路由 | 描述 |\n| :--- | :--- | :--- |\n`;
2002
+ platformPages.forEach(p => { md += `| ${p.name} | \`${p.route}\` | ${p.desc} |\n`; });
2003
+ }
2004
+ else {
2005
+ md += `_待补充:从需求中提取 ${platform} 端的页面清单。_\n`;
2006
+ }
2007
+ md += `\n## 2. 组件设计\n\n`;
2008
+ const platformComponents = uiPatterns.components.filter(c => c.page.includes(platform) || c.type.includes(platform));
2009
+ if (platformComponents.length > 0) {
2010
+ md += `| 组件 | 类型 | 所属页面 |\n| :--- | :--- | :--- |\n`;
2011
+ platformComponents.forEach(c => { md += `| ${c.name} | ${c.type} | ${c.page} |\n`; });
2012
+ }
2013
+ else {
2014
+ md += `_待补充:从需求中提取 ${platform} 端的组件清单。_\n`;
2015
+ }
2016
+ md += `\n## 3. 状态管理\n\n`;
2017
+ md += `_待 AI 分析 ${platform} 端的状态管理方案(Pinia/Redux/Context 等)。_\n`;
2018
+ md += `\n## 4. 交互设计\n\n`;
2019
+ if (platform === 'h5' || platform === 'miniapp') {
2020
+ md += `- 触摸交互优化\n- 弱网环境适配\n- 响应式布局\n`;
2021
+ }
2022
+ else if (platform === 'admin') {
2023
+ md += `- 表格/表单交互规范\n- 权限控制\n- 批量操作\n`;
2024
+ }
2025
+ else {
2026
+ md += `_待补充 ${platform} 端特有的交互要求。_\n`;
2027
+ }
2028
+ }
2029
+ return md;
2030
+ }
2031
+ /**
2032
+ * 生成指定端的测试计划(该端专属内容)
2033
+ */
2034
+ function buildTestSpecForPlatform(iter, now, features, apis, platform) {
2035
+ let md = `# ${platform} 端测试计划\n\n> 迭代: ${iter} | 端: ${platform} | 生成: ${now}\n\n`;
2036
+ if (isBackendPlatform(platform)) {
2037
+ md += `## 1. 接口测试\n\n`;
2038
+ const backendApis = apis.filter(a => !a.path.startsWith('/h5') && !a.path.startsWith('/admin'));
2039
+ if (backendApis.length > 0) {
2040
+ backendApis.forEach(a => {
2041
+ md += `- [ ] ${a.method} ${a.path}: ${a.desc || '验证接口功能'}\n`;
2042
+ });
2043
+ }
2044
+ else {
2045
+ md += `_待补充:根据需求编写接口测试用例。_\n`;
2046
+ }
2047
+ md += `\n## 2. 性能测试\n\n`;
2048
+ md += `- QPS 目标:待补充\n- 响应时间 P99:待补充\n- 并发用户数:待补充\n`;
2049
+ }
2050
+ else {
2051
+ md += `## 1. 页面流转测试\n\n`;
2052
+ md += `_待 AI 分析 ${platform} 端的页面跳转流程、入口校验、权限拦截。_\n`;
2053
+ md += `\n## 2. 交互测试\n\n`;
2054
+ if (platform === 'h5' || platform === 'miniapp') {
2055
+ md += `- 触摸手势识别\n- 下拉刷新/上拉加载\n- 键盘弹出适配\n`;
2056
+ }
2057
+ else if (platform === 'admin') {
2058
+ md += `- 表格排序/筛选/分页\n- 表单校验提示\n- 批量操作确认\n`;
2059
+ }
2060
+ md += `\n## 3. 四态测试\n\n`;
2061
+ md += `- 空状态(无数据时展示)\n- 加载中状态\n- 错误状态(网络异常/超时)\n- 成功状态\n`;
2062
+ }
2063
+ return md;
2064
+ }
2065
+ /**
2066
+ * 生成指定端的 UI 规格(仅前端)
2067
+ */
2068
+ function buildUISpecForPlatform(iter, now, uiPatterns, platform) {
2069
+ let md = `# ${platform} 端 UI 规格\n\n> 迭代: ${iter} | 端: ${platform} | 生成: ${now}\n\n`;
2070
+ md += `## 1. 路由表\n\n`;
2071
+ const platformPages = uiPatterns.pages.filter(p => p.route.includes(`/${platform}`) || p.name.includes(platform));
2072
+ if (platformPages.length > 0) {
2073
+ md += `| 页面 | 路由 | 入口 | 权限 |\n| :--- | :--- | :--- | :--- |\n`;
2074
+ platformPages.forEach(p => { md += `| ${p.name} | \`${p.route}\` | 待补充 | 待补充 |\n`; });
2075
+ }
2076
+ else {
2077
+ md += `_待补充:从需求中提取 ${platform} 端的路由配置。_\n`;
2078
+ }
2079
+ md += `\n## 2. 组件清单\n\n`;
2080
+ const platformComponents = uiPatterns.components.filter(c => c.page.includes(platform) || c.type.includes(platform));
2081
+ if (platformComponents.length > 0) {
2082
+ md += `| 组件 | 类型 | 复用性 |\n| :--- | :--- | :--- |\n`;
2083
+ platformComponents.forEach(c => { md += `| ${c.name} | ${c.type} | 高/中/低 |\n`; });
2084
+ }
2085
+ else {
2086
+ md += `_待补充:从需求中提取 ${platform} 端的组件清单。_\n`;
2087
+ }
2088
+ md += `\n## 3. 字段→UI 映射\n\n`;
2089
+ const platformFields = uiPatterns.formFields.filter(f => f.page.includes(platform));
2090
+ if (platformFields.length > 0) {
2091
+ md += `| 页面/表单 | 字段 | UI 组件 |\n| :--- | :--- | :--- |\n`;
2092
+ platformFields.forEach(f => { md += `| ${f.page} | ${f.fields.join(', ')} | Input/Select/DatePicker |\n`; });
2093
+ }
2094
+ else {
2095
+ md += `_待补充:从需求中提取 ${platform} 端的字段与 UI 映射关系。_\n`;
2096
+ }
2097
+ md += `\n## 4. 状态枚举\n\n`;
2098
+ if (uiPatterns.statusEnums.length > 0) {
2099
+ md += `| 字段 | 值 | 含义 |\n| :--- | :--- | :--- |\n`;
2100
+ uiPatterns.statusEnums.forEach(s => {
2101
+ md += `| ${s.field} | ${s.values.join(' / ')} | ${s.labels.join(' / ')} |\n`;
2102
+ });
2103
+ }
2104
+ else {
2105
+ md += `_待补充:前后端共享的状态值定义。_\n`;
2106
+ }
2107
+ return md;
2108
+ }
2109
+ // ─ UI 规格提取与构建 ──
1956
2110
  function extractUIPatterns(content) {
1957
2111
  const pages = [];
1958
2112
  const components = [];