# PJ2026-04 求职工作台需求规格

## 1. 文档控制

| 字段 | 内容 |
| --- | --- |
| 编号 | PJ2026-04 |
| 短名 | 求职工作台 |
| 层级 | L1 项目 |
| 状态 | 已生效 |
| 需求规格模板 | [ISO/IEC/IEEE 29148 需求规格模板](../../templates/iso-iec-ieee-29148-requirements-spec-template.md) |

## 2. 目的和范围

### 2.1 目的

求职工作台负责把候选单位、招聘渠道、账号、材料、岗位申请和需要本人参与的事项投影到统一 Web 入口，使求职执行状态可扫描、可扩展并能在验证码或资料缺口出现时及时获得本人输入。

### 2.2 范围内

- 高校、企业、研究机构和其他单位的统一状态模型。
- 账号、简历、岗位和申请状态投影。
- 图形验证码、短信验证码、真人校验、资料补充和提交确认等人工事项。
- 统一管理员密码认证、HTTPS 公开入口和受控会话。
- 招聘账号密码在 host PostgreSQL 中按单位明文保存、生成、查看和复制。
- Vite 前端与 Bun API 的 native 热重载开发形态。
- 声明式业务状态、本地私密运行状态和外部表单工作流的边界。

### 2.3 范围外

- 招聘单位外部系统的可用性和数据正确性。
- 绕过图形、短信、滑块或其他真人验证。
- 未经本人确认最终提交限报或提交后不可修改的岗位。
- 把身份证、密码、验证码、Cookie 或本人补充的敏感答案写入 Git。

## 3. 术语

| 术语 | 定义 |
| --- | --- |
| 单位 | 高校、企业、研究机构或其他招聘主体。 |
| 招聘渠道 | 单位招聘系统、学院邮箱、第三方平台或线下联系人。 |
| 人工事项 | 自动流程需要本人查看、填写或确认后才能继续的任务。 |
| 业务状态 | 可提交到私有仓库的单位、材料和申请公开状态。 |
| 私密运行状态 | 工作流 ID、验证码 artifact、本人答案和其他不得提交的临时状态。 |
| 招聘密码库 | 在 host PostgreSQL 独立数据库中按单位保存招聘账号和明文密码的私密状态。 |

## 4. 系统边界

| 边界项 | 内容 |
| --- | --- |
| 外部使用者 | 求职者本人和受托执行 Agent。 |
| 外部输入 | 单位声明、招聘入口、申请状态、验证码、本人资料和确认结果。 |
| 外部输出 | 状态总览、人工事项、材料清单和操作结果摘要。 |
| 受控资源 | 统一密码来源、招聘工作流、验证码 artifact、本地私密状态和 HTTPS 入口。 |
| 用户接口 | `findjob.hwpod.com` Web 入口和项目 CLI。 |

## 5. 架构

```mermaid
flowchart LR
  Career[单位与申请 YAML] --> API[Bun API]
  Tasks[本地人工事项] --> API
  Secret[统一密码 sourceRef] --> API
  Vault[host PostgreSQL 明文招聘密码库] <--> API
  Workflow[外部表单工作流] <--> API
  API --> Vite[Vite Web 工作台]
  Vite --> Edge[HTTPS 公共边缘]
  Edge --> User[求职者]
```

- 业务状态由求职仓库声明式数据拥有。
- 端口、启动命令、状态路径和认证来源由求职仓库 `config.json` 拥有。
- 公共域名、TLS upstream 和 health path 由 UniDesk public exposure YAML 拥有。
- 私密运行状态只保存在求职仓库 `.state/`。
- 招聘密码库使用受控 Secret sourceRef 连接 host PostgreSQL，不维护第二个主密码。
- 招聘密码明文只在已认证会话的单条显式查看请求中返回。

## 6. 原子需求

### 6.1 FJ-REQ-001 统一状态总览

工作台应在首屏展示全部单位数量、已注册数量、待本人处理数量和可用材料数量，并以表格展示每个单位的账号、简历和申请状态。

### 6.2 FJ-REQ-002 可扩展单位模型

工作台应让高校、企业、研究机构和其他单位共用同一数据结构、筛选器和状态渲染。新增单位不应要求新增专用页面分支。

### 6.3 FJ-REQ-003 人工事项

工作台应把验证码、短信、真人校验、缺失资料、限报决策和提交确认表示为独立人工事项。人工事项应包含所属单位、说明、输入合同和处理状态。

### 6.4 FJ-REQ-004 外部表单续填

