# 岗位

Version: 829db5245701f2f8

模块地址：https://dev.planahr.top/api/v1/job-library/tools；权限 jobs:read / jobs:write。写权限不包含读权限，均不扩大用户自身权限。

操作名：companies、search、detail、create、update、documents。工具名称前缀 job_library_ 不用于 POST 的 operation。

GET 加 ?operation=操作名 只取单项 schema；?view=summary 只取目录。POST 不带查询参数，使用 {operation,input} 和 Content-Type: application/json。

```bash
curl 'https://dev.planahr.top/api/v1/job-library/tools?operation=companies' \
  -H "Authorization: Bearer $ACCESS_TOKEN"
```

- 先查客户公司，使用真实 client_id；维护岗位不改变候选人流程的负责人。暂停/关闭没有 job_library_close 工具，应按 hiring 文档先读 jobImpact，再调用 jobState。
- 岗位原“负责人”现称“岗位客户经理”，与公司客户经理可以不同，也不等于创建人。兼容字段 owner_id / owner_name 及 access.role=owner 表示岗位客户经理；转交仍调用 hiring.jobAssign，使用 context 的 membership ID，不修改创建人或流程负责人。
- 详情中的 created_by / creator_name / creator_source 是只读创建人记录。created 表示创建时自动记录登录人；creation_history 表示依据原始创建日志；manager_backfill 表示用户确认按补填时的岗位客户经理登记，不代表考证的原始创建人。转交客户经理不改变创建人，也不因创建人字段增加权限。
- 岗位 create/update.data.salary_range 为可空结构化薪资范围：min/max 为实际金额，currency 为三位币种，period 为 month/year，可选 months、basis（gross/net/unknown）、negotiable。省略保留原值，null清除，不从JD猜薪资，不把30k字符串当金额。
- 公司/岗位附件：documents({id,page?,pageSize?}) 只列分页元数据，需本模块 :read + sensitive:documents，同组织可读取且按用户审计。GET tools?operation=documents 的 binaryUpload 提供上传/下载地址与限制。POST /api/v1/job-library/{id}/documents 用 multipart/form-data，仅 file、version、requestId 三个字段，需本模块 :write 及原对象编辑权限；不是 JSON 工具，不传 Base64。先保存公司/岗位，再上传；默认每份 20 MiB，支持 PDF/Word/Excel/PowerPoint/PNG/JPEG。每次追加独立附件，不覆盖旧文件；原件不自动转成JD或正文。GET 同路径 /{documentId}?download=1 下载原件（相同 Bearer，需 :read + sensitive:documents）；download=0 可预览 PDF/图片。上传回执返回新版 version，重试保留原 version/requestId/文件名/内容；409 VERSION_CONFLICT 先读新版本，再用新请求 ID。上传人由登录身份确定，不能自报。文件字节不进入模型上下文，只有按需下载的外部文件。
- Office 附件上传成功后后台生成 PDF，列表的 preview.status 为 queued/converting/ready/failed/evicted；原件始终由 download=1 下载，ready 时 download=0 返回 PDF。PDF/图片直接预览，不生成副本。上传回执的状态是当时快照，后续以 documents 列表为准；不要重传原件来催转换，也不要高速轮询。失败原因在 preview.errorCode/message；用户要求重试且 retryAvailable=true 时，按 binaryUpload.previewRetry 用同一 Bearer POST /{documentId}/preview，JSON {}，需本模块 :read + sensitive:documents，不需要编辑权。202 表示已排队；只重建衍生 PDF，不修改附件或资料版本。文件字节不进入 JSON，不将加密或损坏文件误报成上传失败。
- 网页“批量管理/调整招聘状态”复用逐岗位 hiring.jobState，支持 open/paused/closed，没有新批量 API。Agent 也须分别读 jobImpact、取得当前 version/impactToken；暂停或关闭要确认流程及已发 Offer 处置，开放不会自动恢复原先暂停/结束的流程。每岗位使用独立稳定 requestId。整批非原子事务；出错停止后续提交，逐项报告已完成/失败/未处理。响应丢失先用原始请求核对，不换 requestId 重复操作。

以下仅为虚构模板；ID、version 必须从真实读取结果取得，写入 requestId 为每个逻辑动作生成且重试保持不变。

### 查询开放的岗位（只读）

POST /api/v1/job-library/tools

```json
{
  "operation": "search",
  "input": {
    "status": "open",
    "page": 1,
    "pageSize": 20
  }
}
```
