Repository navigation
docs(activities): 把「重复任务」用例里的续约提醒按机制写实(#883) - #900
Merged
Merged
Conversation
…ecurrence (#883) `content/docs/sales/activities.mdx:73` and its zh-Hans / zh-Hant twins listed "Renewal reminder 60 days before contract end — set automatically by the contract flow" as a **recurring task** use case. Both halves are wrong: - Not 60 days. The hardcoded 60-day activation task was deleted from `src/objects/contract.hook.ts` (reason at :121-124). Renewal reminders come from the `contract_renewal` scheduled flow, which runs daily at 08:00, reads `status: 'activated'` contracts only, and applies each contract's own `renewal_notice_days` (`src/objects/contract.object.ts`, defaultValue 30). - Not a recurring task. `create_renewal_task` writes subject / type follow_up / priority / status / due_date / owner_id / related_to_* and no recurrence field at all. It reappears daily through scan + idempotency gate (`find_existing_task` + edge `b3`), not through recurrence. Tested for a real recurrence use case before rewriting. The mechanism is real (`is_recurring` / `recurrence_type` / `recurrence_interval` / `recurrence_end_date` on `crm_task`, the form's Recurrence group, the `recurrence_fields_required` rule, and `task_recurrence` in `src/objects/task.hook.ts` spawning the next occurrence on completion), but no automation ever creates one — `is_recurring` has zero hits under `src/flows/`, `src/actions/` and `src/data/`. So the false example is removed rather than swapped for an invented one, and the section says plainly that every recurring series here starts with a person ticking the box, then points the renewal reminder at the daily sweep and the Contracts page. Documentation only; no metadata, hook or flow changes. Co-authored-by: yinlianghui <yinlianghui@users.noreply.github.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #883
content/docs/sales/activities.mdx:73及其 zh-Hans / zh-Hant 双胞胎,在 Recurring tasks / 重复任务一节的用例列表里写着「合同结束前 60 天的续约提醒——由合同流程自动设置」。两个半句都与源码不符,这个 PR 按实测三语改写这一条用例所在的句段。前提复核(在最新 origin/main 上)
:73。activities 页最近两次改动是 docs(sales): 把 activities 页的活动量指标指向真正报告它的仪表盘 (#747) #772(指向真实仪表板)与 fix(home): bind the Sales Home tabs to real views, and document the task views that ship (#771) #784(Sales Home 标签绑定),都没碰这一节。src/objects/contract.hook.ts:121-124的注释写明写死 60 天的激活期任务已被删除("The activation-time task this hook used to create hardcoded a 60-day notice and duplicated the flow's task.")。今天排续约提醒的是contract_renewal定时流程(src/flows/contract-renewal.flow.ts):start节点schedule: '0 8 * * *',query_contracts的 filter 是{ status: 'activated', end_date: { $gte: '{TODAY()}', $lte: '{TODAY() + 120}' } }(120 天只是宽预过滤),逐份合同的窗口判定在出边b1上,读的是vars.currentContract.renewal_notice_days;该字段定义在src/objects/contract.object.ts,defaultValue: 30,逐份可设。create_renewal_task(contract-renewal.flow.ts:86-98)写入的字段只有subject/type: 'follow_up'/priority: 'high'/status: 'not_started'/due_date/owner_id/related_to_type/related_to_account——没有任何重复字段。它每天重现靠find_existing_task+ 出边b3(existingRenewalTask == null)这个幂等闸门,即「扫描 + 当天已处理则跳过」,与 recurrence 机制无关。recurrence 用例测查结论(决定改法的那一步)
按 PM 裁定,先测本仓是否存在真实的 recurrence 用例,有则换真例、没有则如实写、不编造第二个假例。测查结果分两层:
机制是真的,因此本节的开头段(「标记为重复→系统在你完成当前实例时生成新实例,直到重复结束日期」)不需要改:
crm_task的is_recurring/recurrence_type(daily/weekly/monthly/yearly)/recurrence_interval/recurrence_end_date(src/objects/task.object.ts:178-206);src/views/task.view.ts:279-292的 Recurrence & Effort 分组把四个字段都摆了出来;recurrence_fields_required(task.object.ts:292-296);src/objects/task.hook.ts的task_recurrence钩子,在「进入已完成」的那次转换上克隆下一实例,按recurrence_type × interval推进due_date/reminder_date(月/年步长对月末做 clamp),越过recurrence_end_date即停。但没有任何自动化会创建重复任务。
is_recurring在全仓的命中只有task.object.ts/task.hook.ts/task.view.ts加四个语言包;src/flows/、src/actions/、src/data/(种子)下零命中。也就是说:这个应用里每一条重复任务都由人工勾选发起,钩子只负责把已存在的系列往下续。所以没有真例可换——列表里剩下的两条(季度回访、每日站会)本来就是人工设定的示例,是准确的;假的那一条被移除,改为如实写明「本应用不会自动创建重复任务」,再按真实机制交代续约提醒,并指向
content/docs/revenue/contracts.mdx的每日——续约提醒一节(那里已按实测写实,#823 / #874)。口径与 PR #884(quotes 接受链路)一致:同一句「只读已激活合同、用每份合同自己的续约通知(天)、默认 30、不是 60」,不重复不矛盾;「说明本应用不发布/不使用某能力」的写法沿用 #864。改文三语对照
en — 改前:
- *Renewal reminder 60 days before contract end* — set automatically by the contract flow.改后为两段散文:① 两条用例都是手工设定,且 nothing in HotCRM marks a task as recurring for you(无 flow / action / 种子数据);② The renewal reminder is not one of them — 每日续约扫描建的是普通高优先级 follow-up、身上没有重复字段,针对 Activated 合同、按各自的 Renewal Notice (Days)(默认 30,不是固定 60),每早重现是「扫描又跑一遍 + 跳过还挂着未完成提醒的合同」,并链到 Contracts。
zh-Hans — 改前:
- *合同结束前 60 天的续约提醒*——由合同流程自动设置。改后同结构:「HotCRM 不会替你把任何任务标记成重复任务……你不勾,这个应用里就一条重复任务都没有。」+「续约提醒不在其列。……结束日期已经进入这份合同自己的**续约通知(天)**窗口的已激活合同,默认 30 天、逐份可设,不是固定的 60 天……」链到合同页。
zh-Hant — 改前:
- *合約結束前 60 天的續約提醒*——由合約流程自動設定。改后同上,繁体:「續約提醒不在其列。……**續約通知(天)**視窗的已啟用合約,預設 30 天、逐份可設,不是固定的 60 天……」链到合約頁。
zh 术语按语言包:
renewal_notice_days→ 「续约通知(天)」(src/translations/zh-CN.ts:547),is_recurring→ 「重复任务」(:707),合同status.activated→ 「已激活」(:523);zh-Hant 沿用本仓既有的「啟用 / 視窗 / 欄位」译法与 #884 落地文本一致。只动了该用例所在的句段——本节开头的机制段、其余两条用例、以及前后两节都未改;未触碰
src/**、content/docs/releases/;未加任何守卫;未升级@objectstack/*。验证输出
全量六项在共享锁
flock -w 7200 /tmp/os-heavy-verify.lock下、NODE_OPTIONS=--max-old-space-size=4096依次跑完,退出码全为 0:pnpm validateData: 17 Objects 344 Fields/Logic: 24 Flows;5 条 author-time 警告为既有(approval approvers、campaign_member 分组),与本改动无关pnpm typechecktsc --noEmit无输出pnpm build✓ Build complete (1444ms)·Artifact: dist/objectstack.json (1921.4 KB)pnpm test -- --maxWorkers=2Test Files 66 passed (66)·Tests 1587 passed, 1 skipped (1588)·Duration 47.64spnpm lint13 warning(s), 14 suggestion(s) (1221ms),全部为既有的 approval-approvers 提示pnpm hygieneSource hygiene — 245 files under src, test, e2e, scripts; the control-byte scan adds 409 under content, .changeset·✓ no raw control bytes in first-party files·✓ source hygiene cleantest 输出里的
✗ source hygiene: scanned director(y|ies) missing: .changeset是source-hygiene-scan-surface.test.ts元测试自身刻意触发的负例 stderr,属预期,该文件计入上面 66 passed。控制字节自扫(
grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f]')覆盖三个 mdx 与 changeset,退出码 1(零命中)。changeset:
.changeset/activities-recurring-example.md('hotcrm': patch,站内路径用反引号)。