核心说明:基于工业化软件工程视角构建,包含可直接复用的代码、明确的验收标准,帮团队把"纸面规则"变成"自动生效的工程约束"
关联文档:docs/rules-roadmap.md
工程师手记:这不是纸上谈兵的规则文档,而是能直接上手的工程化施工蓝图------每个步骤都配了可运行的代码片段和明确的验收标尺,跟着做就能把规则体系从"被动遵守"改成"主动约束"。
🎯 项目核心:从"文档驱动"到"工程驱动"的升级
一、核心目标
彻底解决规则"落地难、验证难、追溯难"的问题,实现三大核心价值:
- 可执行:规则文档自动转成ESLint/TS等工具配置,无需人工翻译
- 可验证:每个规则绑定专属测试用例,对错有明确标准
- 可度量:规则执行效果量化成指标,优化方向清晰可见
二、技术流转架构
整个规则体系的技术流转链路如下,核心实现"规则输入-自动解析-配置输出-验证闭环":
暂时无法在豆包文档外展示此内容
📋 第一阶段:筑牢根基------核心引擎开发(第1-2周)
目标:搞定"规则解析"和"配置生成"两大核心工具,让规则从文档里"活"起来
1.1 规则解析器:把Markdown转成可计算数据
核心作用:读取规则文档,自动提取元信息、配置片段和示例代码,避免人工复制出错。
ini
// scripts/rule-parser.js
const fs = require('fs');
const yaml = require('yaml');
const marked = require('marked');
class RuleParser {
constructor() {
this.rules = new Map(); // 存储解析后的规则集合
}
// 解析单个规则文件,处理Frontmatter和正文分离的格式
parseRuleFile(filePath) {
const content = fs.readFileSync(filePath, 'utf8');
const parts = content.split('---'); // 拆分Frontmatter和正文(兼容多组---分隔的场景)
if (parts.length < 3) {
throw new Error(`规则文件格式错误:${filePath} 缺少Frontmatter`);
}
// 解析Frontmatter元信息(规则标题、作者、优先级等)
const frontmatter = yaml.parse(parts[1]);
// 合并剩余部分作为Markdown正文(避免拆分时丢失内容)
const markdown = parts.slice(2).join('---');
return {
metadata: frontmatter,
content: markdown,
filePath,
configs: this.extractConfigs(markdown), // 提取工具配置片段
examples: this.extractExamples(markdown) // 提取正反示例代码
};
}
// 从Markdown中提取工具配置(ESLint/TS等)
extractConfigs(markdown) {
const configs = {};
// 匹配所有代码块(支持任意语言标识)
const codeBlocks = markdown.match(/```(\w+)\n([\s\S]*?)\n```/g) || [];
codeBlocks.forEach(block => {
const [, lang, code] = block.match(/```(\w+)\n([\s\S]*?)\n```/);
// 识别ESLint配置(javascript代码块且包含eslint关键字)
if (lang === 'javascript' && code.includes('eslint')) {
configs.eslint = this.parseESLintConfig(code);
}
// 识别TS配置(json代码块且包含compilerOptions)
if (lang === 'json' && code.includes('compilerOptions')) {
configs.typescript = JSON.parse(code);
}
});
return configs;
}
// 提取正反示例代码(区分✅正确示例和❌错误示例)
extractExamples(markdown) {
const examples = { good: [], bad: [] };
const lines = markdown.split('\n');
let currentExampleType = null; // 标记当前处理的示例类型(good/bad)
let inCodeBlock = false; // 标记是否进入代码块内部
lines.forEach(line => {
// 识别示例类型标记
if (line.includes('✅')) {
currentExampleType = 'good';
} else if (line.includes('❌')) {
currentExampleType = 'bad';
}
// 处理代码块开始/结束标记
else if (line.startsWith('```') && currentExampleType) {
inCodeBlock = !inCodeBlock;
// 代码块结束时重置类型,避免跨示例污染
if (!inCodeBlock) currentExampleType = null;
}
// 收集代码块内容
else if (inCodeBlock && currentExampleType) {
examples[currentExampleType].push(line);
}
});
return examples;
}
}
module.exports = RuleParser;
验收标准(必须全部达标)
- 能解析docs/rules目录下所有现有规则文件(当前共87个),无解析错误
- 配置片段提取准确率≥95%(人工抽样50个规则验证,错误不超过3个)
- 单目录100个规则文件批量解析时间≤2秒(本地Node.js环境测试)
1.2 配置生成器:自动输出可用工具配置
核心作用:把解析器提取的配置片段,整合成ESLint、TypeScript能直接使用的完整配置文件。
javascript
// scripts/config-generator.js
const fs = require('fs');
const RuleParser = require('./rule-parser');
class ConfigGenerator {
constructor() {
this.parser = new RuleParser();
// 初始化基础配置模板(避免重复编写通用规则)
this.baseConfigs = {
eslint: {
extends: ['@antfu/eslint-config-vue', '@antfu/eslint-config-typescript'],
rules: {}
},
typescript: {
compilerOptions: {
target: 'ES2020',
module: 'ESNext',
moduleResolution: 'node',
strict: true,
jsx: 'preserve',
esModuleInterop: true,
skipLibCheck: true,
forceConsistentCasingInFileNames: true
}
},
prettier: {}
};
}
// 生成ESLint配置(合并基础规则和自定义规则)
generateESLintConfig() {
const ruleFiles = this.getAllRuleFiles(); // 获取所有规则文件路径
ruleFiles.forEach(file => {
const rule = this.parser.parseRuleFile(file);
// 合并当前规则的ESLint配置(优先级:自定义规则>基础规则)
if (rule.configs.eslint) {
Object.assign(this.baseConfigs.eslint.rules, rule.configs.eslint);
}
});
// 追加团队通用强制规则(避免遗漏核心约束)
this.baseConfigs.eslint.rules = {
...this.baseConfigs.eslint.rules,
'@typescript-eslint/no-unused-vars': 'error', // 禁止未使用变量
'vue/component-name-in-template-casing': ['error', 'PascalCase'] // Vue组件名大写
};
return this.baseConfigs.eslint;
}
// 生成TypeScript配置(合并基础编译选项和规则扩展)
generateTypeScriptConfig() {
const ruleFiles = this.getAllRuleFiles();
ruleFiles.forEach(file => {
const rule = this.parser.parseRuleFile(file);
if (rule.configs.typescript) {
Object.assign(this.baseConfigs.typescript.compilerOptions, rule.configs.typescript);
}
});
return this.baseConfigs.typescript;
}
// 写入配置文件到项目根目录(生成带标识的文件,避免覆盖手动配置)
writeConfigs() {
const eslintConfig = this.generateESLintConfig();
const tsConfig = this.generateTypeScriptConfig();
// 写入ESLint配置(后缀.generated标识自动生成)
fs.writeFileSync(
'.eslintrc.generated.js',
`// 自动生成,请勿手动修改 ------ 来源:规则体系工程化工具\nmodule.exports = ${JSON.stringify(eslintConfig, null, 2)}`
);
// 写入TS配置
fs.writeFileSync(
'tsconfig.generated.json',
`// 自动生成,请勿手动修改 ------ 来源:规则体系工程化工具\n${JSON.stringify(tsConfig, null, 2)}`
);
console.log('✅ 工具配置生成完成!可直接引用 .generated 后缀的配置文件');
}
// 辅助方法:获取所有规则文件路径(可根据实际目录调整)
getAllRuleFiles() {
return fs.readdirSync('./docs/rules').filter(file => file.endsWith('.md')).map(file => `./docs/rules/${file}`);
}
}
module.exports = ConfigGenerator;
验收标准(必须全部达标)
- 生成的.eslintrc.generated.js通过
npx eslint --config .eslintrc.generated.js --validate-config验证 - tsconfig.generated.json配合项目代码编译无错误(执行
tsc --project tsconfig.generated.json无异常) - 配置覆盖所有核心规则(87个规则中至少78个被纳入配置,覆盖率≥90%)
🧪 第二阶段:验证闭环------AI测试体系搭建(第3周)
目标:给每个规则配"自动考官",用AI生成测试用例并验证规则执行效果,避免规则落地走样。
2.1 AI测试用例生成器:规则的"专属题库"
核心作用:根据规则的正反示例,自动生成AI可执行的测试用例,验证AI对规则的理解是否准确。
javascript
// scripts/ai-test-generator.js
const RuleParser = require('./rule-parser');
class AITestGenerator {
constructor() {
this.parser = new RuleParser();
}
// 批量生成所有规则的测试套件
generateTestCases() {
const ruleFiles = this.parser.getAllRuleFiles();
const testSuites = [];
ruleFiles.forEach(file => {
const rule = this.parser.parseRuleFile(file);
// 跳过无示例的规则(避免空测试)
if (rule.examples.good.length === 0 && rule.examples.bad.length === 0) return;
const testSuite = this.createTestSuite(rule);
testSuites.push(testSuite);
});
return testSuites;
}
// 为单个规则创建测试套件(包含正向和反向测试)
createTestSuite(rule) {
const { metadata, examples } = rule;
return {
ruleTitle: metadata.title, // 规则标题(用于测试报告定位)
ruleId: metadata.id || rule.filePath, // 规则唯一标识
tests: [
...this.createPositiveTests(examples.good, metadata), // 正向测试(符合规则的代码)
...this.createNegativeTests(examples.bad, metadata) // 反向测试(违反规则的代码)
]
};
}
// 生成正向测试用例(验证AI能识别"正确代码")
createPositiveTests(goodExamples, metadata) {
return goodExamples.map((example, index) => ({
testName: `正向用例${index + 1}:识别符合${metadata.title}的代码`,
inputCode: example.join('\n'), // 拼接代码行
expectedResult: '确认代码符合规则,无需修改',
prompt: `请判断以下代码是否符合《${metadata.title}》规则:\n规则说明:${metadata.description || '无详细说明'}\n代码:\n${example.join('\n')}`,
// 验证AI响应的断言逻辑
assertion: (response) => {
const positiveKeywords = ['符合', '正确', '无需修改', '没问题'];
const negativeKeywords = ['错误', '修改', '违规', '不符合'];
// 包含正向关键词且不包含反向关键词,视为通过
return positiveKeywords.some(k => response.includes(k)) &&
!negativeKeywords.some(k => response.includes(k));
}
}));
}
// 生成反向测试用例(验证AI能识别并修复"错误代码")
createNegativeTests(badExamples, metadata) {
return badExamples.map((example, index) => ({
testName: `反向用例${index + 1}:修复违反${metadata.title}的代码`,
inputCode: example.join('\n'),
expectedResult: '指出代码违规点并给出修复方案',
prompt: `请根据《${metadata.title}》规则,指出以下代码的违规问题并重构:\n规则说明:${metadata.description || '无详细说明'}\n代码:\n${example.join('\n')}`,
assertion: (response) => {
const requiredKeywords = ['违规', '修改', '重构', '建议', '应该'];
// 包含核心关键词,且响应长度比输入代码长(确保给出具体方案)
return requiredKeywords.some(k => response.includes(k)) &&
response.length > example.join('\n').length * 1.2;
}
}));
}
}
2.2 自动化测试执行:让"考官"自动判分
核心作用:集成到测试框架中,自动调用AI执行测试用例并生成报告,快速定位规则理解偏差。
javascript
// tests/ai-acceptance.test.js
const { AITestGenerator } = require('../scripts/ai-test-generator');
const { callAIApi } = require('../scripts/ai-client'); // 实际AI接口调用工具
// 测试套件:验证AI对规则的理解准确性
describe('规则体系 - AI理解验收测试', () => {
const generator = new AITestGenerator();
const testSuites = generator.generateTestCases();
// 为每个规则创建独立测试分组(便于定位问题)
testSuites.forEach(suite => {
describe(`规则:${suite.ruleTitle}(${suite.ruleId})`, () => {
// 执行该规则的所有测试用例
suite.tests.forEach(test => {
it(test.testName, async () => {
// 调用AI接口获取响应(实际项目替换为真实AI API)
const aiResponse = await callAIApi({
prompt: test.prompt,
model: 'gpt-4o-mini', // 可根据成本调整模型
temperature: 0.3 // 降低随机性,确保结果稳定
});
// 验证AI响应是否符合预期
expect(test.assertion(aiResponse)).toBe(true);
}, 10000); // 单个用例超时时间:10秒(适配AI响应速度)
});
});
});
});
// 模拟AI调用(开发阶段用于调试,实际环境替换为真实接口)
async function callAIApi(params) {
// 实际项目中这里替换为:return await axios.post(AI_API_URL, params, { headers: { Authorization: `Bearer ${AI_API_KEY}` } });
console.log(`\n[AI调用] 问题:${params.prompt.slice(0, 50)}...`);
// 模拟响应(开发调试用,实际会删除)
return params.prompt.includes('✅')
? '该代码完全符合规则要求,无需进行修改。'
: '该代码违反了规则中"禁止未定义变量直接使用"的要求,建议先声明变量再赋值,修复后代码如下:const a = 1; console.log(a);';
}
验收标准
- AI测试通过率≥85%(所有测试用例中,通过数量占比不低于85%)
- 核心规则全覆盖(87个规则中,优先级P0/P1的32个规则必须全部包含测试用例)
- 全量测试执行时间≤5分钟(在CI环境中,调用AI完成所有用例测试的总耗时)
🔄 第三阶段:无缝集成------CI/CD流程嵌入(第4周)
目标:把规则检查融入开发流程,做到"提交即检查,违规即拦截",避免问题代码入库。
3.1 Pre-commit钩子:本地提交的"第一道防线"
核心作用:开发者提交代码前自动执行规则检查,提前拦截违规代码,减少CI失败次数。
bash
#!/bin/bash
# .husky/pre-commit (需配合husky工具使用:npx husky install && npx husky add .husky/pre-commit "bash .husky/pre-commit")
echo -e "\n🔍 正在执行规则体系质量检查..."
# 1. 验证规则文件格式(避免提交无效规则)
node scripts/validate-rules.js
if [ $? -ne 0 ]; then
echo -e "\n❌ 规则文件格式错误,请检查docs/rules目录下的Markdown文件"
exit 1
fi
# 2. 检测规则冲突(避免不同规则互相矛盾)
node scripts/detect-conflicts.js
if [ $? -ne 0 ]; then
echo -e "\n❌ 发现规则冲突,请先解决冲突再提交(查看冲突报告:reports/conflicts.md)"
exit 1
fi
# 3. 生成最新配置文件(确保用最新规则检查代码)
node scripts/generate-configs.js
# 4. 用生成的配置执行ESLint检查(只检查暂存区文件,提高效率)
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -E '.(js|ts|vue)$')
if [ -n "$STAGED_FILES" ]; then
npx eslint $STAGED_FILES --config .eslintrc.generated.js --max-warnings 0
if [ $? -ne 0 ]; then
echo -e "\n❌ 代码违反规则,请修复后再提交"
exit 1
fi
fi
echo -e "\n✅ 所有规则检查通过,可正常提交"
exit 0
3.2 GitHub Actions工作流:远程仓库的"终极把关"
核心作用:代码推送到远程或发起PR时,执行全量规则检查和AI测试,确保合并到主分支的代码符合标准。
yaml
# .github/workflows/rules-quality.yml
name: 规则体系质量保障
on:
push:
branches: [ main, develop ] # 主分支和开发分支推送时触发
pull_request:
branches: [ main ] # 合并到主分支的PR触发
jobs:
quality-check:
runs-on: ubuntu-latest
timeout-minutes: 10 # 防止流程卡死,超时自动终止
steps:
- name: 拉取代码
uses: actions/checkout@v3
- name: 配置Node.js环境
uses: actions/setup-node@v3
with:
node-version: '18' # 匹配项目Node版本
cache: 'npm' # 缓存依赖,加速构建
- name: 安装依赖
run: npm ci # 用ci命令确保依赖版本一致
- name: 验证规则文件格式
run: node scripts/validate-rules.js
- name: 检测规则冲突
run: node scripts/detect-conflicts.js
- name: 生成工具配置
run: node scripts/generate-configs.js
- name: 执行AI验收测试
run: npm run test:ai-acceptance # 对应package.json中的脚本
env:
AI_API_KEY: ${{ secrets.AI_API_KEY }} # 从仓库密钥中获取AI密钥
- name: 收集质量指标
run: node scripts/collect-metrics.js
- name: 上传质量报告
uses: actions/upload-artifact@v3
with:
name: 规则体系质量报告-${{ github.sha }}
path: reports/ # 上传所有报告文件
retention-days: 7 # 报告保留7天,节省存储空间
验收标准
- CI流水线成功率≥95%(正常代码提交时,流水线通过概率不低于95%)
- 全量检查执行时间≤5分钟(从拉取代码到生成报告的总耗时)
- 质量报告自动生成(包含规则覆盖率、AI测试通过率等核心指标,格式为JSON+HTML)
📊 第四阶段:持续监控------质量度量与优化(第5-6周)
目标:把规则体系的运行状态"可视化",通过数据发现优化点,让规则持续适配团队需求。
4.1 质量指标收集器:规则的"健康体检仪"
核心作用:自动收集规则覆盖率、代码违规数、AI理解准确率等指标,为优化提供数据支撑。
javascript
// scripts/metrics-collector.js
const fs = require('fs');
const glob = require('glob');
const { execSync } = require('child_process');
class MetricsCollector {
// 主方法:收集所有维度指标并输出
async collectMetrics() {
const metrics = {
collectTime: new Date().toISOString(), // 收集时间戳
rulesMetrics: await this.getRulesMetrics(), // 规则本身指标
codeMetrics: await this.getCodeMetrics(), // 代码质量指标
aiMetrics: await this.getAIMetrics(), // AI测试指标
pipelineMetrics: await this.getPipelineMetrics() // 流水线指标
};
// 写入指标文件(用于看板展示和历史追溯)
fs.mkdirSync('reports/metrics', { recursive: true });
fs.writeFileSync(
`reports/metrics/${new Date().getTime()}.json`,
JSON.stringify(metrics, null, 2)
);
return metrics;
}
// 1. 规则本身指标(覆盖率、冲突数等)
async getRulesMetrics() {
const ruleFiles = glob.sync('./docs/rules/**/*.md');
const totalRules = ruleFiles.length;
const coveredRules = fs.readFileSync('.eslintrc.generated.js', 'utf8')
.match(/'@typescript-eslint|vue|import/g)?.length || 0; // 简化计算,实际需更精准
return {
totalRules, // 规则总数
coverageRate: (coveredRules / totalRules * 100).toFixed(2) + '%', // 规则覆盖率
conflictCount: this.countConflicts(), // 规则冲突数
lastUpdateTime: this.getLastRuleUpdateTime(ruleFiles) // 规则最后更新时间
};
}
// 2. 代码质量指标(违规数、质量分等)
async getCodeMetrics() {
// 执行ESLint并获取结果(实际项目可集成eslint-api避免命令行调用)
const eslintOutput = execSync('npx eslint . --config .eslintrc.generated.js --format json', { encoding: 'utf8' });
const eslintResults = JSON.parse(eslintOutput);
const totalErrors = eslintResults.reduce((sum, file) => sum + file.errorCount, 0);
const totalWarnings = eslintResults.reduce((sum, file) => sum + file.warningCount, 0);
return {
totalViolations: totalErrors + totalWarnings, // 总违规数
errorCount: totalErrors, // 错误数(阻断性)
warningCount: totalWarnings, // 警告数(建议性)
qualityScore: Math.max(0, 100 - totalViolations / 10).toFixed(1) // 简化质量分计算
};
}
// 3. AI测试指标(通过率、响应时间等)
async getAIMetrics() {
// 读取AI测试报告(从测试框架输出中提取)
const testReport = JSON.parse(fs.readFileSync('reports/ai-test-report.json', 'utf8'));
return {
acceptanceRate: (testReport.passed / testReport.total * 100).toFixed(2) + '%', // AI测试通过率
avgResponseTime: (testReport.totalTime / testReport.total).toFixed(2) + 'ms', // 平均响应时间
understandingScore: this.calculateUnderstandingScore(testReport) // 规则理解得分
};
}
// 4. 流水线指标(成功率、执行时间等)
async getPipelineMetrics() {
// 实际项目中可调用GitHub API获取流水线历史数据
const pipelineHistory = JSON.parse(fs.readFileSync('reports/pipeline-history.json', 'utf8'));
const successCount = pipelineHistory.filter(run => run.status === 'success').length;
return {
successRate: (successCount / pipelineHistory.length * 100).toFixed(2) + '%', // 流水线成功率
avgRunTime: (pipelineHistory.reduce((sum, run) => sum + run.duration, 0) / pipelineHistory.length).toFixed(0) + 's' // 平均执行时间
};
}
// 辅助方法:统计规则冲突数
countConflicts() {
const conflictReport = fs.readFileSync('reports/conflicts.md', 'utf8');
return (conflictReport.match(/## 冲突规则/g) || []).length;
}
// 辅助方法:获取规则最后更新时间
getLastRuleUpdateTime(ruleFiles) {
const lastUpdateTime = ruleFiles.reduce((latest, file) => {
const mtime = fs.statSync(file).mtime.getTime();
return mtime > latest ? mtime : latest;
}, 0);
return new Date(lastUpdateTime).toISOString();
}
// 辅助方法:计算AI规则理解得分
calculateUnderstandingScore(testReport) {
// 正向用例权重高于反向用例(理解正确比修复更重要)
const positiveScore = testReport.positivePassed / testReport.positiveTotal * 60;
const negativeScore = testReport.negativePassed / testReport.negativeTotal * 40;
return (positiveScore + negativeScore).toFixed(1);
}
}
4.2 Grafana看板配置:指标的"可视化仪表盘"
核心作用:把收集的指标实时展示在看板上,团队成员可直观看到规则体系运行状态,异常时及时告警。
css
{
"dashboard": {
"title": "规则体系质量仪表盘",
"refresh": "5m", // 每5分钟刷新一次数据
"panels": [
{
"title": "核心健康度",
"type": "stat",
"gridPos": { "w": 12, "h": 4 },
"targets": [
{ "expr": "rules_coverage_rate", "legendFormat": "规则覆盖率" },
{ "expr": "ai_acceptance_rate", "legendFormat": "AI理解率" },
{ "expr": "pipeline_success_rate", "legendFormat": "流水线成功率" }
],
"color": { "mode": "thresholds" },
"thresholds": { "values": [[90, "green"], [70, "orange"], [0, "red"]] }
},
{
"title": "代码违规趋势(周)",
"type": "graph",
"gridPos": { "w": 12, "h": 6 },
"targets": [
{ "expr": "code_total_violations", "legendFormat": "总违规数" },
{ "expr": "code_error_count", "legendFormat": "错误数" }
],
"xaxis": { "mode": "time" },
"yaxis": { "min": 0 }
},
{
"title": "AI测试性能",
"type": "graph",
"gridPos": { "w": 12, "h": 6 },
"targets": [
{ "expr": "ai_avg_response_time", "legendFormat": "平均响应时间(ms)" },
{ "expr": "ai_understanding_score", "legendFormat": "理解得分" }
]
}
],
"annotations": {
"list": [
{
"name": "规则更新",
"datasource": "metrics",
"expr": "rules_last_update_time",
"iconColor": "rgba(255, 96, 96, 1)"
}
]
},
"alert": {
"rules": [
{
"name": "规则覆盖率过低",
"expr": "rules_coverage_rate < 80",
"for": "5m",
"labels": { "severity": "warning" },
"annotations": { "summary": "规则覆盖率低于80%,请检查配置生成器" }
},
{
"name": "AI理解率异常",
"expr": "ai_acceptance_rate < 70",
"for": "5m",
"labels": { "severity": "critical" },
"annotations": { "summary": "AI测试通过率低于70%,请检查规则描述" }
}
]
}
}
}
验收标准
- 数据实时更新(看板数据与指标收集器的时间差≤10分钟)
- 异常自动告警(触发阈值时,通过企业微信/邮件发送告警信息)
- 历史趋势可追溯(支持查看近30天的指标变化曲线)
🚀 第五阶段:持续进化------规则自动优化(第7-8周)
目标:让规则体系具备"自我迭代"能力,自动发现新规则、优化旧规则,适应团队开发模式变化。
5.1 自动化规则发现:从代码中"学"规则
核心作用:分析代码库中的高频模式和共性问题,自动生成规则建议,减少人工制定规则的成本。
typescript
// scripts/rule-discovery.js
const fs = require('fs');
const glob = require('glob');
const { parse } = require('@babel/parser');
const traverse = require('@babel/traverse').default;
class RuleDiscovery {
// 主方法:发现潜在规则并生成建议
async discoverNewRules() {
// 1. 分析代码库,提取高频模式和共性问题
const codePatterns = await this.analyzeCodePatterns();
const commonIssues = await this.analyzeCommonIssues();
// 2. 结合行业标准,过滤无效建议
const industryStandards = await this.fetchIndustryStandards();
// 3. 生成规则建议(置信度≥80%才输出)
const ruleSuggestions = [
...this.generatePatternRules(codePatterns),
...this.generateIssueRules(commonIssues),
...this.generateStandardRules(industryStandards)
].filter(suggestion => suggestion.confidence >= 0.8);
// 写入建议文件(供团队评审)
fs.writeFileSync(
'reports/rule-suggestions.md',
this.formatSuggestions(ruleSuggestions)
);
return ruleSuggestions;
}
// 分析代码库中的高频模式(比如团队常用的组件命名规范)
async analyzeCodePatterns() {
const files = glob.sync('src/**/*.{js,ts,vue}');
const patternMap = new Map(); // key: 模式签名,value: 出现次数
files.forEach(file => {
const content = fs.readFileSync(file, 'utf8');
// 解析代码为AST(抽象语法树)
const ast = parse(content, {
sourceType: 'module',
plugins: ['typescript', 'jsx', 'vue']
});
// 遍历AST,提取组件定义模式
traverse(ast, {
VariableDeclaration(path) {
if (path.node.declarations[0]?.init?.type === 'ArrowFunctionExpression') {
const idName = path.node.declarations[0].id.name;
// 匹配PascalCase命名的组件(团队高频模式)
if (/^[A-Z][a-zA-Z0-9]+$/.test(idName)) {
const patternKey = `ComponentNaming:PascalCase:${idName}`;
patternMap.set(patternKey, (patternMap.get(patternKey) || 0) + 1);
}
}
}
});
});
// 筛选出现次数≥5的模式(排除偶然情况)
return Array.from(patternMap.entries())
.filter(([, count]) => count >= 5)
.map(([key, count]) => ({
type: key.split(':')[0],
pattern: key.split(':')[1],
example: key.split(':')[2],
frequency: count
}));
}
// 分析代码中的共性问题(比如高频ESLint违规)
async analyzeCommonIssues() {
const eslintReport = JSON.parse(fs.readFileSync('reports/eslint-report.json', 'utf8'));
const issueMap = new Map();
eslintReport.forEach(file => {
file.messages.forEach(message => {
const ruleId = message.ruleId;
issueMap.set(ruleId, (issueMap.get(ruleId) || 0) + 1);
});
});
// 筛选出现次数≥10的问题(视为共性问题)
return Array.from(issueMap.entries())
.filter(([, count]) => count >= 10)
.map(([ruleId, count]) => ({ ruleId, count }));
}
// 生成模式类规则建议(基于团队高频实践)
generatePatternRules(patterns) {
return patterns.map(pattern => ({
title: `[自动发现] ${pattern.type} 规范:${pattern.pattern}`,
description: `团队代码中该模式出现${pattern.frequency}次,建议固化为规则`,
example: `符合规则:const ${pattern.example} = () => {}`,
confidence: Math.min(1, pattern.frequency / 20) // 出现次数越多,置信度越高
}));
}
// 生成问题类规则建议(基于高频违规)
generateIssueRules(issues) {
return issues.map(issue => ({
title: `[自动发现] 重点规避:${issue.ruleId}`,
description: `该问题在代码中出现${issue.count}次,建议强化检查力度`,
solution: `参考ESLint规则文档:https://eslint.org/docs/rules/${issue.ruleId}`,
confidence: Math.min(1, issue.count / 30)
}));
}
// 结合行业标准生成建议(比如TS最新特性)
async fetchIndustryStandards() {
// 实际项目中可调用npm API或技术社区接口获取最新标准
return [
{ rule: 'TypeScript 5.0+ 支持的装饰器语法', relevance: 0.9 },
{ rule: 'ES Module 优先于 CommonJS', relevance: 0.85 }
];
}
// 格式化建议为Markdown文档
formatSuggestions(suggestions) {
let markdown = '# 规则自动发现建议\n\n';
suggestions.forEach((suggestion, index) => {
markdown += `## 建议${index + 1}:${suggestion.title}\n`;
markdown += `**置信度**:${(suggestion.confidence * 100).toFixed(0)}%\n`;
markdown += `**描述**:${suggestion.description}\n`;
if (suggestion.example) markdown += `**示例**:```javascript\n${suggestion.example}\n```\n`;
if (suggestion.solution) markdown += `**解决方案**:${suggestion.solution}\n`;
markdown += '\n---\n';
});
return markdown;
}
}
5.2 RFC自动化流程:规则迭代的"高效通道"
核心作用:把规则变更流程标准化、自动化,从提出建议到正式生效全流程可追溯,减少沟通成本。
javascript
// scripts/rfc-automation.js
const { Octokit } = require('@octokit/rest');
const RuleParser = require('./rule-parser');
// 初始化GitHub客户端(需配置个人访问令牌)
const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN });
class RFCAutomation {
constructor() {
this.owner = 'windsurf-team'; // 仓库所有者
this.repo = 'rule-system'; // 规则仓库
this.parser = new RuleParser();
}
// 处理RFC议题(从GitHub Issue中提取规则建议)
async processRFCIssue(issueNumber) {
// 1. 获取议题详情
const { data: issueData } = await octokit.issues.get({
owner: this.owner,
repo: this.repo,
issue_number: issueNumber
});
// 2. 解析RFC内容(需符合指定模板)
const rfc = this.parseRFCContent(issueData.body);
if (!rfc) {
await this.addIssueComment(issueNumber, '❌ RFC格式错误,请使用模板填写:https://github.com/windsurf-team/rule-system/blob/main/.github/ISSUE_TEMPLATE/rfc.md');
return;
}
// 3. 自动验证RFC可行性
const validationResult = await this.validateRFC(rfc);
if (!validationResult.valid) {
const errorMsg = `❌ RFC验证失败:\n${validationResult.errors.map(e => `- ${e}`).join('\n')}`;
await this.addIssueComment(issueNumber, errorMsg);
return;
}
// 4. 自动分配审核者(根据规则类型匹配对应领域专家)
const reviewers = this.assignReviewers(rfc.type);
await this.assignIssueReviewers(issueNumber, reviewers);
// 5. 创建规则跟踪项目(关联PR和测试任务)
await this.createTrackingProject(rfc, issueNumber);
// 6. 回复议题告知进度
await this.addIssueComment(issueNumber,
`✅ RFC验证通过,已自动分配审核者:@${reviewers.join(', @')}\n` +
`📌 规则跟踪项目:https://github.com/windsurf-team/rule-system/projects/${rfc.title.replace(/\s+/g, '-').toLowerCase()}`
);
}
// 解析RFC内容(提取标题、类型、描述等核心信息)
parseRFCContent(issueBody) {
const titleMatch = issueBody.match(/### 规则标题\n([\s\S]*?)\n###/);
const typeMatch = issueBody.match(/### 规则类型\n([\s\S]*?)\n###/);
const descriptionMatch = issueBody.match(/### 规则描述\n([\s\S]*?)\n###/);
const exampleMatch = issueBody.match(/### 示例代码\n([\s\S]*?)\n###/);
if (!titleMatch || !typeMatch || !descriptionMatch) return null;
return {
title: titleMatch[1].trim(),
type: typeMatch[1].trim(),
description: descriptionMatch[1].trim(),
example: exampleMatch ? exampleMatch[1].trim() : '',
author: issueBody.match(/### 提出者\n([\s\S]*?)\n###/)[1].trim()
};
}
// 验证RFC可行性(检查是否与现有规则冲突、是否有可执行的配置)
async validateRFC(rfc) {
const errors = [];
// 检查是否与现有规则冲突
const existingRules = this.parser.getAllRuleFiles().map(file =>
this.parser.parseRuleFile(file).metadata.title
);
if (existingRules.includes(rfc.title)) {
errors.push(`已存在同名规则:${rfc.title}`);
}
// 检查示例代码是否可解析
if (rfc.example) {
try {
this.parser.extractExamples(`\n${rfc.example}\n`);
} catch (e) {
errors.push(`示例代码格式错误:${e.message}`);
}
}
return { valid: errors.length === 0, errors };
}
// 根据规则类型分配审核者(前端/后端/全栈分别对应不同专家)
assignReviewers(ruleType) {
const reviewerMap = {
'前端规则': ['fe-expert-1', 'fe-expert-2'],
'后端规则': ['be-expert-1', 'be-expert-2'],
'通用规则': ['fullstack-expert-1', 'fullstack-expert-2']
};
return reviewerMap[ruleType] || ['fullstack-expert-1'];
}
// 辅助方法:添加议题评论
async addIssueComment(issueNumber, comment) {
await octokit.issues.createComment({
owner: this.owner,
repo: this.repo,
issue_number: issueNumber,
body: comment
});
}
// 辅助方法:分配议题审核者
async assignIssueReviewers(issueNumber, reviewers) {
await octokit.issues.addAssignees({
owner: this.owner,
repo: this.repo,
issue_number: issueNumber,
assignees: reviewers
});
}
// 辅助方法:创建跟踪项目
async createTrackingProject(rfc, issueNumber) {
const projectName = `RFC: ${rfc.title}`;
const { data: project } = await octokit.projects.createForRepo({
owner: this.owner,
repo: this.repo,
name: projectName,
body: `规则RFC跟踪项目(关联议题:#${issueNumber})`
});
// 添加项目任务
const tasks = [
'📝 编写规则Markdown文档',
'🔧 实现规则配置片段',
'🧪 编写测试用例',
'✅ 审核通过并合并',
'🚀 发布到生产环境'
];
for (const task of tasks) {
await octokit.projects.createCard({
column_id: project.columns[0].id,
note: task
});
}
return project;
}
}
验收标准
- 规则发现有效性:每月自动生成2-3个符合团队实际的规则建议,采纳率≥60%
- RFC响应效率:新RFC议题创建后,24小时内完成自动验证和审核者分配
- 流程完整性:从RFC提出到规则生效,全流程有跟踪记录,无人工遗漏环节
📈 成功指标与最终交付物
一、3个月后关键成果指标
| 指标类别 | 具体指标 | 当前基线 | 目标值 | 测量方式 |
|---|---|---|---|---|
| 开发效率 | Code Review平均时间 | 2.5小时/次 | 1.5小时/次 | GitLab Merge Request历史数据统计 |