图形验证码事项应展示当前受控 artifact，并把本人输入经标准输入传给已声明的外部表单工作流。验证码值不得进入 URL、命令参数、日志、Git 或持久响应记录。

### 6.5 FJ-REQ-005 认证和隐私

工作台应使用统一管理员密码来源认证。正式 HTTPS 入口使用 `Secure`、`HttpOnly` 和 `SameSite=Strict` 会话 Cookie；公共入口故障期间的固定 HTTP 降级入口保留 `HttpOnly` 和 `SameSite=Strict` 并显示传输降级警告。API 未认证时不得返回求职状态、材料路径或人工事项。

### 6.6 FJ-REQ-006 热重载

native 开发应同时保持前端 HMR 和 API 文件监听热重载。服务端口和生命周期应由项目配置和项目 CLI 固定管理。

### 6.7 FJ-REQ-007 公开入口

正式用户入口应为 YAML 声明的 HTTPS 域名。公共边缘应把该域名代理到固定前端端口，并通过同源 `/api` 到达 API 服务。

### 6.8 FJ-REQ-008 提交边界

账号注册可在本人授权和验证码完成后执行。每人限报一个、提交后不可修改或其他高影响岗位申请只能保存草稿，最终提交前必须生成人工确认事项。

### 6.9 FJ-REQ-009 招聘密码库

工作台应为每个单位管理独立招聘账号和密码，并满足以下要求：

- 使用密码学安全随机源生成符合指定长度的密码。
- 密码库使用 host PostgreSQL 独立数据库和最小权限角色。
- `password_plaintext` 字段直接保存招聘密码明文，不进行应用层或字段级加密。
- 数据库连接参数只从受控 Secret sourceRef 读取，不写入仓库。
- 单位列表和密码库摘要只返回账号、密码是否存在和更新时间，不返回密码明文。
- 查看或复制密码必须由已认证用户对单个单位显式触发。
- 前端不得把全部密码预加载到页面状态。
- API、CLI、日志、TaskTree、Git 和错误响应不得打印密码明文。
- 更新密码时应覆盖该单位的当前明文记录，不保留可由普通接口读取的历史密码。
- 外部招聘表单需要密码时，应按单位把当前账号和密码物化到 `.state/` 下权限为
  `0600` 的临时 Secret 文件；表单完成 Secret 注入后应立即清除该文件。
- 临时 Secret 物化和清除命令只返回单位 ID、文件 presence 与路径，不返回账号或
  密码值；PostgreSQL 仍为招聘密码的唯一长期事实源。

### 6.10 FJ-REQ-010 人工事项操作说明

人工事项详情应提供可由本人独立执行的结构化操作说明，而不是只展示结果输入框。
说明合同应支持以下可选字段：

- `reason`：必须本人处理的原因。
- `operationUrl`：办理事项的官方入口或必要的邮件入口。
- `prerequisites`：开始操作前需要准备或确认的内容。
- `steps`：按顺序执行的具体步骤。
- `completionEvidence`：判断事项已完成的页面状态或其他证据。
- `troubleshooting`：常见失败及对应处理方法。
- `resultPrompt`：完成后需要回填给 Agent 的信息。

工作台应先展示操作入口和说明，再在详情底部展示结果输入区。说明不得包含密码、
身份证号、验证码或其他敏感值，也不得向前端披露内部工作流路径和 ID。涉及限报、
提交后不可修改或正式投递的事项，应明确要求本人停在最终提交前确认。

## 7. 验收契约

- 未登录打开正式 HTTPS 入口时只显示登录界面。
- 正确统一密码登录后能看到单位状态、材料和人工事项。
- 新增一条企业声明后，无需修改前端即可出现在企业筛选结果中。
- 图形验证码事项能显示受控图片并把值传入对应工作流，页面和日志不回显验证码。
- 修改前端源码后 HMR 连接保持可用，修改 API 源码后服务自动重载。
- 桌面和移动视口均无文本重叠、横向页面溢出或操作按钮不可达。
- 正确登录后能为单个单位生成、查看和复制招聘密码。
- 未登录请求、单位列表请求和密码库摘要请求均不能取得密码明文。
- Git diff、CLI、日志和 TaskTree 中不出现招聘密码明文。
- 按单位物化的临时 Secret 能被声明式外部表单读取，并能在注入后通过受控命令清除。
- 人工事项详情能展示办理入口、本人处理原因、步骤、完成标准、异常处理和结果回填
  提示，结果输入区位于说明之后。
- 人工事项在移动视口内无横向溢出，外部办理入口和关闭操作均可达。
