# onlyWeb 产品需求文档

## 目录

- [1. 背景](#1-背景)
- [2. 产品目标](#2-产品目标)
- [3. 用户角色](#3-用户角色)
- [4. 核心场景](#4-核心场景)
- [5. 功能需求](#5-功能需求)
- [6. 非功能需求](#6-非功能需求)
- [7. 数据实体](#7-数据实体)
- [8. MVP 范围](#8-mvp-范围)
- [9. 当前前端 Mock 原型](#9-当前前端-mock-原型)
- [10. 成功指标](#10-成功指标)
- [11. 当前正式程序实现状态](#11-当前正式程序实现状态)
- [12. 软删除和回收站](#12-软删除和回收站)
- [13. 作品文档上传](#13-作品文档上传)
- [14. Markdown 阅读体验优化](#14-markdown-阅读体验优化)
- [15. HR 联系信息展示](#15-hr-联系信息展示)
- [16. 作品效果演示与模块展示配置](#16-作品效果演示与模块展示配置)
- [17. AGENTS.md 要求模块对照](#17-agentsmd-要求模块对照)
- [18. Wiki 知识库展示](#18-wiki-知识库展示)

## 1. 背景

个人求职过程中，不同公司和岗位关注点不同。传统单份简历难以充分展示与目标岗位最相关的经历和作品。

onlyWeb 希望提供一个个人网站系统，让网站所有者可以：

- 管理个人资料、工作经历、项目作品和技能。
- 针对不同公司和岗位生成定制化简历页面。
- 将个人作品集中展示，作为长期维护的个人品牌入口。

## 2. 产品目标

### 2.1 短期目标

构建一个可以 Docker 部署的小型个人网站系统，支持：

- 公开展示个人信息和作品。
- 创建不同公司 / 岗位的定制简历页面。
- 通过后台管理核心内容。

### 2.2 长期目标

将 onlyWeb 打造成个人职业展示中枢，支持：

- 定制化投递页面管理。
- 作品长期沉淀。
- 访问统计。
- 简历 PDF 下载。
- 页面权限控制。
- 多端适配和 SEO 优化。

## 3. 用户角色

### 3.1 访客

典型用户：HR、面试官、招聘负责人、合作方。

访客目标：

- 快速了解网站所有者是谁。
- 查看与岗位相关的经历和项目。
- 访问个人作品。
- 获取联系方式。

### 3.2 管理员

典型用户：网站所有者本人。

管理员目标：

- 维护个人资料。
- 管理作品和经历。
- 创建定制简历页面。
- 控制内容发布状态。

## 4. 核心场景

### 4.1 作品展示

管理员添加项目作品，访客可以在作品集页面浏览，并进入详情页查看项目介绍、截图、技术栈、职责和链接。

### 4.2 通用简历展示

访客可以访问通用简历页，看到完整但精简的个人履历。

### 4.3 定制化投递

管理员针对某个公司和岗位创建定制页面。

示例：

```txt
公司：字节跳动
岗位：前端工程师
管理员预览路径：/for/bytedance/frontend-engineer
HR 专属路径：/r/hr-bytedance-frontend-2026
```

管理员可以为该页面选择：

- 重点展示哪些经历。
- 重点展示哪些项目。
- 展示哪些技能。
- 写一段针对岗位的匹配说明。
- 生成或复制 HR 专属分享链接。

HR 打开专属链接后，只能看到对应岗位的个人展示页，不能看到其他公司或岗位的定制页，也不能看到定制页管理列表。

## 5. 功能需求

### 5.1 前台功能

### 5.1.1 首页

首页用于建立第一印象。

应包含：

- 姓名
- 当前职业定位
- 一句话介绍
- 核心技能摘要
- 精选作品
- 联系入口

优先级：P0

### 5.1.2 作品列表页

展示已发布的作品。

应包含：

- 作品标题
- 简介
- 封面图，可选
- 技术栈标签
- 是否精选
- 详情页入口

优先级：P0

### 5.1.2.1 独立作品集展示页

用于只展示作品集的独立页面，不展示站点导航，作品卡片可点击进入对应作品详情。

要求：

- 路径为 `/portfolio`。
- 只展示已发布作品。
- 作品卡片可点击进入对应作品详情页。
- 从 `/portfolio` 进入的作品详情页和文档预览页必须继续保持独立展示模式，不能出现全站导航和页脚。
- 不展示页头导航和页脚。
- 后台作品管理页需要在工具栏和顶部卡片展示 `/portfolio` 入口及完整访问地址，并支持打开和复制。

优先级：P0

### 5.1.3 作品详情页

展示单个作品的完整信息。

应包含：

- 标题
- 简介
- 详细说明
- 技术栈
- 个人职责
- 项目亮点
- 截图，可选
- 演示链接，可选
- 代码链接，可选
- 文档链接，可选
- 效果演示模块，可配置视频链接或演示文档；作品详情页面向 HR、人资总监、总经理等非技术读者，优先展示业务痛点、解决方案、使用效果、项目价值和个人贡献，完整技术或文档内容通过资料入口查看
- 模块展示开关：项目介绍、个人职责、效果演示、项目亮点、技术栈、相关链接/文档均可按作品控制是否展示
- 上传文档在线预览：Markdown 直接渲染，PDF 直接预览，Word `.doc/.docx` 转 PDF 后预览

优先级：P0

### 5.1.4 通用简历页

展示默认个人简历。

应包含：

- 基础信息
- 工作经历
- 项目经历
- 技能
- 教育经历，后续可选
- 联系方式

优先级：P0

### 5.1.5 定制简历页

根据公司和岗位动态展示内容。

路径建议：

```txt
/for/:companySlug/:positionSlug 管理员预览地址，需要登录
/r/:shareToken                 HR 专属访问地址
```

应包含：

- 公司名称
- 岗位名称
- 页面标题
- 定制化介绍
- 岗位匹配说明
- 关联经历
- 关联项目
- 关联技能
- 联系方式

访问约束：

- 前台导航不展示定制页列表。
- 管理员登录后才能进入定制页管理和预览地址。
- HR 只能通过收到的 `/r/:shareToken` 访问单个定制页。
- HR 页面不展示其他定制页入口。

优先级：P0

### 5.1.6 联系页

展示联系方式。

可包含：

- 邮箱
- GitHub
- LinkedIn
- 个人网站
- 微信号和微信二维码

优先级：P1

### 5.2 后台功能

### 5.2.1 管理员登录

管理员通过邮箱和密码登录后台。

需求：

- 支持登录
- 支持退出
- 后台页面需要登录保护
- 定制页管理和管理员预览需要登录保护

优先级：P0

### 5.2.2 个人资料管理

可维护：

- 姓名
- 职业标题
- 个人简介
- 所在地
- 邮箱
- 手机，可选
- GitHub
- LinkedIn
- 网站链接

优先级：P0

### 5.2.3 作品管理

作品管理页面在桌面端需要支持左侧作品名称列表和右侧作品详情独立滚动，鼠标停留在哪个区域就滚动哪个区域；点击左侧作品后应保持当前页面和列表滚动位置，只刷新右侧作品内容，避免编辑长表单时频繁丢失左侧作品定位。

支持：

- 创建作品
- 编辑作品
- 删除作品
- 发布 / 隐藏作品
- 设置精选作品
- 配置作品详情页模块是否展示
- 维护效果演示信息：演示类型、标题、说明、链接
- 维护业务成果展示信息：展示标题、首屏说明、使用场景、核心价值、交付形式、业务痛点、解决步骤、使用效果、项目价值、个人贡献、管理者关注点、技术实现标签
- 管理员登录后可在作品详情页点击“编辑页面”进入原位编辑模式，直接编辑业务成果展示、“我负责什么”和技术实现标签，并能继续新增标签；资料入口模块展示现有文档列表，并支持直接上传普通文档和效果演示文档；完整作品管理页继续维护发布状态和模块开关
- 单独上传效果演示文档，不能与普通项目文档混在一起
- 上传普通项目文档，支持 Markdown、PDF、Word `.doc/.docx`

优先级：P0

### 5.2.4 经历管理

支持：

- 创建经历
- 编辑经历
- 删除经历
- 发布 / 隐藏经历

优先级：P0

### 5.2.5 技能管理

支持：

- 创建技能
- 编辑技能
- 删除技能
- 按分类展示技能

优先级：P0

### 5.2.6 定制简历页管理

支持：

- 创建定制简历页
- 编辑定制简历页
- 删除定制简历页
- 发布 / 隐藏页面
- 选择关联项目
- 选择关联经历
- 选择关联技能
- 自动生成管理员预览路径
- 自动生成 HR 专属分享 token
- 复制 HR 专属分享链接
- 查看 HR 视图

优先级：P0

### 5.2.7 文件上传

MVP 阶段支持上传文件到项目目录 `public/uploads/`，Docker 中通过绑定挂载持久化。

可用于：

- 普通项目文档
- 效果演示文档
- 微信二维码图片
- 后续项目封面、项目截图、个人头像

优先级：P1

## 6. 非功能需求

### 6.1 部署

系统必须支持 Docker Compose 部署。

MVP 至少包含：

- app 服务
- SQLite 文件数据库

### 6.2 数据持久化

SQLite 数据库文件必须持久化到项目目录 `data/`。

上传文件后续如使用本地存储，也必须持久化到项目目录 `public/uploads/`。

### 6.3 响应式

前台页面必须适配：

- 桌面端
- 平板
- 手机

后台优先适配桌面端，移动端可后续优化。

### 6.4 SEO

前台公开页面应支持基础 SEO：

- title
- description
- Open Graph 信息，后续增强

### 6.5 安全

- 管理后台需要登录保护。
- 密码不能明文存储。
- 敏感配置通过环境变量注入。
- HR 专属链接应使用不可猜测的随机 token，不能使用简单自增 ID。
- `.env` 不提交到仓库。

## 7. 数据实体

MVP 核心实体：

- AdminUser
- Profile
- Project
- Experience
- Skill
- ResumePage
- ResumePageShareToken，或作为 ResumePage 字段实现

后续实体：

- ProjectDocument
- UploadFile
- PageView
- ResumePdf

## 8. MVP 范围

### 8.1 包含

- Docker Compose 启动 app，SQLite 文件通过 `./data:/app/data` 绑定挂载持久化
- 管理员登录
- Profile 管理
- Project 管理
- Experience 管理
- Skill 管理
- ResumePage 管理
- 首页
- 作品列表页
- 独立作品集展示页
- 作品详情页
- 通用简历页
- 定制简历页
- 定制页分享 token
- 管理员预览地址
- HR 专属分享链接
- 项目文档上传、在线预览和原始文档下载
- 效果演示文档单独上传和展示
- 作品详情页模块展示开关
- 独立作品集展示页 `/portfolio`

### 8.2 不包含

MVP 暂不包含：

- 复杂权限系统
- 多用户协作
- 访问统计
- PDF 在线生成
- 访问码保护
- 多语言
- 对象存储
- 自动备份

这些功能可以在 MVP 稳定后逐步加入。


## 9. 当前前端 Mock 原型

当前已在 `webMock/` 中实现前端原型，用于确认视觉风格和核心流程。

已实现页面：

- 首页
- 作品列表页
- 独立作品集展示页
- 作品详情页
- 通用简历页
- 联系页
- 管理员登录 Mock
- 后台管理 Mock
- 定制页管理 Mock
- HR 专属定制页访问 Mock

当前 Mock 规则：

- 所有数据来自 `webMock/src/mockData.ts`。
- `webMock/` 中管理员登录状态暂存在浏览器 `localStorage`。
- 正式程序中管理员登录使用服务端 HTTP-only Cookie 会话。
- `/for/:companySlug/:positionSlug` 作为管理员预览地址，未登录不可看。
- `/r/:shareToken` 作为 HR 专属访问地址。
- HR 视图不展示站点导航和其他定制页入口。

## 10. 成功指标

MVP 成功标准：

- 可以通过 Docker Compose 一键启动。
- 管理员可以在后台录入和管理核心内容。
- 可以创建至少一个公司 / 岗位定制简历页。
- 定制简历页可以通过 HR 专属链接访问。
- 作品集可以作为统一入口分享。

## 11. 当前正式程序实现状态

当前正式程序已完成 MVP 功能闭环。

已完成：

- Next.js 正式应用初始化。
- 前台页面迁移到 `src/app`。
- 服务端管理员登录和 HTTP-only Cookie 会话。
- 后台页面服务端登录保护。
- 定制页管理。
- `/for/:companySlug/:positionSlug` 管理员预览，已接入服务端登录保护。
- `/r/:shareToken` HR 专属访问。
- SQLite schema 和初始化逻辑。
- Dockerfile。
- `docker-compose.yml`，包含 app、SQLite 数据目录和上传文件目录绑定挂载。
- `.env.example`。
- 后台 Profile / Project / Experience / Skill / ResumePage CRUD。
- 项目普通文档与效果演示文档分开上传、分开管理、分开展示。
- Markdown / PDF / Word `.doc/.docx` 文档在线预览，Word 通过 LibreOffice 转 PDF。
- 作品详情页模块展示开关
- 独立作品集展示页 `/portfolio`、专用作品详情页 `/portfolio/:slug` 与专用文档预览页 `/portfolio/:slug/docs`。
- 软删除和回收站。
- HR 联系方式卡片和微信二维码展示。

已知后续增强：

- 访问统计。
- PDF 简历下载。
- 访问码保护。


## 12. 软删除和回收站

作品、经历和定制简历页删除时不做物理删除，而是进入后台回收站。

要求：

- 删除后的内容不在前台页面展示。
- 删除后的内容不在对应管理列表中展示。
- 管理员可以在 `/admin/recycle-bin` 查看已删除内容。
- 管理员可以从回收站恢复作品、经历和定制简历页。
- 恢复后内容回到原管理列表，并按原发布状态参与前台展示。


## 13. 作品文档上传

作品管理需要支持上传项目文档，并区分普通项目文档和效果演示文档。

要求：

- 管理员可以在作品管理页面为具体作品上传多个文档。
- 上传文档需要保留原始文件名。
- 普通项目文档与效果演示文档需要分开上传、分开管理、分开展示。
- 上传 Markdown、PDF、Word `.doc/.docx` 后，作品详情页提供在线查看入口。
- 在线查看页面使用 `/projects/:slug/docs?doc=<documentId>`。
- Word `.doc/.docx` 文档通过 LibreOffice 转 PDF 后预览，保留原始文档下载。
- 原始文档下载使用 `/projects/:slug/docs/download?doc=<documentId>`，响应头需要包含 `Content-Disposition: attachment` 以触发浏览器下载。
- 已上传文件可以在作品管理页删除；删除后不在作品详情页和后台文档列表展示。
- 已上传文件保存在 Docker 持久化上传目录中。


## 14. Markdown 阅读体验优化

Markdown 在线查看需要具备较好的阅读体验，至少支持：

- 标题层级
- 段落
- 有序和无序列表
- 代码块
- 表格
- 引用
- 图片
- 链接

定制简历页中的项目卡片需要可以打开对应作品详情，方便 HR 继续查看项目文档和完整项目介绍。


## 15. HR 联系信息展示

后台个人资料需要支持维护手机号、微信号和微信二维码。HR 打开的定制简历页需要展示完整联系方式，包括邮箱、手机号、微信号、所在地和微信二维码，便于 HR 快速联系候选人。联系方式模块需要与现有卡片风格统一；微信二维码必须完整显示，不得裁剪；HR 页面底部不再重复展示旧联系方式模块。


## 16. 作品效果演示与模块展示配置

作品详情页需要支持按作品配置模块展示状态。管理员可以控制以下模块是否对访客展示：

- 项目介绍
- 我的职责
- 效果演示
- 项目亮点
- 技术栈
- 相关链接/文档

效果演示模块需要支持：

- 视频链接或可直接播放的视频文件链接。
- 单独上传效果演示文档。
- 演示标题和演示说明。
- 与普通项目文档分开存储和展示。


## 17. AGENTS.md 要求模块对照

本 PRD 与项目规范要求的模块对应如下：

### 项目概述

对应本文档的“背景”“产品目标”和“当前正式程序实现状态”。

### 目标与范围

对应“产品目标”和“MVP 范围”。

### 用户与角色

对应“用户角色”。

### 业务流程

对应“核心场景”，包括作品展示、通用简历展示和定制化投递。

### 功能需求

对应“功能需求”以及后续软删除、作品文档上传、效果演示等补充需求。

### 页面与交互

对应前台功能、后台功能、当前前端 Mock 原型和当前正式程序实现状态。

### 数据模型

对应“数据实体”，详细字段见 `DatabaseSchema.md`。

### 接口定义

主要通过 Next.js 路由和 Server Actions 实现；公开路由包括 `/projects/:slug/docs`、`/projects/:slug/docs/preview`、`/projects/:slug/docs/download`、`/r/:shareToken`。

### 业务规则

对应定制页访问约束、HR token 规则、软删除规则、文档分类规则和模块展示开关规则。

### 非功能要求

对应“非功能需求”，包括部署、数据持久化、响应式、SEO 和安全。

### 验收标准

对应“MVP 范围”“成功指标”和各功能小节中的要求。

### 技术与实现约束

对应 Docker Compose、SQLite、环境变量、HTTP-only Cookie、LibreOffice 文档转换和项目目录绑定挂载文件存储约束。

## 18. Wiki 知识库展示

Wiki 模块读取通过 Docker 挂载的 Obsidian vault，并在 `/wiki` 和 `/wiki/:slug` 中展示。

需求：

- 默认仅管理员可访问，可通过 `WIKI_PUBLIC=true` 开启公开访问。
- 左侧展示文件树，目录默认收起，可点击展开或收起。
- 中间展示 Markdown 内容。
- 右侧展示可拖拽动态局部关系图谱、反向链接和出链。
- 支持 Obsidian 双链 `[[note]]` 和 `[[note|显示名称]]`。
- vault 路径、公开状态、忽略目录必须支持环境变量配置；管理员在后台 `/admin/wiki` 页面可以点击“知识库根目录路径”后用弹窗逐级浏览服务器目录并选择 vault 路径，并通过选项维护公开状态和忽略目录，避免手动输入路径或逗号配置；页面配置优先级高于环境变量，选择“不忽略任何目录”时必须生效，并在 `.env` 存在且可写时同步更新 `WIKI_VAULT_PATH`、`WIKI_HOST_VAULT_PATH`、`WIKI_EXCLUDE_DIRS`、`WIKI_PUBLIC`。
- 管理员可以在后台直接上传 Markdown 文档到知识库目录，文件名保持不变，同名文件允许覆盖。上传目标目录必须从当前知识库已有目录中选择，默认可选择根目录。
