# Home 页开源贡献卡片新增“仓库地址”字段 Follow-up PRD ## 背景 当前 Home 页“开源贡献”卡片已经支持: - 主标题 / 副标题 - 描述 bullets - tags - 一个通用外链 `link` - 按钮文案 `link_label`(follow-up 设计中) 但在实际使用上,一个通用 `link` 仍然不够细: - 有的链接更适合指向 **PR / Commit / Issue** - 有的链接更适合指向 **仓库主页** 如果只有一个 `link`,会导致两种信息混在一起: - “这条贡献发生在哪个仓库” - “这条贡献的具体证据 / 详情入口是什么” 因此本次新增一个很小的 follow-up: **为开源贡献条目增加独立的“仓库地址”字段,并支持后台编辑。** --- ## 目标 ### 产品目标 让开源贡献卡片同时表达两类信息: 1. 贡献发生在哪个仓库 2. 具体贡献详情查看入口是什么 ### 技术目标 在保持现有 `open_source` schema 向后兼容的前提下,新增一个可选字段用于仓库地址。 --- ## 问题定义 ### 当前问题 当前条目只有: ```json "link": "https://..." ``` 它语义不明确,可能指向: - 仓库主页 - Pull Request - Commit - Issue - Release - 作者主页 这会带来两个问题: 1. **仓库归属信息表达不足** - 即使副标题写了仓库名,也无法点击进入仓库主页 2. **一个链接承担两种职责** - 既想作为“仓库地址” - 又想作为“查看贡献详情” - 容易冲突 --- ## 设计原则 ### 原则 1:仓库地址与贡献详情分离 - `repo_url`:仓库主页 - `link`:具体贡献详情链接 ### 原则 2:保持最小改动 不重做整张卡片,不新增复杂交互,仅补充一个可选字段和对应展示方式。 ### 原则 3:兼容旧数据 历史 `open_source` 条目没有 `repo_url` 时,前台和后台都必须正常工作。 --- ## 方案设计 ## 一、新增字段 在 `open_source` 每条记录中新增: ```json "repo_url": "https://github.com/NousResearch/hermes-agent" ``` ### 字段语义 - `repo_url` - 指向该开源贡献所属的仓库主页 - 可选字段 ### 推荐结构 ```json { "title": "修复 Hermes Agent 对 Xiaomi MiMo reasoning_content 的兼容性问题", "role": "NousResearch/hermes-agent", "date": "2026.05", "bullets": [ "定位 Xiaomi MiMo thinking 模式下 assistant tool-call replay 缺少 reasoning_content 导致的 HTTP 400 问题", "提交 provider 检测与 reasoning echo-back 修复方案" ], "tags": ["Python", "LLM", "Agent", "Compatibility"], "repo_url": "https://github.com/NousResearch/hermes-agent", "link": "https://github.com/NousResearch/hermes-agent/pull/25484", "link_label": "查看合并 PR", "is_draft": false } ``` --- ## 二、前台展示方案 ### 必改文件 - `home/templates/index.html` ### 展示目标 前台需要同时支持: - 仓库地址存在时,可进入仓库主页 - 贡献详情链接存在时,可进入 PR / commit / issue / 详情页 ### 推荐做法 #### 方案 A:将副标题仓库名变为可点击链接(推荐) 如果: - `item.role` 有值 - `item.repo_url` 有值 则将当前副标题从纯文本: ```jinja2

{{ item.role }}

``` 改为: ```jinja2 {{ item.role }} ``` 如果没有 `repo_url`,仍按纯文本显示。 ### 为什么推荐这个方案 因为: - 副标题本来就承载“项目 / 仓库名称”语义 - 给它加链接最自然 - 不会新增第二个按钮,避免卡片过挤 ### `link` 的职责 仍保留卡片底部按钮: - `link` → 贡献详情 - `link_label` → 详情按钮文案 这样形成清晰分工: - 仓库名 → 仓库地址 - 按钮 → 贡献详情 --- ## 三、后台编辑方案 ### 必改文件 - `home/templates/admin/index.html` ### 新增输入项 在开源贡献编辑区新增一个字段: - 标签:`仓库地址(可选)` - 字段名:`repo_url` - 类型:`url` - placeholder:`例如:https://github.com/owner/repo` ### 建议位置 建议放在: - `项目 / 仓库名称(可选)` 下方 - `外部链接 / 贡献详情链接` 上方 推荐顺序: 1. 贡献摘要 / 主标题 2. 项目 / 仓库名称(可选) 3. **仓库地址(可选)** 4. 时间 5. 描述 6. tags 7. 贡献详情链接 `link` 8. 按钮文案 `link_label` ### JS 需要同步更新 需要补到: - `renderOpenSource()` - `addOpenSource()` - `updateOpenSource()` - `collectFormData()` 默认结构建议变为: ```js { title: '', role: '', repo_url: '', date: '', bullets: [], tags: [], link: '', link_label: '', is_draft: true } ``` --- ## 四、服务层兼容要求 ### 必改文件 - `home/src/services/content.py` ### 兼容要求 这次不需要强制迁移旧数据。 旧条目没有 `repo_url` 时: - 前台副标题仍正常显示为纯文本 - 后台输入框为空 - 不影响既有 `link` 的使用 ### 可选做法 若希望结构更整齐,可以在 normalize 时对 `open_source` 每项补: ```python item.setdefault("repo_url", "") ``` 但不是必须项。 --- ## 五、测试要求 ### 必改文件 - `home/tests/test_admin_permissions.py` 或对应 Home 测试文件 ### 至少补 4 类测试 #### 1. 后台出现仓库地址输入项 验证: - 开源贡献编辑区出现 `repo_url` 对应的 URL 输入框 - 页面中存在“仓库地址”相关文案 #### 2. 前台在有 `repo_url` 时将仓库名渲染为链接 验证: - `item.role` 文本存在 - 对应链接指向 `repo_url` #### 3. 前台在没有 `repo_url` 时仓库名仍显示为纯文本 验证: - 页面正常显示副标题 - 不要求仓库名可点击 #### 4. 旧数据兼容 当历史 `open_source` 条目没有 `repo_url` 时:首页与后台都正常打开。 --- ## 验收标准 ### 前台 1. 开源贡献卡片在存在 `repo_url` 时,仓库名可点击进入仓库主页 2. 贡献详情按钮继续可用,不受影响 3. 没有 `repo_url` 时,仓库名仍正常显示为纯文本 ### 后台 1. 开源贡献编辑区新增“仓库地址(可选)”输入项 2. 保存草稿 / 发布 / 回显正常 3. `repo_url` 与 `link` 不混淆 ### 兼容性 1. 历史条目没有 `repo_url` 不报错 2. 不要求手动迁移已有内容 --- ## 非目标 本次 follow-up 不包含: - 一个卡片展示多个按钮(如“查看仓库”“查看 PR”并列) - 自动从 GitHub 链接反推仓库名 - 自动抓取仓库 star / language / metadata - 开源贡献卡片的整体样式重构 --- ## 实施顺序建议 1. 后台新增 `repo_url` 输入项 2. 更新 `renderOpenSource()` / `collectFormData()` 3. 前台将副标题仓库名按条件渲染为链接 4. 补测试 --- ## 结论 这个 follow-up 很小,但信息结构会更清楚。 新增 `repo_url` 后,开源贡献卡片可以明确区分: - **仓库归属**:`repo_url` - **贡献详情**:`link` 这样比让单个 `link` 同时承担两类语义更干净,也更适合长期维护。