@lark-people/cli 0.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/CHANGELOG.md +324 -0
  2. package/LICENSE +21 -0
  3. package/README.md +232 -0
  4. package/README.zh.md +232 -0
  5. package/bin/people-cli_darwin_amd64 +0 -0
  6. package/bin/people-cli_darwin_arm64 +0 -0
  7. package/bin/people-cli_linux_amd64 +0 -0
  8. package/bin/people-cli_linux_arm64 +0 -0
  9. package/bin/people-cli_windows_amd64.exe +0 -0
  10. package/bin/people-cli_windows_arm64.exe +0 -0
  11. package/package.json +41 -0
  12. package/scripts/install-wizard.js +700 -0
  13. package/scripts/install.js +56 -0
  14. package/scripts/run.js +36 -0
  15. package/skills/people-attendance/SKILL.md +667 -0
  16. package/skills/people-attendance/references/people-attendance-submission.md +426 -0
  17. package/skills/people-attendance/scripts/resolve_date.py +894 -0
  18. package/skills/people-corehr/references/people-corehr-pre-hire-search.md +0 -0
  19. package/skills/people-corehr-employee/SKILL.md +111 -0
  20. package/skills/people-corehr-employee/references/people-corehr-employee-basic-info-query.md +97 -0
  21. package/skills/people-corehr-employee/references/people-corehr-employee-fields-list.md +87 -0
  22. package/skills/people-corehr-employee/references/people-corehr-employee-filter.md +403 -0
  23. package/skills/people-corehr-employee/references/people-corehr-employee-search.md +73 -0
  24. package/skills/people-corehr-job-change/SKILL.md +212 -0
  25. package/skills/people-corehr-job-change/references/people-job-change-business-rules.md +113 -0
  26. package/skills/people-corehr-job-change/references/people-job-change-lookup-filters.md +82 -0
  27. package/skills/people-corehr-job-change/references/people-job-change-output-and-empty.md +207 -0
  28. package/skills/people-corehr-job-change/references/people-job-change-search-advanced.md +226 -0
  29. package/skills/people-corehr-job-change/references/people-job-change-search-fields.md +119 -0
  30. package/skills/people-corehr-job-change/references/people-job-change-search-option.md +72 -0
  31. package/skills/people-corehr-job-change/references/people-job-change-search.md +215 -0
  32. package/skills/people-corehr-offboarding/SKILL.md +188 -0
  33. package/skills/people-corehr-offboarding/references/people-corehr-offboarding-business-knowledge.md +27 -0
  34. package/skills/people-corehr-offboarding/references/people-corehr-offboarding-search-option.md +187 -0
  35. package/skills/people-corehr-offboarding/references/people-corehr-offboarding-search.md +54 -0
  36. package/skills/people-corehr-organization/SKILL.md +42 -0
  37. package/skills/people-corehr-organization/references/aggregate.md +11 -0
  38. package/skills/people-corehr-organization/references/detail.md +39 -0
  39. package/skills/people-corehr-organization/references/field-values.md +44 -0
  40. package/skills/people-corehr-organization/references/hierarchy.md +61 -0
  41. package/skills/people-corehr-organization/references/lookup.md +41 -0
  42. package/skills/people-corehr-organization/references/metadata.md +40 -0
  43. package/skills/people-corehr-organization/references/tree.md +45 -0
  44. package/skills/people-corehr-prehire/SKILL.md +160 -0
  45. package/skills/people-corehr-prehire/references/command-resolution.md +48 -0
  46. package/skills/people-corehr-prehire/references/filter-fields.md +151 -0
  47. package/skills/people-corehr-prehire/references/return-fields.md +153 -0
  48. package/skills/people-corehr-prehire/references/templates.md +202 -0
  49. package/skills/people-corehr-prehire/references/troubleshooting.md +93 -0
  50. package/skills/people-corehr-query-id-by-name/SKILL.md +154 -0
  51. package/skills/people-corehr-renewal/SKILL.md +186 -0
  52. package/skills/people-corehr-renewal/references/people-corehr-renewal-fields-query.md +62 -0
  53. package/skills/people-corehr-renewal/references/people-corehr-renewal-routing.md +54 -0
  54. package/skills/people-corehr-renewal/references/people-corehr-renewal-search.md +137 -0
  55. package/skills/people-corehr-renewal/references/people-corehr-renewal.md +39 -0
  56. package/skills/people-corehr-workforce-plan/SKILL.md +52 -0
  57. package/skills/people-corehr-workforce-plan/references/people-corehr-workforce-plan-detail-list.md +238 -0
  58. package/skills/people-corehr-workforce-plan/references/people-corehr-workforce-plan-detail-summary.md +221 -0
  59. package/skills/people-corehr-workforce-plan/references/people-corehr-workforce-plan.md +79 -0
  60. package/skills/people-hire/SKILL.md +255 -0
  61. package/skills/people-hire/references/people-hire-application.md +334 -0
  62. package/skills/people-hire/references/people-hire-evaluation-task-list.md +233 -0
  63. package/skills/people-hire/references/people-hire-evaluation.md +127 -0
  64. package/skills/people-hire/references/people-hire-interview-record.md +109 -0
  65. package/skills/people-hire/references/people-hire-interview-task-list.md +250 -0
  66. package/skills/people-hire/references/people-hire-interview.md +146 -0
  67. package/skills/people-hire/references/people-hire-job-process.md +93 -0
  68. package/skills/people-hire/references/people-hire-job-requirement.md +227 -0
  69. package/skills/people-hire/references/people-hire-job.md +277 -0
  70. package/skills/people-hire/references/people-hire-minutes.md +91 -0
  71. package/skills/people-hire/references/people-hire-talent.md +105 -0
  72. package/skills/people-hire/references/people-hire-test.md +197 -0
  73. package/skills/people-overtime/SKILL.md +992 -0
  74. package/skills/people-overtime/references/people-attendance-overtime-apply.md +491 -0
  75. package/skills/people-overtime/references/people-attendance-overtime.md +51 -0
  76. package/skills/people-overtime/references/people-attendance-submission.md +203 -0
  77. package/skills/people-overtime/scripts/resolve_date.py +894 -0
  78. package/skills/people-shared/SKILL.md +94 -0
