diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..1bebbf4 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +在 ./PLAN.md 中规划 \ No newline at end of file diff --git a/PLAN.md b/PLAN.md new file mode 100644 index 0000000..235093d --- /dev/null +++ b/PLAN.md @@ -0,0 +1,790 @@ +# 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.css # Diff 查看器自定义样式(覆盖 diff2html 默认) +│ ├── js/ +│ │ ├── graph.js # D3.js Git Graph 实现 +│ │ ├── diff-viewer.js # Diff 查看器逻辑(文件树联动、滚动高亮) +│ │ ├── review-inline.js # 行内 Review 建议渲染 + 备注交互 +│ │ ├── htmx.min.js # HTMX 库 +│ │ └── sse.js # SSE 连接管理 +│ └── 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:基础骨架 +- [ ] Go 项目初始化(go mod、目录结构) +- [ ] Gin 路由和基础中间件 +- [ ] SQLite 数据库初始化和迁移 +- [ ] 基础 HTML 模板布局(Tailwind CSS) +- [ ] 设置页面(LLM 配置) + +### Phase 2:Git 核心 +- [ ] go-git 集成:clone 仓库 +- [ ] go-git 集成:获取 refs、commits +- [ ] go-git 集成:计算 diff +- [ ] Git Graph 数据提取(构建节点和边) +- [ ] 仓库缓存管理(过期清理) + +### Phase 3:前端交互 +- [ ] D3.js Git Graph 可视化 +- [ ] 交互式分支/commit 选择 +- [ ] Diff 查看器组件(diff2html Split 视图) +- [ ] 文件树侧边栏(树形结构、点击跳转、滚动高亮联动) +- [ ] 上下文行折叠/展开 +- [ ] Split/Unified 视图切换 +- [ ] AI Review 行内建议展示(嵌入代码行旁) +- [ ] SSE 流式展示组件 + +### Phase 4:LLM 集成 +- [ ] OpenAI 兼容 API 调用封装 +- [ ] PR 描述生成(prompt + SSE 流式) +- [ ] AI 代码审查(分文件处理 + 汇总) +- [ ] 大 diff 处理(Top-N 策略) + +### Phase 5:审查编辑与导出 +- [ ] 备注编辑器组件(Markdown 支持,三级作用域) +- [ ] 备注 CRUD API(保存/读取) +- [ ] PDF 报告 HTML 模板(打印样式) +- [ ] chromedp HTML→PDF 生成服务 +- [ ] PDF 下载接口 + +### Phase 6:完善与部署 +- [ ] 错误处理和用户提示 +- [ ] 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. **存储**:仓库缓存可能占用大量磁盘空间,过期清理策略很重要