feat: 集成code-review skill到项目
- 项目级 skill: .claude/skills/code-review/ (398行SKILL.md + 参考文件) - 自动触发: AI修改.py/.cbl/.cpy/.lark后自动review - CLAUDE.md: 定义触发规则、review流程、严重级别 - .code-review.yaml: tier=standard, 高风险模块配置 效果: clone即用, 每次代码变更后自动审查, 防止低质量代码入库 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,211 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Code Review Report</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg: #1a1b1e;
|
||||
--surface: #25262b;
|
||||
--border: #373a40;
|
||||
--text: #c1c2c5;
|
||||
--text-muted: #909296;
|
||||
--accent: #5c7cfa;
|
||||
--success: #51cf66;
|
||||
--warning: #fcc419;
|
||||
--danger: #ff6b6b;
|
||||
--info: #339af0;
|
||||
}
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
background: var(--bg);
|
||||
color: var(--text);
|
||||
padding: 32px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.container { max-width: 960px; margin: 0 auto; }
|
||||
.header {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 12px;
|
||||
padding: 24px 32px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.header h1 {
|
||||
font-size: 22px;
|
||||
color: #fff;
|
||||
margin-bottom: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
.meta-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: 8px;
|
||||
font-size: 14px;
|
||||
}
|
||||
.meta-item { display: flex; gap: 8px; }
|
||||
.meta-label { color: var(--text-muted); min-width: 80px; }
|
||||
.meta-value { color: #fff; }
|
||||
.verdict { font-weight: 700; font-size: 18px; }
|
||||
.verdict.pass { color: var(--success); }
|
||||
.verdict.fail { color: var(--danger); }
|
||||
.section {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 12px;
|
||||
padding: 24px 32px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.section h2 {
|
||||
font-size: 16px;
|
||||
color: #fff;
|
||||
margin-bottom: 16px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
.layer-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 8px; }
|
||||
.layer-item { display: flex; justify-content: space-between; padding: 6px 0; font-size: 14px; }
|
||||
.layer-item .status { font-weight: 600; }
|
||||
.status-clean { color: var(--success); }
|
||||
.status-issues { color: var(--warning); }
|
||||
.status-na { color: var(--text-muted); }
|
||||
table { width: 100%; border-collapse: collapse; font-size: 14px; }
|
||||
th, td { text-align: left; padding: 8px 12px; border-bottom: 1px solid var(--border); }
|
||||
th { color: var(--text-muted); font-weight: 500; text-transform: uppercase; font-size: 12px; letter-spacing: 0.5px; }
|
||||
td { color: var(--text); }
|
||||
.metric-warn { color: var(--warning); font-weight: 600; }
|
||||
.metric-good { color: var(--success); }
|
||||
.summary-row { display: flex; gap: 16px; flex-wrap: wrap; }
|
||||
.summary-card {
|
||||
flex: 1; min-width: 140px; padding: 16px; border-radius: 8px; text-align: center;
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
.summary-card .num { font-size: 28px; font-weight: 700; }
|
||||
.summary-card .label { font-size: 12px; color: var(--text-muted); margin-top: 4px; }
|
||||
.card-ready .num { color: var(--success); }
|
||||
.card-needsfix .num { color: var(--warning); }
|
||||
.card-unusable .num { color: var(--danger); }
|
||||
.severity-row { display: flex; gap: 16px; flex-wrap: wrap; margin-bottom: 16px; }
|
||||
.severity-badge {
|
||||
display: inline-flex; align-items: center; gap: 6px;
|
||||
padding: 4px 12px; border-radius: 20px; font-size: 13px; font-weight: 600;
|
||||
}
|
||||
.sev-blocker { background: rgba(255,107,107,0.15); color: var(--danger); }
|
||||
.sev-major { background: rgba(252,196,25,0.15); color: var(--warning); }
|
||||
.sev-minor { background: rgba(52,154,240,0.15); color: var(--info); }
|
||||
.issue {
|
||||
padding: 12px 16px; margin-bottom: 8px; border-radius: 8px;
|
||||
border-left: 4px solid; font-size: 14px;
|
||||
}
|
||||
.issue-blocker { background: rgba(255,107,107,0.08); border-left-color: var(--danger); }
|
||||
.issue-major { background: rgba(252,196,25,0.08); border-left-color: var(--warning); }
|
||||
.issue-minor { background: rgba(52,154,240,0.08); border-left-color: var(--info); }
|
||||
.issue .tag {
|
||||
display: inline-block; padding: 1px 8px; border-radius: 4px;
|
||||
font-size: 11px; font-weight: 600; margin-right: 8px;
|
||||
}
|
||||
.issue .tag-blocker { background: rgba(255,107,107,0.2); color: var(--danger); }
|
||||
.issue .tag-major { background: rgba(252,196,25,0.2); color: var(--warning); }
|
||||
.issue .tag-minor { background: rgba(52,154,240,0.2); color: var(--info); }
|
||||
.issue .category { color: var(--accent); font-weight: 500; }
|
||||
.issue .location { color: var(--text-muted); font-size: 12px; }
|
||||
.issue .fix { margin-top: 4px; padding: 6px 10px; background: rgba(92,124,250,0.1); border-radius: 4px; font-size: 13px; color: #dde; }
|
||||
.manual-item { padding: 8px 0; font-size: 14px; }
|
||||
.manual-item::before { content: '→ '; color: var(--warning); }
|
||||
.accum-item { padding: 6px 0; font-size: 14px; }
|
||||
.accum-item::before { content: '• '; color: var(--accent); }
|
||||
.footer { text-align: center; color: var(--text-muted); font-size: 12px; margin-top: 32px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
|
||||
<!-- Header -->
|
||||
<div class="header">
|
||||
<h1>🔍 Backend Code Review Report</h1>
|
||||
<div class="meta-grid">
|
||||
<div class="meta-item"><span class="meta-label">Scope</span><span class="meta-value">{{SCOPE}}</span></div>
|
||||
<div class="meta-item"><span class="meta-label">Tier</span><span class="meta-value">{{TIER}}</span></div>
|
||||
<div class="meta-item"><span class="meta-label">Time</span><span class="meta-value">{{TIMESTAMP}}</span></div>
|
||||
<div class="meta-item"><span class="meta-label">Files</span><span class="meta-value">{{FILES}}</span></div>
|
||||
<div class="meta-item"><span class="meta-label">Baseline</span><span class="meta-value">{{BASELINE}}</span></div>
|
||||
<div class="meta-item">
|
||||
<span class="meta-label">Verdict</span>
|
||||
<span class="meta-value verdict {{VERDICT_CLASS}}">{{VERDICT}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Layer 1 -->
|
||||
<div class="section">
|
||||
<h2>Layer 1 · Chain Decomposition</h2>
|
||||
<div class="layer-grid">
|
||||
<div class="layer-item"><span>Interface</span><span class="status {{L1_INTERFACE_CLASS}}">{{L1_INTERFACE}}</span></div>
|
||||
<div class="layer-item"><span>Business</span><span class="status {{L1_BUSINESS_CLASS}}">{{L1_BUSINESS}}</span></div>
|
||||
<div class="layer-item"><span>Data</span><span class="status {{L1_DATA_CLASS}}">{{L1_DATA}}</span></div>
|
||||
<div class="layer-item"><span>Utility</span><span class="status {{L1_UTILITY_CLASS}}">{{L1_UTILITY}}</span></div>
|
||||
<div class="layer-item"><span>Error Handling</span><span class="status {{L1_ERROR_CLASS}}">{{L1_ERROR}}</span></div>
|
||||
<div class="layer-item"><span>Security</span><span class="status {{L1_SECURITY_CLASS}}">{{L1_SECURITY}}</span></div>
|
||||
<div class="layer-item"><span>Performance</span><span class="status {{L1_PERFORMANCE_CLASS}}">{{L1_PERFORMANCE}}</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Layer 2 -->
|
||||
<div class="section">
|
||||
<h2>Layer 2 · Quantitative Metrics</h2>
|
||||
<table>
|
||||
<thead><tr><th>Metric</th><th>Value</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>Requirement Coverage</td><td class="{{REQ_COV_CLASS}}">{{REQ_COVERAGE}}</td></tr>
|
||||
<tr><td>Logic Alignment</td><td>{{LOGIC_ALIGNMENT}}</td></tr>
|
||||
<tr><td>Exception Branch Coverage</td><td class="{{EXC_COV_CLASS}}">{{EXC_COVERAGE}}</td></tr>
|
||||
<tr><td>SQL Performance Risk</td><td class="{{SQL_RISK_CLASS}}">{{SQL_RISK}}</td></tr>
|
||||
<tr><td>Code Redundancy Rate</td><td>{{REDUNDANCY_RATE}}</td></tr>
|
||||
<tr><td>Vulnerability Risk Rate</td><td class="{{VULN_RISK_CLASS}}">{{VULN_RISK}}</td></tr>
|
||||
<tr><td>High-Risk Scenario Coverage</td><td class="{{HRISK_CLASS}}">{{HRISK_COVERAGE}}</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Classification -->
|
||||
<div class="section">
|
||||
<h2>Classification</h2>
|
||||
<div class="summary-row">
|
||||
<div class="summary-card card-ready"><div class="num">{{READY_COUNT}}</div><div class="label">Ready</div></div>
|
||||
<div class="summary-card card-needsfix"><div class="num">{{NEEDS_FIX_COUNT}}</div><div class="label">Needs Fix</div></div>
|
||||
<div class="summary-card card-unusable"><div class="num">{{UNUSABLE_COUNT}}</div><div class="label">Unusable</div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Severity Summary -->
|
||||
<div class="section">
|
||||
<h2>Severity Summary</h2>
|
||||
<div class="severity-row">
|
||||
<span class="severity-badge sev-blocker">🔴 Blocker: {{BLOCKER_COUNT}}</span>
|
||||
<span class="severity-badge sev-major">🟡 Major: {{MAJOR_COUNT}}</span>
|
||||
<span class="severity-badge sev-minor">🔵 Minor: {{MINOR_COUNT}}</span>
|
||||
</div>
|
||||
|
||||
{{ISSUES_LIST}}
|
||||
</div>
|
||||
|
||||
<!-- Manual Review Required -->
|
||||
{{MANUAL_REVIEW_SECTION}}
|
||||
|
||||
<!-- Knowledge Accumulation -->
|
||||
{{ACCUMULATION_SECTION}}
|
||||
|
||||
<!-- Footer -->
|
||||
<div class="footer">
|
||||
Generated by code-review skill · {{TIMESTAMP}}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user