docs: 删除 PLAN.md,更新 CLAUDE.md 中的引用

PLAN.md 的内容已被 CLAUDE.md、README.md 和代码覆盖:
- API 路由、功能描述、Docker 配置 → README.md
- 架构、关键模式、目录结构 → CLAUDE.md
- SQL Schema、LLM Prompts、SSE 格式 → 代码本身

更新 CLAUDE.md Development Notes,将 PLAN.md 引用改为指向实际代码文件。
This commit is contained in:
2026-06-20 17:34:57 +08:00
parent e571a33dd2
commit 87bb23e19e
2 changed files with 2 additions and 799 deletions
+2 -2
View File
@@ -69,6 +69,6 @@ static/ → CSS (Tailwind output), JS (graph, diff-viewer, sse), vendor libs
## Development Notes
- Refer to `PLAN.md` for full specification including API routes, SSE event formats, SQL schema, and prompt templates.
- No authentication — do not expose to public internet.
- All LLM prompts are in PLAN.md §8; model/endpoint/key are configurable via the settings page.
- LLM prompts are in `services/generate.go` and `services/review.go`; model/endpoint/key are configurable via the settings page.
- SSE event formats are defined in `handlers/generate.go` and `handlers/review.go` (server) and consumed by `static/js/sse.js` (client).
-797
View File
@@ -1,797 +0,0 @@
# PR-Helper 项目规划
## 1. 项目概述
**PR-Helper** 是一个 Web 服务,帮助开发者:
- 根据 Git 仓库的 commit 历史和 diff,**自动生成 PR 描述**
- 使用 AI 对代码变更进行**自动代码审查**
技术栈:Go + Gin + SQLite + HTMX + D3.js + Tailwind CSS
部署方式:Docker
---
## 2. 技术架构
```
┌─────────────────────────────────────────────────┐
│ Browser (前端) │
│ Go 模板 + HTMX + D3.js + Tailwind CSS │
└──────────────────────┬──────────────────────────┘
│ HTTP / SSE
┌──────────────────────▼──────────────────────────┐
│ Gin HTTP Server │
│ ┌──────────┐ ┌──────────┐ ┌───────────────┐ │
│ │ 仓库管理 │ │ PR 生成 │ │ AI Review │ │
│ └────┬─────┘ └────┬─────┘ └──────┬────────┘ │
│ │ │ │ │
│ ┌────▼──────────────▼───────────────▼────────┐ │
│ │ Git 操作层 (go-git) │ │
│ └────────────────────────────────────────────┘ │
│ ┌────────────────────────────────────────────┐ │
│ │ LLM 调用层 (OpenAI 兼容) │ │
│ └────────────────────────────────────────────┘ │
│ ┌────────────────────────────────────────────┐ │
│ │ PDF 生成层 (chromedp) │ │
│ └────────────────────────────────────────────┘ │
│ ┌────────────────────────────────────────────┐ │
│ │ SQLite 数据库 │ │
│ └────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────┘
```
### 2.1 后端
| 组件 | 技术选型 | 说明 |
|------|---------|------|
| Web 框架 | **Gin** | Go 生态最成熟的 Web 框架 |
| Git 操作 | **go-git** | 纯 Go 实现的 Git 库,无需系统 git |
| 数据库 | **SQLite** (go-sqlite3) | 轻量级,嵌入式,适合单实例部署 |
| 模板引擎 | **html/template** | Go 标准库 |
| 后台任务 | **goroutine + channel** | 简单直接,适合单实例场景 |
### 2.2 前端
| 组件 | 技术选型 | 说明 |
|------|---------|------|
| 交互增强 | **HTMX** | 局部更新,无需 SPA 框架 |
| Git 图可视化 | **D3.js** | 完整的交互式 Git Graph |
| CSS 框架 | **Tailwind CSS** | 原子化 CSS,灵活高效 |
| 流式输出 | **SSE (Server-Sent Events)** | LLM 生成结果的打字机效果 |
### 2.3 LLM 集成
- 使用 **OpenAI 兼容 API** 格式(支持 OpenAI、Deepseek、本地 Ollama 等)
- 通过 Web 设置页面配置 API Key、Endpoint、Model
- 使用 SSE 流式输出生成结果
- 大 diff 处理策略:**分文件处理 + Top-N 结合**(按文件拆分送 LLM,优先分析变更最大的 N 个文件,最后汇总)
---
## 3. 功能模块
### 3.1 PR 描述生成
**用户流程:**
1. 用户在首页输入 Git 仓库 URL
2. 服务端 clone 仓库(带进度反馈)
3. 前端展示完整的 **D3.js Git Graph** 可视化
- 展示所有分支、标签、commit 历史
- 节点可交互(hover 显示详情)
4. 用户在 Git Graph 上选择两个点(base 和 head)
5. 服务端计算 diff,聚合 commit messages
6. LLM 生成结构化 PR 描述:
- **标题**(简洁概括变更)
- **变更类型**(feat/fix/refactor/docs/chore 等)
- **变更摘要**(概述主要改动)
- **详细说明**(按模块/文件分组描述)
- **影响范围**(受影响的功能/模块)
7. 前端结构化展示,支持**一键复制 Markdown**
**数据流:**
```
Git URL → Clone → Git Graph 选择 → Diff + Commits → LLM → 结构化 PR 描述 → Markdown 复制
```
### 3.2 AI 代码审查
**用户流程:**
1. 复用已 clone 的仓库(或新输入 URL)
2. 在 Git Graph 上选择要审查的范围(base..head)
3. **配置审查参数**(前端表单):
- Top-N 文件数:输入框,默认读取全局设置值(`20`),用户可临时修改
- 例如设为 `10` 则只分析变更最大的 10 个文件
- 设为 `0` 或留空表示分析全部文件(不截断)
- 显示当前 diff 的总文件数,提示用户是否需要调整 Top-N
4. 服务端提取 diff,按文件拆分
5. LLM 逐文件分析,流式输出审查结果
6. 输出:
- **整体评估**:变更质量评分、总体评价
- **逐文件建议**:每个文件的具体问题和改进建议
- 严重程度(🔴 严重 / 🟡 建议 / 🟢 提示)
- 问题描述
- 建议的修改方案
7. 用户可在 AI 审查结果基础上**追加备注**(不修改 AI 原始输出)
8. 支持**导出为 PDF 文档**
**大 Diff 处理策略:**
- 按文件拆分 diff
- 按变更行数排序,优先处理 Top-N 个最大变更文件
- Top-N 优先级:**用户前端输入 > 全局设置默认值(20)**
- 每个文件独立送 LLM 分析
- 最后用一个汇总 prompt 整合所有文件的审查结果
- SSE 流式输出,逐文件展示进度
### 3.2.1 审查结果在线编辑
**编辑规则:**
- AI 生成的审查结果为**只读**,不可修改
- 用户可在以下位置追加自己的备注:
- 整体评估下方:追加总体备注
- 每个文件建议下方:追加文件级备注
- 每条具体建议下方:追加针对该建议的备注
- 备注支持 Markdown 格式
- 备注实时保存到数据库
**数据模型扩展:**
```sql
-- 用户备注表
CREATE TABLE review_notes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
analysis_id INTEGER REFERENCES analyses(id),
scope TEXT NOT NULL, -- 'overall' | 'file' | 'suggestion'
scope_key TEXT NOT NULL, -- 整体为空,文件名为 key,建议 ID 为 key
content TEXT NOT NULL, -- 用户备注内容(Markdown)
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
```
### 3.2.2 PDF 导出
**PDF 内容(完整报告):**
```
┌─────────────────────────────────────────┐
│ PR-Helper 审查报告 │
├─────────────────────────────────────────┤
│ 元信息 │
│ · 仓库: https://github.com/xxx/xxx │
│ · 分支: main → feature/auth │
│ · 审查时间: 2026-06-18 22:30 │
│ · 变更文件数: 15 │
│ · 变更行数: +320 / -85 │
├─────────────────────────────────────────┤
│ 整体评估 │
│ · 评分: 7/10 │
│ · AI 评价: 代码结构清晰,但存在... │
│ · 用户备注: [追加的备注内容] │
├─────────────────────────────────────────┤
│ 逐文件审查 │
│ │
│ 📄 auth/middleware.go │
│ 🟡 建议: JWT 密钥硬编码在代码中... │
│ 💬 用户备注: [追加的备注内容] │
│ │
│ 📄 auth/handler.go │
│ 🔴 严重: SQL 注入风险... │
│ 💬 用户备注: [追加的备注内容] │
│ │
│ ... │
├─────────────────────────────────────────┤
│ 代码变更 (Diff) │
│ │
│ --- a/auth/middleware.go │
│ +++ b/auth/middleware.go │
│ @@ -10,3 +10,5 @@ │
│ + func NewAuth() {...} │
│ │
│ ... │
└─────────────────────────────────────────┘
```
**技术实现:**
- 使用 **chromedp**(Go 的 headless Chrome 库)将 HTML 转为 PDF
- 服务端渲染一个专用的报告 HTML 模板(带打印样式)
- chromedp 将该 HTML 页面转为 PDF
- Docker 镜像中安装 Chromium
- PDF 生成完成后返回下载链接
**PDF 样式要求:**
- 使用 Tailwind CSS 打印友好的样式
- 代码块使用等宽字体,语法高亮
- 严重程度使用颜色区分(红/黄/绿)
- 分页合理,避免代码块被截断
- 页眉页脚包含报告标题和页码
### 3.3 Git Graph 可视化
**核心功能:**
- 使用 D3.js 绘制完整的 Git 提交图
- 节点表示 commit,边表示父子关系
- 分支和标签以彩色标签显示
- 支持交互:
- 点击节点查看 commit 详情(作者、日期、message)
- 选择两个节点作为 base/head
- 缩放和拖拽浏览大型仓库
- 分支高亮
### 3.4 设置管理页面
**配置项:**
| 配置 | 说明 | 默认值 | 存储方式 |
|------|------|--------|---------|
| API Endpoint | OpenAI 兼容 API 地址 | `https://api.openai.com/v1` | SQLite |
| API Key | API 认证密钥 | (空,必填) | SQLite |
| Model Name | 使用的模型名称 | `gpt-4o` | SQLite |
| Top-N 文件数 | 大 diff 时优先分析的最大文件数 | `20` | SQLite |
| 仓库缓存 | 已 clone 的仓库列表、大小、最后使用时间 | - | SQLite |
| 缓存过期 | 自动清理策略(如 7 天未用自动清理) | `7` 天 | SQLite |
### 3.5 Diff 查看器组件
**参考 GitHub PR Diff 设计**,提供完整的代码变更查看体验。
**整体布局:**
```
┌──────────────────────────────────────────────────────────┐
│ ┌─────────────┐ ┌────────────────────────────────────┐ │
│ │ 文件树侧栏 │ │ Diff 主区域 │ │
│ │ │ │ │ │
│ │ 📁 src/ │ │ ┌─ auth/middleware.go ────────┐ │ │
│ │ 📄 main.go │ │ │ 15 additions, 3 deletions │ │ │
│ │ 📄 auth/ │ │ ├────────────────────────────┤ │ │
│ │ 📄 mw.go │ │ │ Split View (左右对比) │ │ │
│ │ 📄 hd.go │ │ │ │ │ │
│ │ 📁 models/ │ │ │ 旧代码 (红) │ 新代码 (绿) │ │ │
│ │ 📄 user.go │ │ │ │ │ │ │
│ │ │ │ │ ... │ ... │ │ │
│ │─────────────│ │ │ │ │ │ │
│ │ 变更统计 │ │ ├─ AI Review 建议 (行内) ────┤ │ │
│ │ +320 / -85 │ │ │ 🟡 建议: JWT 密钥硬编码... │ │ │
│ │ 15 files │ │ │ 💬 [追加备注...] │ │ │
│ └─────────────┘ │ └────────────────────────────┘ │ │
│ │ │ │
│ │ ┌─ auth/handler.go ───────────┐ │ │
│ │ │ ... │ │ │
│ │ └────────────────────────────┘ │ │
│ └────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────┘
```
**文件树侧边栏:**
- 树形结构展示变更文件,按目录分组
- 每个文件显示增删行数(`+15 -3` 绿/红标签)
- 点击文件跳转到对应的 Diff 区域(平滑滚动)
- 顶部显示变更统计(总文件数、总增删行数)
- 文件树可折叠/展开目录
- 当前滚动到的文件在侧边栏高亮
**Diff 主区域(diff2html Split 视图):**
- 使用 **diff2html** 库渲染
- **Split 视图**(左右对比)为默认,支持切换到 Unified 视图
- 每个文件一个卡片,包含:
- 文件头:文件路径、变更类型(新增/修改/删除/重命名)、增删行数
- 代码区域:左右两栏对比
- **语法高亮**:diff2html 内置 highlight.js 支持
- **上下文行**:默认显示变更行前后各 3 行,可点击展开更多
- 文件头可折叠整个文件的 Diff
**AI Review 行内显示:**
- 在 AI Review 模式下,审查建议直接嵌入到对应的代码行旁边
- 类似 GitHub 的 inline comment 设计:
- 在相关代码行下方插入一个建议卡片
- 卡片包含:严重程度图标 + 建议内容
- 卡片下方有备注输入框,用户可追加备注
- 严重程度样式:
- 🔴 `critical`:红色左边框 + 浅红背景
- 🟡 `warning`:黄色左边框 + 浅黄背景
- 🟢 `info`:绿色左边框 + 浅绿背景
**交互功能:**
- 文件树点击 → 平滑滚动到对应文件
- 滚动 Diff 区域 → 侧边栏高亮当前文件
- 文件头点击 → 折叠/展开该文件
- 上下文行「展开」按钮 → 加载更多上下文
- Split/Unified 视图切换按钮
- 行号点击 → 高亮该行(用于引用讨论)
---
## 4. 数据模型
### 4.1 SQLite 表结构
```sql
-- 系统配置(KV 存储)
CREATE TABLE settings (
key TEXT PRIMARY KEY,
value TEXT NOT NULL
);
-- 仓库缓存记录
CREATE TABLE repositories (
id INTEGER PRIMARY KEY AUTOINCREMENT,
url TEXT NOT NULL UNIQUE,
local_path TEXT NOT NULL,
size_bytes INTEGER DEFAULT 0,
cloned_at DATETIME DEFAULT CURRENT_TIMESTAMP,
last_used DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- 分析历史(可选,记录生成/审查历史)
CREATE TABLE analyses (
id INTEGER PRIMARY KEY AUTOINCREMENT,
repo_id INTEGER REFERENCES repositories(id),
type TEXT NOT NULL, -- 'pr_description' | 'code_review'
base_ref TEXT NOT NULL,
head_ref TEXT NOT NULL,
result TEXT, -- LLM 输出结果(Markdown)
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
```
### 4.2 配置默认值
| Key | 默认值 | 说明 |
|-----|--------|------|
| `llm.endpoint` | `https://api.openai.com/v1` | API 地址 |
| `llm.api_key` | (空) | 必须配置 |
| `llm.model` | `gpt-4o` | 默认模型 |
| `cache.max_age_days` | `7` | 缓存过期天数 |
| `cache.max_size_mb` | `5000` | 最大缓存大小 (MB) |
| `review.top_n` | `20` | 大 diff 时优先分析的文件数 |
---
## 5. API 设计
### 5.1 页面路由
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/` | 首页(输入 Git URL) |
| GET | `/repo/:id` | 仓库详情页(Git Graph + 操作) |
| GET | `/repo/:id/generate` | PR 描述生成页 |
| GET | `/repo/:id/review` | AI Review 页 |
| GET | `/settings` | 设置页面 |
### 5.2 API 路由
| 方法 | 路径 | 说明 |
|------|------|------|
| POST | `/api/repos` | clone 仓库(返回仓库 ID + 进度 SSE) |
| GET | `/api/repos/:id/graph` | 获取 Git Graph 数据(JSON) |
| GET | `/api/repos/:id/diff` | 获取两个 ref 之间的 diff(返回文件树 + 各文件 unified diff,供 diff2html 渲染) |
| POST | `/api/repos/:id/generate` | 生成 PR 描述(SSE 流式) |
| POST | `/api/repos/:id/review` | AI Review(SSE 流式),请求体含 `base`、`head`、`top_n`(可选,默认读全局设置) |
| POST | `/api/repos/:id/review/notes` | 保存审查备注 |
| GET | `/api/repos/:id/review/notes` | 获取审查备注 |
| POST | `/api/repos/:id/review/pdf` | 生成并下载 PDF 报告 |
| GET | `/api/settings` | 获取设置 |
| PUT | `/api/settings` | 更新设置 |
| GET | `/api/repos` | 获取缓存仓库列表 |
| DELETE | `/api/repos/:id` | 删除仓库缓存 |
| POST | `/api/repos/:id/cleanup` | 手动触发缓存清理 |
### 5.3 SSE 事件格式
**Clone 进度:**
```
event: progress
data: {"step": "cloning", "progress": 45, "message": "接收对象中..."}
```
**PR 描述生成(流式):**
```
event: title
data: {"content": "feat: 添加用户认证模块"}
event: type
data: {"content": "feat"}
event: summary
data: {"content": "本次变更添加了完整的用户认证..."}
event: detail
data: {"content": "### 认证模块\n- 新增 JWT 认证中间件\n..."}
event: done
data: {"content": ""}
```
**AI Review(流式):**
```
event: file_start
data: {"file": "auth/middleware.go"}
event: suggestion
data: {
"file": "auth/middleware.go",
"line": 15, // 关联的新代码行号(用于行内定位)
"side": "right", // "left"=旧代码侧, "right"=新代码侧
"severity": "warning", // critical / warning / info
"content": "JWT 密钥硬编码在代码中,建议使用环境变量"
}
event: file_end
data: {"file": "auth/middleware.go"}
event: summary
data: {"content": "整体评估:代码结构清晰,但存在安全隐患..."}
event: done
data: {"content": ""}
```
> **行内定位说明**:`line` + `side` 用于将建议定位到 Diff 视图中的具体代码行。
> 前端 diff-viewer.js 根据这两个字段将建议卡片插入到对应行的下方。
---
## 6. 目录结构
```
PR-Helper/
├── main.go # 入口,初始化配置、数据库、路由
├── go.mod
├── go.sum
├── Dockerfile
├── docker-compose.yml
├── PLAN.md
├── CLAUDE.md
│
├── config/
│ └── config.go # 配置加载和管理
│
├── models/
│ ├── repository.go # 仓库数据模型
│ ├── settings.go # 设置数据模型
│ └── analysis.go # 分析历史模型
│
├── database/
│ └── db.go # SQLite 初始化和迁移
│
├── handlers/
│ ├── pages.go # 页面路由 handler
│ ├── repos.go # 仓库 API handler
│ ├── generate.go # PR 生成 handler(含 SSE)
│ ├── review.go # AI Review handler(含 SSE)
│ └── settings.go # 设置 API handler
│
├── services/
│ ├── git.go # Git 操作封装(clone、diff、graph)
│ ├── llm.go # LLM 调用封装(OpenAI 兼容)
│ ├── generate.go # PR 描述生成业务逻辑
│ ├── review.go # AI Review 业务逻辑
│ ├── cache.go # 仓库缓存管理(过期清理)
│ └── pdf.go # PDF 生成服务(chromedp HTML→PDF)
│
├── templates/
│ ├── layouts/
│ │ └── base.html # 基础布局模板
│ ├── pages/
│ │ ├── index.html # 首页
│ │ ├── repo.html # 仓库详情(Git Graph)
│ │ ├── generate.html # PR 生成页
│ │ ├── review.html # AI Review 页(含 Top-N 配置输入框)
│ │ └── settings.html # 设置页
│ └── partials/
│ ├── graph.html # Git Graph 组件
│ ├── diff/
│ │ ├── container.html # Diff 查看器主容器(文件树 + Diff 区域)
│ │ ├── file-tree.html # 文件树侧边栏组件
│ │ ├── file-diff.html # 单文件 Diff 卡片
│ │ └── review-inline.html # 行内 AI Review 建议卡片
│ ├── stream.html # SSE 流式展示组件
│ └── note-editor.html # 备注编辑器组件
│
├── templates/
│ └── reports/
│ └── review.html # PDF 报告专用模板(打印样式)
│
├── static/
│ ├── css/
│ │ ├── style.css # Tailwind 编译输出 + 自定义样式(含文件树、Diff 布局)
│ ├── js/
│ │ ├── graph.js # D3.js Git Graph 实现(含点击选择 base/head)
│ │ ├── diff-viewer.js # Diff 查看器逻辑(文件树联动、滚动高亮、行内建议插入)
│ │ ├── review-inline.js # 行内 Review 建议渲染 + 备注交互
│ │ ├── sse.js # SSE 连接管理(POST-based fetch+ReadableStream)
│ │ └── htmx.min.js # HTMX 库
│ └── lib/
│ ├── d3.min.js # D3.js 库
│ ├── diff2html.min.js # diff2html 库
│ ├── diff2html.min.css # diff2html 样式
│ └── highlight.min.js # highlight.js(diff2html 语法高亮依赖)
│
└── data/ # 运行时数据目录(Docker volume)
├── pr-helper.db # SQLite 数据库文件
└── repos/ # Clone 的仓库缓存
```
---
## 7. 核心流程图
### 7.1 PR 描述生成流程
```
用户输入 Git URL
│
▼
POST /api/repos ──→ goroutine: git clone
│ │
│ SSE: 进度推送
│ │
▼ ▼
仓库就绪 ◄────────── clone 完成
│
▼
GET /api/repos/:id/graph ──→ go-git: 遍历 refs/commits
│
▼
前端渲染 D3.js Git Graph
│
▼
用户选择 base..head
│
▼
GET /api/repos/:id/diff ──→ go-git: 计算 diff
│
▼
POST /api/repos/:id/generate
│
▼
goroutine:
1. 聚合 commit messages
2. 分析 diff(按文件拆分)
3. 构建 prompt
4. 调用 LLM(SSE 流式)
5. 解析结构化输出
│
▼
前端 SSE 接收 → 结构化展示 + Markdown 复制按钮
```
### 7.2 AI Review 流程
```
用户选择 base..head(复用已 clone 仓库)
│
▼
前端显示 diff 统计(总文件数、变更行数)
· Top-N 输入框,默认值 = 全局设置(20)
· 用户可修改,或留空表示分析全部
│
▼
POST /api/repos/:id/review { base, head, top_n }
│
▼
goroutine:
1. 提取 diff,按文件拆分
2. 按变更行数排序
3. 取 Top-N 文件(top_n=0 则全部)
4. 逐文件调用 LLM(SSE 流式推送每个文件的结果)
5. 最后汇总 prompt → 整体评估
│
▼
前端 SSE 接收 → 逐文件展示建议 + 整体评估
│
▼
用户追加备注(可选)
· POST /api/repos/:id/review/notes
· 支持整体/文件/建议三级备注
· Markdown 格式,实时保存
│
▼
导出 PDF(可选)
· POST /api/repos/:id/review/pdf
· 服务端渲染报告 HTML 模板
· chromedp 转 PDF
· 返回 PDF 下载链接
```
---
## 8. LLM Prompt 设计
### 8.1 PR 描述生成 Prompt
```
你是一个专业的技术文档撰写助手。根据以下 Git 变更信息,生成一份结构化的 PR 描述。
## Commit 记录
{{range .Commits}}
- {{.Hash}} {{.Message}}
{{end}}
## 代码变更 (Diff)
{{.Diff}}
请按以下 JSON 格式输出:
{
"title": "简洁的 PR 标题",
"type": "变更类型: feat|fix|refactor|docs|chore|style|test|perf",
"summary": "一段话概述变更内容",
"details": "详细的变更说明,按模块分组,使用 Markdown 格式",
"impact": "影响范围说明"
}
```
### 8.2 AI Review Prompt(单文件)
```
你是一个资深代码审查专家。请审查以下代码变更,给出专业的 Review 意见。
## 文件: {{.FileName}}
## 变更类型: {{.ChangeType}}
## Diff
{{.Diff}}
请按以下格式输出审查意见:
- 严重程度: critical / warning / info
- 问题描述: 清晰描述问题
- 建议修改: 具体的修改建议(如有)
- 代码示例: 建议的代码(如有)
如果没有问题,说明代码质量良好。
请用中文回复。
```
### 8.3 AI Review 汇总 Prompt
```
以下是多个文件的代码审查结果,请给出整体评估:
{{range .FileReviews}}
### {{.FileName}}
{{.ReviewResult}}
{{end}}
请输出:
1. 整体评分(1-10)
2. 总体评价(2-3 句话)
3. 主要发现汇总(按严重程度排序)
4. 改进建议优先级列表
```
---
## 9. Docker 部署
### 9.1 Dockerfile
```dockerfile
# 构建阶段
FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=1 go build -o pr-helper .
# 运行阶段
FROM alpine:3.19
RUN apk add --no-cache ca-certificates sqlite chromium
ENV CHROME_BIN=/usr/bin/chromium-browser
WORKDIR /app
COPY --from=builder /app/pr-helper .
COPY --from=builder /app/templates ./templates
COPY --from=builder /app/static ./static
VOLUME ["/app/data"]
EXPOSE 8080
CMD ["./pr-helper"]
```
> **注意**:chromedp 需要 Chromium。Docker 镜像中通过 `apk add chromium` 安装。
> 如果使用 Debian/Ubuntu 基础镜像,改用 `apt-get install chromium`。
> 也可以使用 `chromedp/headless-shell` 作为 sidecar 容器。
### 9.2 docker-compose.yml
```yaml
version: '3.8'
services:
pr-helper:
build: .
ports:
- "8080:8080"
volumes:
- pr-helper-data:/app/data
environment:
- GIN_MODE=release
restart: unless-stopped
volumes:
pr-helper-data:
```
---
## 10. 开发阶段
> **当前进度**:Phase 1-5 已完成,Phase 6 待完善
>
> - ✅ Phase 1(基础骨架):Go 项目、Gin 路由、SQLite、设置页面
> - ✅ Phase 2(Git 核心):clone、refs、diff、graph 数据、缓存管理
> - ✅ Phase 3(前端交互):Git Graph、Diff 查看器、文件树、SSE 流式展示、行内建议
> - ✅ Phase 4(LLM 集成):OpenAI 兼容 API、PR 描述生成、AI 代码审查、Top-N 策略
> - ✅ Phase 5(审查编辑与导出):备注编辑器、备注 CRUD API、PDF 报告生成
> - ⚠️ Phase 6(完善与部署):Docker 配置已完成,其他待完善
### Phase 1:基础骨架 ✅ 已完成
- [x] Go 项目初始化(go mod、目录结构)
- [x] Gin 路由和基础中间件
- [x] SQLite 数据库初始化和迁移
- [x] 基础 HTML 模板布局(Tailwind CSS)
- [x] 设置页面(LLM 配置)
### Phase 2:Git 核心 ✅ 已完成
- [x] go-git 集成:clone 仓库(SSE 进度推送)
- [x] go-git 集成:获取 refs、commits
- [x] go-git 集成:计算 diff
- [x] Git Graph 数据提取(构建节点和边)
- [x] 仓库缓存管理(过期清理)
### Phase 3:前端交互 ✅ 已完成
- [x] D3.js Git Graph 可视化(graph.js)
- [x] Diff 查看器组件(diff2html Split 视图)(diff-viewer.js)
- [x] 交互式分支/commit 选择(base/head 选择,点击 Graph 节点选择)
- [x] 文件树侧边栏(树形结构、点击跳转、滚动高亮联动)
- [x] Split/Unified 视图切换
- [x] AI Review 行内建议展示(嵌入代码行旁)
- [x] SSE 流式展示组件(sse.js)
### Phase 4:LLM 集成 ✅ 已完成
- [x] OpenAI 兼容 API 调用封装(services/llm.go)
- [x] PR 描述生成(prompt + SSE 流式)(services/generate.go)
- [x] AI 代码审查(分文件处理 + 汇总)(services/review.go)
- [x] 大 diff 处理(Top-N 策略)
### Phase 5:审查编辑与导出 ✅ 已完成
- [x] 备注编辑器组件(Markdown 支持,三级作用域)
- [x] 备注 CRUD API(保存/读取)
- [x] PDF 报告 HTML 模板(打印样式)
- [x] chromedp HTML→PDF 生成服务
- [x] PDF 下载接口
### Phase 6:完善与部署 ⚠️ 部分完成
- [ ] 错误处理和用户提示
- [x] Dockerfile + docker-compose(含 Chromium)
- [ ] 文档和使用说明
- [ ] 测试和优化
---
## 11. 关键依赖
```go
// go.mod 关键依赖
require (
github.com/gin-gonic/gin // Web 框架
github.com/mattn/go-sqlite3 // SQLite 驱动
github.com/go-git/go-git/v5 // Git 操作
github.com/sashabaranov/go-openai // OpenAI API 客户端
github.com/chromedp/chromedp // headless Chrome,HTML 转 PDF
)
```
前端(CDN 或本地):
- HTMX 2.x
- D3.js 7.x
- diff2html 3.x(Diff 渲染,内置 split/unified 视图 + 语法高亮)
- highlight.js 11.x(diff2html 依赖,代码语法高亮)
- Tailwind CSS 3.x(CLI 编译)
---
## 12. 注意事项
1. **安全性**:无认证设计意味着不应暴露到公网,仅限内网/本地使用
2. **性能**:大仓库 clone 可能耗时较长,需要进度反馈;考虑 shallow clone 选项
3. **LLM 成本**:大 diff 的 token 消耗可能很高,Top-N 策略控制成本
4. **并发**:goroutine 管理需要考虑优雅关闭和 panic 恢复
5. **存储**:仓库缓存可能占用大量磁盘空间,过期清理策略很重要