# 架构概览 ## 项目简介 PR-Helper 是一个自托管的 Web 服务,用于从 Git 历史自动生成 PR 描述并执行 AI 代码审查。专为内部/本地使用设计(无认证)。 ## 技术栈 | 层级 | 技术 | |------|------| | 后端 | Go + Gin + MySQL + go-git | | 前端 | Go html/template + HTMX + D3.js + diff2html + Tailwind CSS | | LLM | OpenAI 兼容 API(SSE 流式传输) | | 部署 | Docker | ## 目录结构 ``` PR-Helper/ ├── main.go # 应用入口 ├── config/ # 配置加载 │ └── config.go ├── database/ # 数据库初始化和迁移 │ └── db.go ├── handlers/ # HTTP 处理器(页面 + JSON API + SSE) │ ├── auth.go # 认证处理 │ ├── generate.go # PR 生成 SSE 端点 │ ├── pages.go # 页面渲染 │ ├── repos.go # 仓库管理 API │ ├── review.go # 代码审查 SSE 端点 │ ├── settings.go # 设置 API │ └── middleware.go # 中间件 ├── models/ # 数据模型 │ ├── repository.go # 仓库模型 │ ├── analysis.go # 分析结果模型 │ └── settings.go # 默认设置 ├── services/ # 业务逻辑 │ ├── git.go # Git 操作(克隆、差异、图形数据) │ ├── llm.go # LLM API 调用(SSE 流式) │ ├── generate.go # PR 描述生成 │ ├── review.go # AI 代码审查 │ ├── cache.go # 仓库缓存管理 │ └── notes.go # 审查笔记 ├── templates/ # Go HTML 模板 │ ├── layouts/ # 布局模板 │ ├── pages/ # 页面模板 │ └── partials/ # 局部模板 ├── static/ # 静态资源 │ ├── css/ # Tailwind 输出 │ ├── js/ # 自定义 JS │ └── lib/ # 第三方库 └── data/ # 数据存储 └── repos/ # 克隆的仓库缓存 ``` ## 数据流 ``` 浏览器 ↔ Gin 处理器 → 服务层(git/llm)→ MySQL + 文件系统(data/) ``` ### 请求流程 1. **浏览器** 发起 HTTP 请求(HTMX 或 fetch) 2. **Gin 路由** 匹配处理器函数 3. **中间件** 验证会话和用户认证 4. **处理器** 解析请求参数 5. **服务层** 执行业务逻辑 6. **数据库/文件系统** 持久化数据 7. **SSE 流** 返回实时更新(可选) ## 核心模块 ### 配置模块 (config/) - 从 `.env` 文件加载环境变量 - 提供默认值 - 生成随机会话密钥(如未配置) ### 数据库模块 (database/) - MySQL 连接管理 - 自动迁移(CREATE TABLE IF NOT EXISTS) - 增量迁移(ALTER TABLE,忽略重复列错误) - 默认设置初始化 ### 处理器模块 (handlers/) - **页面处理器**: 渲染 HTML 模板 - **仓库处理器**: 克隆、删除、拉取、获取图形/差异 - **生成处理器**: PR 描述生成(SSE 流式) - **审查处理器**: AI 代码审查(SSE 流式) - **设置处理器**: 读取/更新用户设置 ### 服务模块 (services/) - **git.go**: 使用 go-git 库执行 Git 操作 - **llm.go**: OpenAI 兼容 API 调用,支持流式响应 - **generate.go**: 从提交历史和差异生成 PR 描述 - **review.go**: Top-N 策略的 AI 代码审查 - **cache.go**: 仓库缓存生命周期管理 ### 前端模块 (static/js/) - **sse.js**: SSE 客户端,支持 POST 请求 - **graph.js**: D3.js Git 图形可视化 - **diff-viewer.js**: diff2html 差异查看器 - **review-inline.js**: 内联 AI 建议 - **markdown.js**: Markdown 渲染 - **note-editor.js**: 审查笔记编辑器 ## 关键设计决策 ### 1. SSE 流式传输 选择 SSE 而非 WebSocket 的原因: - 单向服务器到客户端通信足够 - HTTP 兼容性更好 - 实现更简单 - 自动重连 ### 2. Top-N 策略 大型差异处理: - 按变更行数排序文件 - 只分析前 N 个文件(默认 20) - 每个文件独立分析 - 最后生成汇总 ### 3. 三级审查笔记 - `overall`: 整体审查笔记 - `file`: 文件级别笔记 - `suggestion`: 建议级别笔记 ### 4. 会话认证 - 基于 Cookie 的会话 - 7 天过期 - HttpOnly 标记 - 随机会话密钥 ## 扩展性考虑 ### 水平扩展 - 无状态设计(会话存储在 Cookie) - 数据库可外部化 - 文件存储可替换为对象存储 ### LLM 集成 - 支持任何 OpenAI 兼容 API - 每用户独立配置 - 可扩展为多模型支持 ## 安全考虑 - 仅限内部使用(无认证) - 不暴露到公网 - SQL 参数化查询 - 会话 HttpOnly - 凭证不明文存储在 JSON 响应中