diff --git a/prd-home-open-source-contributions-section.md b/prd-home-open-source-contributions-section.md new file mode 100644 index 0000000..4cce2bf --- /dev/null +++ b/prd-home-open-source-contributions-section.md @@ -0,0 +1,477 @@ +# Home 页新增“开源贡献”板块与后台可编辑支持 PRD + +## 背景 + +用户希望在 `https://www.ephron.ren/` 首页新增一个独立板块:**开源贡献**,并且该板块内容必须能够在 Home 后台中编辑、保存草稿、发布,不接受只改前台模板的静态实现。 + +本 PRD 基于 `origin/main` 最新源码分析,覆盖 Home 的: +- 公共渲染模板 +- Admin 编辑模板 +- content schema +- 草稿 / 发布链路 +- 兼容策略 +- 测试要求 + +--- + +## 现状分析 + +### 1. 首页当前内容结构 + +当前 Home 页公共模板位于: +- `home/templates/index.html` + +当前页面主区块顺序大致为: +1. Hero +2. 工作经历 +3. 项目经验 +4. 技术栈 +5. 页脚 +6. 联系方式弹窗 + +其中内容类区块已经形成清晰模式: +- `experience`:时间线列表 +- `projects`:时间线列表 + tags + 可选 badge +- `skills`:分类列表 + +### 2. Home 内容 schema 当前主结构 + +当前 `home/src/services/content.py` 中 HomeContent 及默认内容模板包含: + +```python +hero +experience +projects +skills +contact +footer +``` + +当前**没有** `open_source` 或同义字段。 + +### 3. 后台编辑页当前主结构 + +后台模板位于: +- `home/templates/admin/index.html` + +当前后台已提供以下可编辑区块: +- Hero +- 工作经历 +- 项目经验 +- 技术栈 +- 联系方式 +- 页脚 + +其 JS 通过 `initialContent` + 各类 `renderXxx()`、`addXxx()`、`updateXxx()`、`removeXxx()` 管理动态列表,再通过 `collectFormData()` 汇总为完整 `content_json`。 + +### 4. Draft / Publish 机制已存在 + +Home Admin 已支持: +- 保存草稿 +- 发布内容 +- 丢弃草稿 + +相关服务链路位于: +- `home/src/routes/admin.py` +- `home/src/services/content.py` + +所以本次需求不应走“单独 API”或“静态 hardcode”路线,而应纳入现有 content schema。 + +--- + +## 问题定义 + +如果只是简单在前台首页插入一个“开源贡献”区块,会有以下问题: + +1. **后台无法维护** + - 用户明确要求后台可修改 + - 只改模板会让内容写死在代码里 + +2. **不进入草稿 / 发布流程** + - 无法像其他首页内容一样先保存草稿再发布 + +3. **与 Home 当前内容架构不一致** + - Home 当前是 schema 驱动 + admin 驱动 + - 新区块也应遵循同样模式 + +4. **历史内容兼容问题** + - 线上已有 `content_json` 一定不包含新字段 + - 如果不做 normalize,可能出现模板取值缺失或后台初始值异常 + +--- + +## 目标 + +### 产品目标 +在首页新增一个独立的 **开源贡献** 板块,用于展示用户的开源贡献记录。 + +### 后台目标 +管理员可在 Home 后台中: +- 新增开源贡献条目 +- 编辑开源贡献条目 +- 删除开源贡献条目 +- 标记草稿 / 已发布条目(如果沿用当前列表编辑模式) +- 保存草稿 +- 发布 + +### 技术目标 +将“开源贡献”纳入 Home 的统一内容 schema,而不是写死在模板中。 + +--- + +## 核心设计判断 + +## 为什么建议新增独立 `open_source` 区块,而不是复用 `projects` + +虽然“开源贡献”看起来和“项目经验”都属于列表,但我**不建议复用 `projects`**,原因如下: + +1. **语义不同** + - 项目经验是个人项目 / 研究 / 比赛 /工程经历 + - 开源贡献是对外部开源生态的参与记录 + +2. **展示重心不同** + - 项目经验偏“我做了什么项目” + - 开源贡献偏“我向哪些项目贡献了什么” + +3. **后台认知更清晰** + - 管理员能清楚区分两类信息 + - 避免未来在同一列表中混入不同语义的数据 + +4. **后续扩展更容易** + - 以后可独立增加 repo 链接、PR 链接、贡献类型、状态标签等 + +### 结论 +**本次建议新增独立字段:`open_source`** + +--- + +## 数据结构设计 + +### 建议新增主字段 + +在 Home content 顶层新增: + +```json +"open_source": [] +``` + +### 单条条目建议结构 + +建议最小结构如下: + +```json +{ + "title": "Hermes Agent", + "role": "提交 PR 修复 MiMo reasoning_content", + "date": "2026.05", + "description": [ + "向上游提交并推动合并 MiMo reasoning_content 修复", + "补充兼容性验证与使用说明" + ], + "tags": ["Python", "Hermes", "Open Source"], + "link": "https://github.com/NousResearch/hermes-agent/pull/25358", + "is_draft": false +} +``` + +### 字段说明 + +- `title` + - 开源项目名 / 仓库名 / 贡献对象名 +- `role` + - 一句话说明贡献类型或身份 + - 例如:修复 PR、功能贡献、文档维护、Issue triage +- `date` + - 贡献时间,沿用当前 Home 的字符串时间格式 +- `description` + - 多条描述,后台可按“每行一条”编辑 +- `tags` + - 技术标签或贡献类型标签 +- `link` + - 对外链接,建议指向 PR / repo / profile / issue +- `is_draft` + - 若沿用现有列表项 draft 切换机制,则保留该字段 + +### 为什么建议有 `link` + +因为“开源贡献”天然需要外部证明入口: +- GitHub PR +- 仓库主页 +- 个人 Profile + +如果没有链接,板块很容易退化成纯文字陈列。 + +--- + +## 服务层改造 + +### 必改文件 +- `home/src/services/content.py` + +### 要求 + +#### 1. 扩展默认 schema +在 `_get_empty_content()` 中新增: + +```python +"open_source": [] +``` + +#### 2. 扩展 normalize +在 `_normalize_content()` 中补: + +```python +content.setdefault("open_source", []) +``` + +#### 3. 兼容性原则 +旧内容没有 `open_source` 时: +- 首页应正常打开 +- 后台应正常打开 +- 不要求先清洗数据库历史内容 + +--- + +## 前台首页改造 + +### 必改文件 +- `home/templates/index.html` + +### 板块位置建议 +建议插入在: +- **项目经验之后** +- **技术栈之前** + +推荐顺序: +1. 工作经历 +2. 项目经验 +3. **开源贡献** +4. 技术栈 + +### 原因 + +1. 信息层级更合理 + - 工作 / 项目 / 开源 属于“经历与实践”一组 + - 技术栈更适合作为总结性能力列表放在后面 + +2. 开源贡献不应放到页脚附近 + - 会显得像附属信息,而不是正式内容资产 + +### 渲染方式建议 + +建议复用当前 `timeline-item` 风格,保持页面一致性。 + +示意结构: + +```jinja2 +{% if content.open_source %} +
+