@@ -0,0 +1,207 @@
1
+ # people-job-change-output-and-empty
2
+
3
+ 输出格式、空结果、拒答模板与校验清单。
4
+
5
+ > 前置条件:先阅读 [`../SKILL.md`](../SKILL.md)。
6
+
7
+ ## 输出格式
8
+
9
+ 最终输出必须是纯答案正文或结构化文本:
10
+ - 禁止使用 markdown 代码块包裹。
11
+ - 禁止输出评测元信息、runner 包装字段、trace、耗时、record_id、JSON 外壳。
12
+ - 禁止向用户输出 API 字段名、JSON path、filter/select 字段、enum value、lookup 字段、内部 ID 或命令参数片段;最终答案只能使用业务展示名和业务口径,例如写"异动后部门/已生效/工号/异动变更内容",不要写 `target_department`、`Transformed`、`employment.employee_number`、`details_of_job_status_change`。
13
+ - 禁止输出推理过程、执行计划、推荐命令、等效 HTTP/Postman/Bitable 调用或“现在执行...”类中间状态。
14
+ - 异动记录查询必须真实执行 `people-cli corehr +job-change-search ... --format json --as user`,再基于 CLI 返回结果、分页聚合结果或必需解析失败回答。
15
+ - 最终回答前,命令链必须包含真实 `+job-change-search` 或等价真实搜索;若只有 `search-option` / `--help` / `schema`,禁止输出业务答案,只能继续搜索或输出必需解析不可完成原因。
16
+ - 若最终搜索尚未执行,只有在必需 lookup / enum / option 解析失败时才能回答;此时必须使用不可用结果模板,不能输出“下一步将查询”。
17
+ - 若最终搜索已经执行,最终答案必须只基于最后一次 `+job-change-search` 的结果生成;旧的计划、探索、解析说明不能作为最终答案。
18
+ - 收口优先级高于字段完美度:只要最后一次搜索返回合法 `data.total` 和 `data.items`,必须立即组织答案;用户未明确要求的缺失字段写“未返回”,禁止为了补齐字段继续 `search-option/help/schema/脚本解析` 到超时。
19
+ - 若本轮没有成功的真实搜索结果,禁止输出具体人数、姓名、工号、部门、日期;只能继续执行搜索或输出运行时解析/搜索失败模板。
20
+ - 若模型准备输出空文本、过程句、命令计划或“搜索成功待聚合”,必须改为最终结论;无法形成结论时输出不可完成原因,不能让最终答案为空。
21
+ - 目标侧变更查询一旦完成运行时校准并执行最终搜索,必须立即输出数量和明细;不要继续尝试同义词、英文名、`--help`、宽搜样本或本地 original/target 验证。只有用户明确"从 X 到 Y"或要求复杂统计时,才做有界后处理。
22
+ - 搜索后允许按用户目标做分页、聚合、去重或轻量格式化;但分页只能使用返回的 `page_token`。用户未明确要求翻页/全部/完整列表/继续翻页时,不翻页,只返回当前页并说明 `total`、`has_more`、`page_size` 和本页数量。问“有哪些/都去了哪些/汇总/统计/数量/分组”等全量才准确问题时,最多先处理前 200 条;若仍有更多,说明这是部分统计,不代表全量,并询问是否继续。
23
+ - CLI 结果按 `--format json` 的固定对象读取,只读取 `data.items[]`、`data.has_more`、`data.page_token`、`data.total`;答案中的“总数/共有/一共”只能来自 `data.total`。禁止把本页数量当总数,禁止把样例数量、已聚合数量或前 200 条部分结果写成全量总数;不要判断 NDJSON/多 JSON,不要用 `grep`/`head` 截取 search 结果。若 JSON 形态不符合固定对象、`has_more=true` 但缺 `page_token`、任一页失败或分页解析失败,输出结构化不可完成原因,不要调 help/schema、写临时脚本或继续重试到超时。
24
+ - 最终答案必须包含以下之一:`data.total` 总数 + 本次返回/已聚合记录数量 + 关键记录摘要、没有符合条件的记录 + 已执行查询条件、必需 lookup / enum / option 解析失败 + 失败条件、搜索失败 + 错误类别。若接口未返回 `data.total`,必须写“接口未返回总数”,只能说明本页数量或已聚合数量。非空查询若用户问“有没有/有哪些/哪些单据/具体记录”,默认展示当前页全部记录明细(默认 `page_size=10`);不能只给统计表。
25
+ - 最终 search 的输出必须保留原始 `items`。默认不要加 `--jq`;若为了稳定展示 `total/has_more/page_token` 使用 `--jq`,必须同时返回完整 `items:.data.items`,不能只返回元信息、统计分组或裁剪后的少数字段。`total>0` 但没有可读原始 `items` 时,不能回答“只查到总数”;应把该结果视为被投影破坏,使用同一筛选条件重新搜索一次并保留原始 `items`。只有重搜失败或工具输出截断且无法可靠读取记录明细时,才说明无法列出明细。
26
+ - Bash 命令只能包含可执行 CLI 及其参数;若混入自然语言、shell syntax error、unknown flag、校验失败或命令污染,必须按运行时搜索失败/解析失败输出,禁止继续生成业务答案。
27
+ - 若工具输出被 persisted/truncated:优先从可见的固定 JSON 中读取 `data.total/has_more/items`;只要能可靠读取到完整当前页 `items`,就默认展示当前页全部记录明细。若只能可靠读取部分 `items`,展示已可靠读取的记录并提示“输出较大,本次仅展示可可靠读取的记录,完整数据需继续分页/缩小范围”。禁止只抽取总数后丢弃 `items`。若无法可靠读取固定 JSON 或任何完整记录,才说明输出被截断、无法可靠列出明细;禁止基于零散预览补全名单、字段或统计。
28
+ - 多分支/交集/分组类问题完成搜索后,最终答案必须同时包含:已执行的筛选条件、每个分支的 `data.total`、交集或分组结果(命中数量与代表记录)、完整性说明(`has_more`/部分口径)。某分支 `data.total=0` 时可显式输出"0 条";交集为空但任一分支仍有更多时,禁止输出"全量 0 条",只能说明当前已返回范围内 0 条且不能确认全量为空。禁止输出空答案、过程性结尾或"待聚合/将合并"等中间表述。
29
+ - 异动详情基础展示字段强制契约:凡最终答案展示任意异动记录明细,必须逐条展示姓名、工号、头像、生效日期、异动类型、异动状态。用户额外要求的业务字段只能追加,不能替代这 6 个基础字段;字段在原始 `items` 中存在就必须展示,确实缺失或无权限时写"未返回/无权限",禁止省略列、禁止用 ID 替代工号。纯统计且不列记录明细时不适用;只要列代表记录/样例/当前页明细就适用。
30
+ - 用户未明确指定返回字段时,默认展示姓名、工号、头像、生效日期、异动类型、状态;姓名可从 `employment_name` 或 `person.preferred_name` 读取,工号可从嵌套的 `employment.employee_number` 读取。
31
+ - 用户问题中提到某个返回字段或信息点时必须展示该字段,即使没有说"展示/返回"。例如问"异动内容是什么/他们的异动内容"时,结果必须包含 `details_of_job_status_change` 或运行时展示名"异动变更内容";默认结果未返回时,补合法返回字段重新搜索。
32
+ - 用户问"异常类型"时必须展示运行时异常类型字段;若字段未返回,写"异常类型未返回/无法确认",禁止把异常处理状态、异动状态或异动变更内容列当异常类型。
33
+ - 复杂变更明细默认补齐员工工号、中文状态、异动类型末级名、异动原因末级名、异动变更内容、用户提到字段的原/新值;字段未返回写“未返回”,不要展示 employment_id/person_id 冒充工号。
34
+ - 多字段变化标注明细必须逐项输出用户点名维度,至少包含原值、新值、是否变化;常见维度包括职务、序列、职级、人员类型、工作地点。若用户要求异动原因和是否调薪,必须展示运行时原因字段与 `is_adjust_salary`,缺失时写"未返回",不能整列省略。
35
+ - 合同/试用期/司龄/协议标签类输出必须包含运行时可返回的原/新字段:合同公司、合同类型、合同编号、开始/预计结束日期、签订/期限类型;试用期预计结束日期;"异动后有新试用期"必须包含"是否有试用期"并仅 true 算命中;司龄起算日期;属地协议标签。缺字段时说明缺失。
36
+ - 用户要求展示合同/试用期变更信息时,不能只写"包含合同变更/包含试用期变更";必须展示具体返回值,未返回则逐项写未返回。
37
+ - 简单时间范围查询返回 `has_more=true` 时,若用户未明确要求翻页/全部/完整列表,只展示当前页并说明 `total`/`has_more`/`page_size`。用户明确要求全部时,最多先返回/聚合 200 条后询问是否继续。用户明确要求统计、汇总、分组、数量时,最多先按 `page_token` 有界分页聚合 200 条;仍有更多时必须标注部分统计。
38
+ - 非空结果只能使用 CLI 返回字段渲染人员、日期、部门、地点、状态、类型、原因等;字段缺失时写“未返回”,不得补全。
39
+ - 空结果、能力边界、多匹配澄清使用本文模板。
40
+
41
+ 非空结果建议结构:
42
+ - 查询口径:简述时间、部门/人员、状态、类型/原因等已执行筛选条件。
43
+ - 结果数量:必须优先说明 `data.total` 总数;同时说明本页返回数量或已聚合数量。如 `has_more=true`,说明只展示当前页或继续分页后的合并结果;做过分页聚合时说明已聚合页数/记录数和是否仍有更多。若聚合到 200 条仍有更多,说明当前为前 200 条或本批 200 条的部分口径,并询问是否继续。禁止把本页数量、样例数量或已聚合数量当总数。
44
+ - 记录明细:逐条列出 CLI 返回的关键字段;基础字段为姓名、工号、头像、生效日期、异动类型、状态;用户点名字段追加展示。基础字段缺失时写"未返回/无权限",不要省略或用 ID 替代。
45
+ - 口径说明:仅在发生状态集合选择、部门二级搜索、去重或分页时说明。
46
+
47
+ 最终答案自检:
48
+
49
+ - 多目标 lookup 分组题必须按返回的目标字段分组输出数量和明细;"有没有变化/是否变更"只能作为每条记录的标注后处理,不能把该变更项加成筛选条件,除非用户明确要求"发生变化的记录"。
50
+ - "我管理的部门/我管理范围/我的团队/团队里"是否只用 `--as user` 承载,且没有把该短语当部门名 lookup、没有传当前用户所在部门、没有调用组织/员工接口反查?
51
+ - 若答案包含"现在我需要""先查看""接下来""将执行""现在用""已执行搜索但还要格式化""命令如下""建议执行""我会并行""即将聚合"等过程表达,**不能交付**。复杂聚合/全景题必须直接给出最终结论 + 聚合表 + 数据口径 + has_more/部分口径说明,不能停在"搜索成功,将聚合"。
52
+ - 多状态全景(如"已生效/审批中/已撤销/已拒绝"分别多少)必须**对每个状态分别发起一次** `+job-change-search`,分别记录 `data.total`,再合并;不能用一次无 status 搜索 + 客户端分桶代替。
53
+ - 状态口径是否正确:已生效只包含已生效;未生效包含待生效/审批通过和无需审批/直接异动。不得把 `Approved`、审批通过、无需审批算入已生效。
54
+ - 相对季度是否按自然季度计算:本季度=当前自然季度完整起止日期,上季度=前一个完整自然季度;不得把上季度写成滚动近三个月,也不得出现季度标签和日期范围不一致。
55
+ - 多变更内容"同时/都/并且"发生时,默认只基于各分支当前页做保守交集;"同时变更"数量必须写"当前页交集命中 N 条/已聚合交集 N 条";不得把任一分支或单次多值 OR 的 `data.total` 当成"同时发生"总数。若当前页交集为空但任一分支 `has_more=true`,禁止回答"没有符合条件",只能说明当前已返回记录内未发现交集但不能确认全量为空。
56
+ - "异动到/调到/变更到 X"是否同时使用目标字段和对应变更内容;例如到北京必须是新工作地点北京且异动变更内容包含工作地点。
57
+ - "转为/变为/成为 X"是否按目标侧字段 + 对应变更内容处理;目标值是否只校准一次并立即搜索,没有为证明变化而拉全集本地对比。
58
+ - "按异动类型分类/统计/分组"必须以 `transfer_type_unique_identifier` 的**二级 name**(末级类型名)作为分组 key;不得把所有记录归到一级"异动"或公共父类型。
59
+ - `--lookup-filters` 命中后**禁止**对 `*_department.name` / `*_work_location.name` 做客户端等值/包含二次过滤;不得用"原部门 ≠ 目标部门"剔除同部门内异动。
60
+ - 用户只说"某部门的异动/某部门有哪些异动"且未明确员工当前部门、异动前部门或异动后部门时,最终口径是否说明"本次按异动后部门查询;如需员工当前部门或异动前部门口径需另行说明"?
61
+ - 若 `+job-change-search` 返回非空,改写为记录数量 + 当前页全部记录明细;输出被截断时只展示可可靠读取的完整记录,并说明不是全量明细。凡展示记录明细,是否逐条包含姓名、工号、头像、生效日期、异动类型、异动状态;用户点名字段是否只做追加而未替换基础字段?
62
+ - 非空查询最终答案必须同时包含三类信息:接口返回总数、分页状态(是否还有更多/分页标记是否返回)、异动详细记录。缺任一项都不能交付;若接口未返回总数或分页标记,必须明确写“接口未返回总数/分页标记未返回”。
63
+ - 若答案里出现“总数/共有/一共”,必须确认该数字来自 `data.total`;否则改写为“本页返回 N 条”或“已聚合 N 条”,并说明接口未返回总数。
64
+ - 若用户未明确要求翻页/全部/完整列表/继续翻页,不能自动翻页;改写为当前页数量 + 当前页记录明细 + `total`/`has_more`/`page_size`。
65
+ - 若用户目标需要统计/汇总/分组/数量/有哪些/都去了哪些,最多先按 `page_token` 处理前 200 条;若仍有更多,必须标注部分统计并询问是否继续。若分页失败,输出不可完成原因而不是首屏结论。
66
+ - 若是普通明细类“所有/全部”,最多先返回 200 条;若仍有更多,说明仍有更多分页未展示并询问是否继续。
67
+ - 若最后一次 `+job-change-search` 返回空,改写为空结果模板。
68
+ - 若最后一次 `+job-change-search` 报错,改写为运行时搜索失败模板;不要继续调试、改参重试、查源码/配置/版本或切换二进制路径。
69
+ - 若命令链只有 `search-option`、`help` 或 `schema`,不能交付业务结果;继续执行最终 search,或在必需条件无法解析时输出不可完成原因。
70
+ - 若最终 search 中的 `--lookup-filters` 解析失败,按运行时解析不可用或多匹配澄清模板输出,不要回退到显式名称转 ID。
71
+ - 若未执行最终搜索且必需解析失败,改写为运行时解析不可用模板。
72
+ - 若返回字段不足以回答用户问题,只能基于 `system_columns` 校准后补充合法返回字段重新搜索一次;仍不足时说明缺失字段和已执行查询条件,不得继续试 `--help`、nested path 或改字段名。用户问"为什么/为啥/原因"时按运行时异动原因字段展示,缺失则写未返回。
73
+ - 如果已经得到候选明细并完成计算/分组/交集,下一条 assistant 消息必须是最终答案;不得再开启字段探索。
74
+ - 不展示 option id、内部部门 ID、原始 API 字段名或命令 transcript。
75
+
76
+ ## 空结果模板
77
+
78
+ CLI 返回 `data.items` 为空或 `total=0` 时,使用以下模板之一:
79
+
80
+ 通用空结果:
81
+ ```text
82
+ 查询结果为空。当前没有符合条件的异动记录。
83
+ ```
84
+
85
+ 带筛选条件说明:
86
+ ```text
87
+ 查询结果为空。{时间范围}没有{部门/员工/类型}的{状态}异动记录。
88
+ 如需查看{其他条件}的记录,请补充条件后再查询。
89
+ ```
90
+
91
+ 能力边界拒答:
92
+ ```text
93
+ 无法执行:{具体原因}。people-cli仅支持异动数据的查询和检索,不支持{操作类型}。
94
+ ```
95
+
96
+ 运行时解析不可用:
97
+ ```text
98
+ 无法完成查询:运行时未能解析{条件类型}「{用户输入名称}」或当前用户无权访问该对象。未执行异动记录搜索;请补充更精确的名称、层级路径或其它可唯一定位的信息后再查询。
99
+ ```
100
+
101
+ 运行时搜索失败:
102
+ ```text
103
+ 无法完成查询:异动记录搜索命令执行失败({错误类别})。本次未获得可用的异动记录结果;请稍后重试或补充更精确的查询条件。
104
+ ```
105
+
106
+ 分页不可完成:
107
+ ```text
108
+ 无法完成查询:分页处理失败({缺少page_token/分页请求失败/JSON解析异常})。本次只获得部分异动记录,不能声称已覆盖全部;请稍后重试或缩小查询范围。
109
+ ```
110
+
111
+ 可选条件省略后查询:
112
+ ```text
113
+ 查询口径:已按{已解析条件}执行异动记录搜索;{未解析可选条件}未能通过运行时解析确认,未纳入本次筛选。
114
+ ```
115
+
116
+ ## 空结果正反例
117
+
118
+ 正例:
119
+ - CLI 返回 0 条调出记录:说明当前筛选范围没有已生效调出异动,并提示是否改查调入字段。
120
+ - CLI 返回 0 条某时间范围记录:说明该时间范围内没有符合条件的已生效异动。
121
+ - CLI 返回 0 条某类型记录:说明该时间范围内没有该类型的已生效异动。
122
+
123
+ 反例:
124
+ - CLI 返回 0 条,却编造员工记录。
125
+ - 查询已生效记录为空,未说明口径就直接返回其它状态的统计。
126
+ - 总数为 0,却说“基于首屏样本未找到”。
127
+
128
+ ## 状态空结果处理
129
+
130
+ 普通查询不做同轮状态 fallback。若唯一最终搜索返回空,直接按空结果模板回答。
131
+
132
+ 只有用户明确要求继续扩大状态口径时,才作为新的查询轮次处理;不得在同一最终答案前重新读取状态、改状态集合或发起第二次搜索。
133
+
134
+ ## 能力边界拒答模板
135
+
136
+ | 场景 | 标准拒答话术 |
137
+ |------|-------------|
138
+ | 审批操作 | 无法执行:审批流程操作不属于查询接口的能力范围。people-cli仅支持异动数据的查询和检索,不支持审批流程操作。 |
139
+ | 数据导出 | 无法执行:当前接口不支持数据导出功能。即使拥有导出权限,people-cli也只能查询异动记录并以JSON格式返回结果,无法生成文件。 |
140
+ | 数据修改 | 无法执行:异动记录的修改操作不属于查询接口的能力范围。people-cli仅支持异动数据的查询和检索,不支持修改、删除等写操作。 |
141
+ | 非异动模块 | 该查询属于{模块名}模块范畴,超出本skill异动查询能力范围,请使用对应的skill处理。 |
142
+ | 动态字段无法筛选 | 无法执行:当前运行时无法确认「{字段名}」是异动搜索支持的筛选字段。请改用接口支持的筛选维度。 |
143
+ | 复杂统计分析 | 本skill仅支持基于异动搜索结果的简单计数、分组和交集;不支持跨模块、跨对象或需额外数据仓库的复杂统计分析。 |
144
+
145
+ ## 多匹配澄清模板
146
+
147
+ 部门多匹配:
148
+ ```text
149
+ 需要澄清:查询"{部门名}"部门时可能匹配到多个候选部门,需确认具体组织节点。请补充部门全称、调入还是调出、时间范围等信息。
150
+ ```
151
+
152
+ 员工多匹配:
153
+ ```text
154
+ 需要澄清:查询"{员工名}"时可能匹配到多个人员记录。请提供员工工号、所属部门或更完整的姓名以精确定位。
155
+ ```
156
+
157
+ ## 常见错误速查
158
+
159
+ | 易错点 | 正确做法 | 错误做法 |
160
+ |-------|---------|---------|
161
+ | `filter_str` 字段值类型 | 全部包成数组 | 直接传字符串 |
162
+ | 类型 vs 原因 | 用户说类型用 `transform_type`,说原因用 `transform_reason`,首步 `search-option` 校准候选后再用 `--dynamic-filters` | 混用、自动回退或写死枚举 |
163
+ | 返回字段不足 | 基于 `system_columns` 最多补查一次;"为什么/原因"展示异动原因字段 | 反复试 `--help`、nested path 或相近字段到超时 |
164
+ | 搜索命令报错 | 输出运行时搜索失败模板和已执行条件 | 查源码、配置、版本、二进制路径或继续改参 |
165
+ | 第一人称 | 先判断是否需要解析当前用户 | 直接传 `query_name="我"` |
166
+ | `page_size` 默认值 | 10 | 非 10 的任何值 |
167
+ | `status` 使用 | 纯生效日期查询不追加状态;“已生效/生效的异动”追加首步 `search-option` 校准后的已生效状态 | 生效日期查询默认追加状态、漏掉“生效的异动”状态、只取首个匹配或写死单一状态 |
168
+ | 最终答案 | 执行最终搜索后输出结果正文 | 输出推理过程、计划、命令建议、runner JSON |
169
+ | 最后命令 | 以最后一次 `+job-change-search` 结果生成记录数/空结果 | 搜索已执行却返回旧的探索句 |
170
+ | 搜索后处理 | 可按分页策略做 `page_token` 有界分页/聚合/格式化,并最终输出业务答案或询问是否继续 | 输出“需要写脚本聚合/继续拉取”、只写临时文件或只 `wc` |
171
+ | JSON 解析 | 读取 `data.items[]`、`data.has_more`、`data.page_token`、`data.total` | 判断 NDJSON/多 JSON,或用 `grep/head` 截取 search 输出 |
172
+ | 最终 `--jq` | 不使用;或仅包装 meta 且保留完整 `items` | 只返回 total/has_more、groups,或把 items 裁剪成少数字段 |
173
+ | 总数口径 | “总数/共有/一共”只使用 `data.total`;本页数量写“本页返回 N 条” | 把本页数量、样例数量、已聚合数量当总数 |
174
+ | 默认字段 | 姓名、工号、头像、生效日期、异动类型、状态 | 未指定字段时展示大量无关字段,或用用户点名字段替换基础字段 |
175
+ | 搜索报错 | 输出运行时搜索失败模板 | 调 help/schema/search-option 或改参重试 |
176
+ | 解析失败 | 必需条件失败时输出不可用结果;可选条件安全省略后继续搜索 | 展示 option id、内部候选 ID、命令探索过程 |
177
+ | 数据导出 | 直接说明当前接口不支持数据导出,即使用户说有导出权限也不调用 CLI | 查询后生成或暗示可生成 Excel/CSV/文件 |
178
+
179
+ ## 执行 Checklist
180
+
181
+ - [ ] 意图是否属于异动查询范畴?
182
+ - [ ] 是否命中审批、导出、修改、离职、编制等边界关键词?导出命中时是否未调用 CLI?
183
+ - [ ] 第一人称是否需要解析当前用户?
184
+ - [ ] 对象名称条件存在且当前查询表达需要 lookup 时,是否已通过最终 search 的 `--lookup-filters` 表达?
185
+ - [ ] 当前所属/员工.部门是否使用 `field_name="employment.department",target_object_api_name="department"` 的 `--lookup-filters`?
186
+ - [ ] 是否已先用有界 `search-option` 校准筛选字段、枚举值和显式返回字段?
187
+ - [ ] `search-option` 是否只完整执行一次且复用结果,没有 `head`/`grep` 截断、二次 dump、`--help` 或替代 flag 验证?
188
+ - [ ] 异动类型/原因是否已通过 `search-option` 校准后写入 `--dynamic-filters`,且没有混用?
189
+ - [ ] 是否已把 `details_of_job_status_change` 当作门禁检查:筛"发生某字段变更/异动到/调入调出/从 X 到 Y/转为/同步变"时已追加对应 value;仅要求"是否变更"输出标注时未误加过滤?
190
+ - [ ] 用户要求多个维度是否变化/标注原因/是否调薪时,`--select-fields` 是否已包含每个维度的 original/target 字段、原因字段和 `is_adjust_salary`?
191
+ - [ ] 是否已添加 `page_size=10`,且已区分“生效日期”与“已生效/生效的异动”状态语义?
192
+ - [ ] 相对时间结束日期是否为当前日期?
193
+ - [ ] `filter_str` 所有字段值是否都是数组?
194
+ - [ ] 返回记录是否与筛选条件一致,是否需要去重?
195
+ - [ ] 是否已真实执行 `+job-change-search` 并基于 CLI 返回结果回答?
196
+ - [ ] 命令链是否不止停在 `search-option` / `help` / `schema`?
197
+ - [ ] 若执行过最终搜索,最终答案是否来自最后一次搜索结果,并包含记录数量或无匹配记录?
198
+ - [ ] 若输出“总数/共有/一共”,数字是否来自 `data.total`,且没有把本页数量、样例数量、已聚合数量当总数?
199
+ - [ ] 非空查询最终答案是否同时包含接口返回总数、分页状态(是否还有更多/分页标记是否返回)和异动详细记录?
200
+ - [ ] 若用户未明确要求翻页/全部/完整列表/继续翻页,是否未自动翻页,并已说明 `total`、`has_more`、`page_size`?
201
+ - [ ] 若用户要求全部/完整列表,是否最多先返回或聚合 200 条;仍有更多时是否询问继续?
202
+ - [ ] 若用户要求有哪些/都去了哪些/汇总/统计/数量/分组,是否最多先处理前 200 条;仍有更多时是否说明部分统计不代表全量并询问继续?
203
+ - [ ] 是否只按固定 JSON 对象读取 `data.items[]`、`data.has_more`、`data.page_token`、`data.total`?
204
+ - [ ] 最终 search 是否没有用 `--jq` 裁剪明细;如用了 `--jq`,是否保留完整原始 `items` 而不是只保留 meta/groups?
205
+ - [ ] 若字段不足、搜索报错或分页失败,是否输出结构化不可完成原因,而不是首屏业务结论?
206
+ - [ ] 如果没有执行最终搜索,是否确实因为必需运行时解析失败,并已输出不可用结果?
207
+ - [ ] 最终输出是否为纯答案正文或结构化文本,且没有代码块、推理过程、计划、命令建议或评测元信息?
@@ -0,0 +1,226 @@
1
+ # search-job_change 高级主题
2
+
3
+ 变更类字段筛选、输出结构、权限、示例与反例。
4
+
5
+ > **前置条件:** 先阅读 [`../../people-shared/SKILL.md`](../../people-shared/SKILL.md) 与 `people-job-change` 主 skill,以及 [people-job-change-search.md](people-job-change-search.md)。
6
+
7
+ ## 变更类字段筛选
8
+
9
+ 用户问"涉及 XX 变更"时优先判断是否可以通过 `filter_str` 直接表达:
10
+
11
+ 1. 普通查询第一步先做一次有界 `search-option` 校准,确认该变更语义是否已有可筛选字段,以及原/新字段是否可作为返回字段。
12
+ 2. 若 `system_filters` 已支持该变更条件,优先用校准后的字段 API 名和值构造 `--dynamic-filters`。
13
+ 3. 若只能通过返回字段判断,则在唯一最终搜索中请求 `original_*` / `target_*` 返回字段后按可见结果对比。
14
+ 4. 客户端对比前必须叠加用户其它可表达筛选条件,例如日期、员工、部门、类型、原因,避免无界全量扫描。
15
+
16
+ ### details_of_job_status_change 门禁
17
+
18
+ `details_of_job_status_change` 不是只在用户直说"异动变更内容"时才用;它是所有异动前后字段查询的必检门禁。构造最终 search 前必须判断:
19
+
20
+ 1. 用户是否在筛记录本身发生某类变更:如"异动到北京"、"人员类型转正式"、"职级从 L6 到 L2"、"序列变更"、"调入/调出某部门"、"工作地点发生变化"。是则追加对应 details value,并同时保留目标侧/原侧字段条件。
21
+ 2. 用户是否只是要求在结果里展示或标注变化:如"每组标注工作地点是否变更、职级是否变更"。这时不要把工作地点/职级 details 加为筛选条件;只在 `select_fields` 中返回原/新字段并比较。
22
+ 3. 多个 details 条件若语义是"同时发生",按下方 AND 分支取交集;若只是"合同信息变更"这类父节点概念,用父节点 value 一次筛选。
23
+
24
+ 常用映射:部门 `department`,工作地点 `work_location`,序列 `job_family`,职级 `job_level`,职务 `job`,直属上级 `direct_manager`,虚线上级 `dotted_manager`,人员类型 `employee_type`,合同 `contract`,司龄起算日期 `seniority_date`;试用期用运行时"试用期"父节点/合法值。不确定时仅用一次有界 `search-option --jq` 校准,不能靠 help/schema/临时脚本探索。
25
+
26
+ ### 多变更内容 AND
27
+
28
+ `details_of_job_status_change` 同一字段传多个 values 是 OR 语义,只能表示"部门变更或职级变更"。当用户说"同时发生 A 和 B"/"既 A 又 B"/"A 且 B"时:
29
+
30
+ 1. 先从 `search-option` 校准 A、B 各自的运行时合法 value(不要用"X变更"等带后缀的字符串)。
31
+ 2. 只有多个条件都属于 `details_of_job_status_change` 变更内容时才分支;普通字段/自定义字段取值 + 一个变更内容发生,直接放在同一次 `--dynamic-filters` 数组里表达 AND,不要拆两支。需要分支时按语义组建分支:普通单项变更每组 1 个 value;合同组固定用父节点 `contract`,不要展开合同子项;试用期等集合型变更按运行时父节点优先。保持日期、部门、员工、状态、原因等其它筛选条件**完全一致**,分别搜索每个语义组;不要把组内每个子项拆成独立分支,也不要为了提取 ID 重跑同一分支。
32
+ 3. 保守交集优先:用户未明确要求完整列表/继续翻页时,默认只用每个分支当前页 `items` 求交集,不主动翻页,避免大输出截断后编造。只有用户明确要求全部/继续,才按 `page_token` 有界翻页,最多 200 条。
33
+ 4. 只读每个分支原始 JSON 响应里的 `data.items[].job_change_id` 取交集;缺失 `job_change_id` 时用 `wk_id` 作为兜底稳定键。禁止对最终搜索结果使用管道、`python3`、`grep`、`head`、`wc`、临时文件或静默重跑来提取 ID。
34
+ 5. 分支搜索遵守分页上限:每个分支最多先聚合 200 条;任一分支仍有 `has_more=true` 时,交集结果只能标为已聚合范围内的部分口径,并询问是否继续。
35
+ 6. 答案里的"同时发生"数量写"当前页交集命中 N 条/已聚合交集 N 条",**禁止**使用任一分支或单次 OR 查询的 `data.total` 作为"同时发生"的总数。若当前页交集为空但任一分支 `has_more=true`,禁止回答"没有符合条件";只能写"当前已返回记录内未发现交集,但仍有更多记录,不能确认全量为空",并给出各分支 `data.total`、本页数量和 `has_more`。
36
+ 7. 分支搜索完成后必须输出最终交集结果和明细;如果已拿到两个分支的 `items`,下一步只能在回答逻辑中求交集并回答,不能再读 `search-option`、写脚本、查字段、管道加工或重跑同一分支。
37
+ 8. 三个及以上变更内容同样按上述方式逐个搜索后取多集合交集;变更内容个数过多导致总搜索次数会超过分页预算时,提前说明无法在单次会话内完成并请求用户缩小变更项范围。
38
+
39
+ > **跨城市/跨地区变更**:先用 `details_of_job_status_change=[work_location]` 拉到候选集,再在 `select_fields` 请求 `original_work_location` / `target_work_location`,按其 city 或稳定标识比较;同城市/未变更的剔除,并在口径中说明二次过滤维度。
40
+
41
+ > **Lookup 信任反例**:用户问"调走/调入 Brand 部门"时,已用 `--lookup-filters target_department=Brand`(或 `original_department=Brand`)且追加 `details_of_job_status_change=department` 后,不要再按 `target_department.name == "Brand"` 或 `original != target` 二次剔除;下级同名节点也由 lookup 解析覆盖。
42
+
43
+ ### 目标侧变更必须叠加变更内容
44
+
45
+ 异动查询有"变更前/变更后"概念。用户问"异动到/调到/变更到/转为/变为 X"时,真实语义不是"当前或目标字段值为 X"的宽搜,而是:
46
+
47
+ 1. 目标侧字段命中 X:如新工作地点用 `target_work_location` lookup,新部门用 `target_department` lookup,新人员类型用 `target_workforce_type` 校准枚举。部门调入/调出还必须同步筛 `details_of_job_status_change=department`。
48
+ 2. `details_of_job_status_change` 包含对应变更内容:工作地点、所属部门、人员类型、职级等必须从运行时"异动变更内容"树校准合法值。
49
+ 3. 若用户问"从 X 到 Y",同时加原字段与目标字段;若用户只问"到/转为/变为 Y",默认只加目标字段与变更内容,不再拉全量本地比较 original/target。
50
+ 4. 目标值同义词只校准一次:将用户用语解析到运行时合法值后立即最终搜索;不要继续试英文、别名或宽搜样本。若必需值无法唯一解析,按不可完成模板输出。
51
+ 5. "成功/已生效"只追加严格已生效状态;"生效日期/第一季度"仅限制 `effective_date`,不要把无需审批/审批通过算入已生效。
52
+
53
+ 例:"异动到北京的同学有哪些"应表达为"新工作地点=北京 AND 异动变更内容包含工作地点",不能只查 target_work_location=北京。
54
+
55
+ 例:"AI大部门调出的人都去了哪些部门"应表达为 `original_department=AI大部门 AND details_of_job_status_change=department`,并按 `target_department` 去重/计数;"调出的人/去了哪些部门"默认已发生,追加严格已生效状态。例:"本季度已生效调入 Brand、AI 大部门的记录"应表达为 `target_department in [Brand, AI大部门] AND status=已生效 AND details_of_job_status_change=department`,再按目标部门分组。
56
+
57
+ ### 合同变更用父节点筛选
58
+
59
+ "合同变更/合同信息变更"在界面上有下级字段,但筛选发生合同变更时使用父节点 `contract`,不要把合同类型、编号、开始/预计结束日期等子项展开为多个 details values:
60
+
61
+ - 用户只问合同信息变更:单次搜索 `details_of_job_status_change=["contract"]`。
62
+ - 用户要求按合同子项展示/统计:仍用 `contract` 筛选发生变更,再返回合同类型、编号、开始/预计结束日期等原/新字段;只有接口明确支持子项筛选且用户要求子项本身时才使用子项字段。
63
+ - 用户问"同时涉及合同变更和试用期变更":只做两个分支,合同分支 values=`["contract"]`,试用期分支用运行时父节点/合法值,最后按 `job_change_id` 取交集;交集非空后再最多补一次合同/试用期返回字段。
64
+ - 输出必须展示运行时可返回的合同相关原/新字段;字段不可返回时说明缺失字段,不编造。
65
+ - 合同/试用期/司龄等“有哪些人今年变更了”默认使用今年生效日期范围并追加已生效状态;若用户明确要求全部状态,才不加状态。
66
+ - 跨城市/跨地区工作地点变更必须先筛工作地点变更并返回原/新工作地点,再按城市/地区稳定属性归一比较;不能只用地点展示名不等作为跨城市结论。
67
+
68
+ ### 新试用期口径
69
+
70
+ 用户问"今年有没有异动后有新试用期的同学/有新试用期的同学"时,不按"实习生转正式"或人员类型推断。正确查询与判定:
71
+
72
+ 1. 日期用生效日期,"今年"按自然年完整区间 `2026-01-01` 至 `2026-12-31`。
73
+ 2. 筛选 `details_of_job_status_change` 中运行时"试用期"父节点/合法值,表示本次异动涉及试用期。
74
+ 3. 返回字段必须包含运行时"是否有试用期"字段;必要时用 `--select-field-names '["是否有试用期"]'` 或校准到对应返回字段。
75
+ 4. 最终答案只把"是否有试用期"返回值为 true 的记录算作符合条件;false、空、未返回都不能算命中,并需在口径中说明。
76
+
77
+ ### 对比字段
78
+
79
+ | 用户查询意图 | 对比字段 |
80
+ | --- | --- |
81
+ | 部门变更 | `original_department` vs `target_department` |
82
+ | 工作地点变更 | `original_work_location` vs `target_work_location` |
83
+ | 直属上级变更 | `original_direct_manager` vs `target_direct_manager` |
84
+ | 虚线上级变更 | `original_dotted_manager` vs `target_dotted_manager` |
85
+ | 职务变更 | `original_job` vs `target_job` |
86
+ | 序列变更 | `original_job_family` vs `target_job_family` |
87
+ | 职级变更 | `original_job_level` vs `target_job_level` |
88
+ | 人员类型变更 | `original_workforce_type` vs `target_workforce_type` |
89
+ | 公司 / 任职公司变更 | `original_company` vs `target_company`, `original_service_company` vs `target_service_company` |
90
+ | 工时 / 日历 / 排班变更 | 对应 `original_*` / `origin_*` vs `target_*` 字段 |
91
+ | 合同 / 薪资 / 社保 / 成本中心变更 | 对应 `origin_*` / `original_*` vs `target_*` 字段 |
92
+
93
+ 客户端对比必须使用 ID 或稳定标识比较,不能只比名称。缺失与有值之间的变化也视为发生变更。多条变更同时满足时按"多变更内容 AND"流程取交集,不要把单条记录拉回来再人工凑齐多个变更字段。
94
+
95
+ 多字段变化标注查询的闭环要求:
96
+
97
+ - 用户要求多个维度"分别有没有变化/是否变化"时,这些维度是输出标注,不自动作为筛选条件;但最终 search 必须显式返回每个维度的原/新字段。
98
+ - 常用标注字段:职务 `original_job`/`target_job`,序列 `original_job_family`/`target_job_family`,职级 `original_job_level`/`target_job_level`,人员类型 `original_workforce_type`/`target_workforce_type`,工作地点 `original_work_location`/`target_work_location`。
99
+ - 若用户同时要求"异动原因/为什么"和"是否调薪",必须在 `select_fields` 请求 `transform_reason` 与 `is_adjust_salary`;若响应只给原因标识字段,答案层读取实际返回字段。
100
+ - 若查询本身是从某部门调出到某部门,部门流向条件仍按 `original_department` + `target_department` lookup,并追加 `details_of_job_status_change=department`;返回字段也要包含 `original_department`/`target_department` 便于口径校验。
101
+ - 最终答案按每条记录逐项标注"是/否/未返回",不能只给总数或省略某个用户点名维度。
102
+
103
+ 工作地点变化类复杂查询的闭环要求:
104
+
105
+ - 最终搜索必须在 `select_fields` 中同时请求原工作地点和新工作地点相关字段。
106
+ - 若用户还问调入/调出部门、原因、时间、状态等条件,这些条件必须进入同一次最终搜索的 `filter_str`。
107
+ - 搜索返回后必须逐条比较原/新工作地点的 ID 或稳定标识,再回答是否变化;禁止只完成原因、类型或部门解析后停止。
108
+ - 若返回字段缺失或无权限,必须在最终答案中说明无法判断该条记录的工作地点变化。
109
+
110
+ ## 复杂聚合/全景输出规范
111
+
112
+ 多状态全景、按异动类型/目标部门/原因等维度分组、跨字段聚合等任务,禁止以"现在让我..."、"接下来将..."、"搜索成功,将聚合..."、"我会并行发起..."等过程文本结尾。最终答案至少包含:
113
+
114
+ - **最终结论**(一句话回答用户问题数量/名单/分组结果)。
115
+ - **聚合表**:按用户要求的每个维度各出一张表;状态分布单独成表,异动类型分布单独成表,目标部门分布单独成表。
116
+ - **数据口径**:列出已执行查询条件(时间、部门字段方向、状态集合、变更字段、是否使用了自定义字段)。
117
+ - **完整性说明**:写明每个分支的 `data.total`、本页/已聚合数量、`has_more`;任一分支聚合到 200 条仍 `has_more=true` 时标"前 200 条的部分统计/部分口径"并询问是否继续。
118
+
119
+ 多状态全景执行模式:对"已生效/审批中/已撤销/已拒绝"等多个状态分桶,必须**对每个状态各发一次** `+job-change-search`(其它条件相同),分别记录 `data.total`,再合并出表;一次无 status 搜索 + 客户端分桶**不可代替**,因为单次最多聚合 200 条不能覆盖每个状态真实的 `total`。
120
+
121
+ ## 按异动类型分类
122
+
123
+ 聚合 key 必须使用 `transfer_type_unique_identifier` 的二级运行时 `name`(末级类型名)。**不能**把所有记录归到一级"异动"或公共父类型,也不要写死类型枚举:
124
+
125
+ - 若 `transfer_type_unique_identifier` 是层级路径(如 `异动/活水转岗`),分组 key 取最后一级("活水转岗")。
126
+ - 若运行时只返回标识符,按标识符分组并附运行时 `name`。
127
+ - 若 `transform_type` 字段返回的是结构化对象,优先取其末级 `name`。
128
+
129
+ 输出表样例:
130
+
131
+ ```text
132
+ | 异动类型 | 数量 |
133
+ | --- | --- |
134
+ | <二级 name A> | <N1> |
135
+ | <二级 name B> | <N2> |
136
+ 合计:<N>,与 data.total 对齐。
137
+ ```
138
+
139
+ ## 输出
140
+
141
+ `data.items` 为异动记录列表,主要字段:
142
+
143
+ | 字段 | 说明 |
144
+ | --- | --- |
145
+ | `job_change_id` | 异动记录 ID |
146
+ | `employment_id` / `employment_name` | 异动员工 |
147
+ | `process_id` | 流程实例 ID |
148
+ | `status` | 异动状态 |
149
+ | `effective_date` | 生效日期 |
150
+ | `created_time` / `updated_time` | 创建 / 更新时间 |
151
+ | `exception_status` | 异常处理状态 |
152
+ | `is_adjust_salary` | 是否调薪 |
153
+ | `details_of_job_status_change` | 异动变更内容 |
154
+ | `transfer_info.original_*` / `target_*` | 异动前 / 后的任职信息、合同信息、工时日历、社保、成本中心等 |
155
+ | `transfer_type_unique_identifier` | 异动类型标识符 |
156
+ | `transfer_reason_unique_identifier` | 异动原因标识符 |
157
+ | `no_permission_fields` | 无权限字段 |
158
+
159
+ 分页字段:`data.has_more`、`data.page_token`。
160
+
161
+ ## 所需权限
162
+
163
+ `corehr:job_change:read`
164
+
165
+ ## 示例
166
+
167
+ ```bash
168
+ # 按异动记录 ID 查询,并返回工作地点变化字段
169
+ people-cli corehr +job-change-search \
170
+ --params '{"page_size":10,"department_id_type":"people_corehr_department_id"}' \
171
+ --data '{"filter_str":"{\"wk_id\":[\"<JOB_CHANGE_ID>\"]}","select_fields":["status","effective_date","original_work_location","target_work_location"]}' \
172
+ --as user
173
+
174
+ # 查询本月按生效日期命中的异动
175
+ people-cli corehr +job-change-search \
176
+ --page-size 10 \
177
+ --effective-date-start '<DATE_START>' \
178
+ --effective-date-end '<DATE_END>' \
179
+ --select-fields '["status","effective_date","transform_type","transform_reason","original_department","target_department"]' \
180
+ --as user
181
+
182
+ # 按目标部门名称筛选,名称由 --lookup-filters 内部解析
183
+ people-cli corehr +job-change-search \
184
+ --page-size 10 \
185
+ --lookup-filters '[{"field_name":"target_department","target_object_api_name":"department","values":["<DEPARTMENT_NAME>"]}]' \
186
+ --select-fields '["status","effective_date","original_department","target_department"]' \
187
+ --as user
188
+
189
+ # 分页仅在用户明确要求继续时作为新的查询轮次
190
+ people-cli corehr +job-change-search \
191
+ --page-size 10 \
192
+ --page-token '<PAGE_TOKEN>' \
193
+ --select-fields '["status","effective_date","original_department","target_department"]' \
194
+ --as user
195
+ ```
196
+
197
+ ## 反例(请勿模仿)
198
+
199
+ **场景**:用户问"本季度因为『<TRANSFORM_TYPE_NAME>』为异动类型的员工有哪些?"
200
+
201
+ 错误做法:
202
+
203
+ 1. 绕过 shortcut,直接猜 raw `filter_str.transform_type=["<TRANSFORM_TYPE_NAME>"]`
204
+ 2. 匹配失败后忽略 `transform_type` 筛选条件,只按日期拉取本季度全部异动
205
+ 3. 拿回全量结果后在本地按异动类型名称做包含匹配
206
+
207
+ 为什么错:
208
+
209
+ - 违反"前置依赖解析失败必须停止并向用户确认"约束
210
+ - 违反"禁止先拉全量再客户端文本匹配"约束
211
+ - 异动类型需要先由首步 `search-option` 校准成当前运行时合法候选,不能在 raw `filter_str` 里凭展示名猜测
212
+
213
+ 正确做法:
214
+
215
+ 1. 先用首步 `search-option` 确认 `transform_type` 字段和当前运行时合法类型候选。
216
+ 2. 使用 `+job-change-search --dynamic-filters '[{"field_name":"transform_type","values":["<运行时合法类型展示值>"]}]'` 发起最终搜索。
217
+ 3. 若 search-option 或 shortcut 返回未找到或多候选,立即停止,向用户反馈需要确认的候选或不可用原因。
218
+ 3. 收到用户明确指令后,再决定是否用新名称重试,或在不传 `transform_type` 的情况下继续查询
219
+
220
+ ## 相关文档
221
+
222
+ - 主查询流程见 [people-job-change-search.md](people-job-change-search.md)
223
+ - 字段定义见 [people-job-change-search-fields.md](people-job-change-search-fields.md)
224
+ - 对象名称筛选见 [people-job-change-search.md](people-job-change-search.md) 的 `--lookup-filters` 规则
225
+ - 异动类型/原因普通筛选见 [people-job-change-search.md](people-job-change-search.md) 的 `--dynamic-filters` 规则
226
+ - 系统筛选项和返回字段解析见 [people-job-change-search-option.md](people-job-change-search-option.md)
@@ -0,0 +1,119 @@
1
+ # search-job_change 字段定义
2
+
3
+ `filter_str` 常用 key、`select_fields` 可选值、`status` 枚举与生效状态映射。
4
+
5
+ > **前置条件:** 先阅读 [`../../people-shared/SKILL.md`](../../people-shared/SKILL.md) 与 `people-job-change` 主 skill,以及 [people-job-change-search.md](people-job-change-search.md)。
6
+
7
+ ## `filter_str` 常用 key
8
+
9
+ 以下 key 来自异动 search 的 transform 过滤模型;普通查询必须先用当前环境的 `search-option` 做最终确认,再决定是否能作为筛选字段使用。
10
+
11
+ > **字段值类型硬约束**:`filter_str` 中除日期 / 时间区间字段外,**所有字段值都必须是数组**(如 `{"nickname":["<NAME>"]}`、`{"status":["<STATUS_VALUE>"]}`),即使只有一个元素也要包成 `[...]`。服务端会按 `[]interface{}` 强制类型转换,传 string 会触发 panic 或 `[2200] Internal Error`。日期 / 时间区间字段(`*_start` / `*_end`)保持 schema 中定义的真实标量类型。
12
+
13
+ | 类别 | key |
14
+ | --- | --- |
15
+ | 基础 | `wk_id`, `process_id`, `employment`, `initiator`, `status`, `exception_statuses`, `transform_type`, `transform_reason`, `need_change_compensation`, `target_dotted_manager_clean`, `country_code_3` |
16
+ | 时间 | `wk_created_at_start`, `wk_created_at_end`, `effective_date_start`, `effective_date_end`, `updated_time_start`, `updated_time_end` |
17
+ | 组织/岗位 | `original_department`, `target_department`, `original_work_location`, `target_work_location`, `original_direct_manager`, `target_direct_manager`, `original_dotted_manager`, `target_dotted_manager`, `original_job`, `target_job`, `original_job_family`, `target_job_family`, `original_job_level`, `target_job_level`, `original_workforce_type`, `target_workforce_type` |
18
+ | 公司/合同 | `original_company`, `target_company`, `original_service_company`, `target_service_company`, `origin_contract_type`, `target_contract_type`, `origin_duration_type`, `target_duration_type`, `origin_compensation_type`, `target_compensation_type`, `origin_signing_type`, `target_signing_type` |
19
+ | 工时/日历/排班 | `original_working_hours_type`, `target_working_hours_type`, `origin_working_calendar`, `target_working_calendar`, `origin_work_shift`, `target_work_shift` |
20
+ | 社保/成本中心 | `origin_social_security_city`, `target_social_security_city`, `original_cost_center`, `target_cost_center` |
21
+ | 合同/试用期日期 | `origin_contract_start_date_start`, `origin_contract_start_date_end`, `target_contract_start_date_start`, `target_contract_start_date_end`, `origin_contract_end_date_start`, `origin_contract_end_date_end`, `contract_end_date_start`, `contract_end_date_end`, `origin_probation_end_date_start`, `origin_probation_end_date_end`, `probation_end_date_start`, `probation_end_date_end` |
22
+
23
+ ## `select_fields` 可选值
24
+
25
+ 基础字段:
26
+
27
+ ```text
28
+ status effective_date exception_status transform_type transform_reason
29
+ ```
30
+
31
+ 常见任职字段:
32
+
33
+ ```text
34
+ original_department target_department
35
+ original_work_location target_work_location
36
+ original_direct_manager target_direct_manager
37
+ original_dotted_manager target_dotted_manager
38
+ original_job target_job
39
+ original_job_family target_job_family
40
+ original_job_level target_job_level
41
+ original_workforce_type target_workforce_type
42
+ ```
43
+
44
+ 新增任职 / 合同字段:
45
+
46
+ ```text
47
+ original_company target_company
48
+ original_service_company target_service_company
49
+ original_working_hours_type target_working_hours_type
50
+ origin_working_calendar target_working_calendar
51
+ origin_work_shift target_work_shift
52
+ origin_social_security_city target_social_security_city
53
+ origin_contract_type target_contract_type
54
+ origin_duration_type target_duration_type
55
+ origin_compensation_type target_compensation_type
56
+ origin_signing_type target_signing_type
57
+ original_employee_subtype target_employee_subtype
58
+ original_job_grade target_job_grade
59
+ original_pathway target_pathway
60
+ original_position target_position
61
+ original_default_cost_center.cost_center_id target_default_cost_center.cost_center_id
62
+ original_work_country target_work_country
63
+ ```
64
+
65
+ > `select_fields` 只能用于返回字段。
66
+ >
67
+ > - 不要把 `filter_str` key、`transfer_type_unique_identifier`、`transfer_reason_unique_identifier`、`*_name` 字段放入 `select_fields`
68
+ > - 异动类型 / 异动原因的返回字段是 `transform_type` / `transform_reason`
69
+ > - `_name` 多语言字段会随对应字段一并返回,无需单独指定
70
+ > - 若用户要求的返回字段无法映射到合法值,必须明确说明不支持,不能擅自替换成相近名称
71
+
72
+ ## `status` 可选值
73
+
74
+ 仅当用户明确要求工作流/审批状态时才在最终搜索中使用 `status`。状态枚举必须从首步 `search-option` 的当前运行时结果解析,不能把某个环境中的枚举 value 或展示名当成固定常量。普通“生效时间/生效日期/生效日期在...”查询只使用 `effective_date_start/end`,不要为此追加状态;“已生效的异动/生效的异动记录/某月生效的所有异动”属于已生效状态语义,必须追加状态筛选。
75
+
76
+ 1. 首步 `search-option` 已得到合法状态集合时,按用户状态语义选择对应候选。
77
+ 2. `search-option` 只能调用一次且必须有界过滤;禁止 dump 全量返回。
78
+ 3. 若无法得到合法状态映射,有其它主条件时可省略状态并说明口径,状态本身是必需条件时输出不可用结果。
79
+ 4. 匹配时使用多语言展示名、状态说明和用户语义做等值/语义匹配;禁止把用户中文状态名直接写入 `filter_str.status` 或最终 `--dynamic-filters`。
80
+ 5. `filter_str.status` 的值始终是数组。
81
+
82
+ 可执行选择规则:
83
+
84
+ - 先得到合法状态项列表,每项至少保留 `value` 与展示名/说明文本。
85
+ - 归一化展示名、说明文本和可识别语义标签,按用户语义选择集合,而不是选择第一项。
86
+ - “已生效/生效的异动/有效/完成态/某月生效的所有异动”进入状态选择;普通“生效日期/生效时间”查询不要追加状态。
87
+ - `Approved` / 审批通过 / 已批准是待生效,不是已生效;即使用户问“已生效/某月生效”,也必须从已生效集合中排除。
88
+ - “已取消/取消/作废/撤销”进入取消/撤销语义选择;最终使用当前枚举中的合法候选,例如当前环境只有“已撤销”时使用“已撤销”,不能使用用户原词“已取消”。
89
+ - 若多个合法项都属于完成/生效语义,必须全部写入同一个 `filter_str.status` 数组;禁止只取第一个匹配项、最像的匹配项或任意单一状态。
90
+ - “待生效/即将生效”选择已完成审批或无需审批但生效日未到的合法项,并叠加未来生效日期。
91
+ - 若合法状态项无法区分完成态与待生效态,禁止猜测或写死 value;当用户已有日期、类型、原因、组织或人员等主条件时,可省略状态筛选继续最终搜索,并在答案口径中说明状态条件未纳入。
92
+
93
+ ## 生效状态映射
94
+
95
+ 本节只适用于用户明确要求工作流/审批状态的查询。普通“生效时间/生效日期”查询使用生效日期范围即可,不进入本节,不写死任何状态 value;“已生效的异动/生效的异动记录/某月生效的所有异动”进入本节。
96
+
97
+ | 用户查询意图 | `filter_str.status` 取值规则 |
98
+ | --- | --- |
99
+ | 已生效 / 生效的(明确状态语境) | 严格完成态集合:当前合法状态中表示已实际完成、已转换、已实际生效的 value;排除 `Approved` / 审批通过 / 已批准 |
100
+ | 某月/某时间段生效的所有异动 | 生效日期范围 + 严格完成态集合 |
101
+ | 已完成审批并生效 | 当前合法状态中表示审批已完成且生效日已到达的 value |
102
+ | 无需审批且已生效 | 当前合法状态中表示无需审批,并且生效日已到达的 value |
103
+ | 已生效且未指定审批口径 | 当前合法状态中所有已完成、已转换、已实际生效的 value 集合;排除 `Approved` / 审批通过 / 已批准 |
104
+ | 待生效 / 即将生效 | 当前合法状态中表示已完成审批或无需审批但等待生效日的 value,并叠加未来生效日期 |
105
+ | 审批中 / 已取消 / 已拒绝 | 分别按当前合法状态集合做语义解析;用户原词不是最终值 |
106
+ | 未明确区分 | 不追加状态筛选;若状态是用户的核心必需条件且无法确认,停止说明 |
107
+
108
+ 严格口径返回空时的 fallback:
109
+ - 普通查询禁用同轮 fallback;按唯一最终搜索结果回答。
110
+ - 只有用户明确要求继续扩大状态口径时,才作为新的查询轮次启用。
111
+ - 保留用户给出的个人、部门、时间、类型、原因等所有条件,只放宽 `status` 到更宽完成口径。
112
+ - 不要在同一轮因为空结果回到合法状态项列表再重查。
113
+ - 重查前在最终结果中说明“严格完成态为空,已按更宽完成/无需审批口径重查”;重查仍为空则如实返回空。
114
+ - 个人或部门范围不能混淆:部门名必须先解析为 ID,最终搜索的部门字段必须包含该 ID;默认部门语义仍按 `target_department`,只有“调出/来源/原部门”才用 `original_department`。
115
+
116
+ ## 相关文档
117
+
118
+ - 主查询流程见 [people-job-change-search.md](people-job-change-search.md)
119
+ - 变更类字段筛选与输出见 [people-job-change-search-advanced.md](people-job-change-search-advanced.md)