开源贡献

+ {% for item in content.open_source if not item.get('is_draft', False) %} +
+
+
+

{{ item.title }}

+

{{ item.role }}

+
+ {{ item.date }} +
+
+
    + {% for bullet in item.bullets %} +
  • {{ bullet }}
  • + {% endfor %} +
+ {% if item.tags %} +
+ {% for tag in item.tags %} + {{ tag }} + {% endfor %} +
+ {% endif %} + {% if item.link %} + 查看贡献 + {% endif %} +
+
+ {% endfor %} +
+{% endif %} +``` + +### 说明 + +- 样式可直接复用 `timeline-item`、`project-tags`、`project-badge` +- 不建议本次重新发明一套视觉组件 +- 重点是内容建模与后台可维护性,而不是视觉重构 + +--- + +## 后台管理页改造 + +### 必改文件 +- `home/templates/admin/index.html` + +### 建议新增一个完整 Section +在“项目经验”和“技术栈”之间新增: + +- 板块标题:`开源贡献` +- 列表容器:`
` +- 添加按钮:`+ 添加开源贡献` + +### 建议沿用现有动态列表编辑模式 +即仿照: +- `renderProjects()` +- `addProject()` +- `removeProject()` +- `updateProject()` +- `toggleProjectDraft()` + +新增一组: +- `renderOpenSource()` +- `addOpenSource()` +- `removeOpenSource(index)` +- `updateOpenSource(index, field, value)` +- `updateOpenSourceBullets(index, value)` +- `updateOpenSourceTags(index, value)` +- `toggleOpenSourceDraft(index)`(若保留每项草稿状态) + +### 单条后台表单建议字段 + +- 项目 / 仓库名称(title) +- 贡献角色 / 一句话说明(role) +- 时间(date) +- 描述(每行一条) +- 标签(逗号分隔) +- 外部链接(link) + +### collectFormData 必须同步补充 + +```js +open_source: initialContent.open_source, +``` + +否则后台加了 UI 也不会进入 `content_json`。 + +--- + +## 命名一致性要求 + +当前代码中存在一个值得注意的事实: +- 前台项目区渲染使用的是 `project.bullets` +- 但示例数据文件中很多项目仍然是 `description` + +这说明 Home 当前已有一定字段漂移历史。 + +### 本次 PRD 的要求 +对于“开源贡献”,字段命名必须从一开始就统一,不要再制造第二套字段名。 + +建议直接统一使用: +- `bullets` 作为前台 / 后台 / 存储字段名 + +而不是: +- 后台叫 `description` +- 前台叫 `bullets` +- 示例数据再写成第三种 + +### 结论 +**开源贡献条目统一使用 `bullets`,不要引入 `description`。** + +--- + +## 测试要求 + +### 必改文件 +- `home/tests/test_admin_permissions.py` + 或 Home 对应测试文件 + +### 建议至少补 4 类测试 + +#### 1. Admin 渲染测试 +后台页面应出现: +- `openSourceList` +- `添加开源贡献` +- 对应字段输入结构 + +#### 2. 首页渲染测试 +当 `open_source` 有已发布数据时: +- 首页应显示 `开源贡献` 标题 +- 应显示条目标题 / 链接 + +#### 3. 空列表隐藏测试 +当 `open_source` 为空时: +- 首页不应显示空板块 + +#### 4. 旧 schema 兼容测试 +当历史内容没有 `open_source` 字段时: +- 首页正常打开 +- 后台正常打开 + +### 可选补充 +如果你们继续沿用每项 `is_draft`: +- 测试首页不会渲染 `open_source` 中 `is_draft=true` 的条目 + +--- + +## 验收标准 + +### 前台 +1. 首页新增 `开源贡献` 板块 +2. 板块位于“项目经验”之后、“技术栈”之前 +3. 存在数据时正常渲染条目 +4. 条目链接可打开外部页面 +5. 无数据时不显示空板块 + +### 后台 +1. 管理页新增“开源贡献”编辑区块 +2. 支持新增 / 编辑 / 删除条目 +3. 保存草稿后刷新后台可回显 +4. 发布后首页可见 +5. 丢弃草稿后未发布修改可撤销 + +### 兼容性 +1. 历史 `content_json` 没有 `open_source` 字段时不报错 +2. 不要求先手工迁移历史数据库内容 + +--- + +## 非目标 + +本次 PRD 不包含: +- 从 GitHub API 自动拉取开源贡献 +- 统计贡献数量、Star、PR 数等自动指标 +- 把开源贡献和项目经验合并 +- 新增单独的 Home Service API +- 重做首页视觉风格 + +--- + +## 实施顺序建议 + +1. 先改 `home/src/services/content.py` + - schema 默认值 + - normalize 兼容 +2. 再改 `home/templates/admin/index.html` + - 新区块 UI + - 新增 JS 列表管理逻辑 + - 更新 `collectFormData()` +3. 最后改 `home/templates/index.html` + - 新区块渲染 +4. 补测试 + +这样可以避免先改模板后 schema 未补齐导致的半更新问题。 + +--- + +## 结论 + +“开源贡献”不是单纯新增一段 HTML,而是一个完整的 **Home 内容模型扩展**。 + +要满足“前台显示 + 后台可改 + 草稿发布 + 历史兼容”,最小闭环必须同时覆盖: +- schema +- normalize +- admin 区块 +- 前台渲染 +- 测试 + +建议采用独立 `open_source` 列表区块,而不是复用 `projects`。这样语义更清晰,也更利于后续继续扩展你的开源履历展示。 \ No newline at end of file