Skip to content

forecast_snapshot 与启动重播种的互动:每次 dev 重启后,当季出现一条无 owner 的幻影快照行与 owner 键控行并存 #702

Description

@yinlianghui

Found during the 17.0 GA acceptance sweep on @objectstack/* 17.0.0-rc.2 (current main), flow phase. Minor, demo-data-only, but it produces visibly wrong analytics rows on every re-seeded dev boot.

Mechanism (observed live)

  1. The nightly forecast_snapshot (03:00) maintains an owner-keyed current-quarter row per deal-owning user — that part works (verified: gate skips no-deal users, creates/updates the owner's row, sums the four buckets, leaves quota untouched).
  2. A warm boot re-runs seeds (updated: 288 at 07:19:43), which re-upserts all 8 seed forecast rows — and seed rows carry no owner (seeds cannot declare one; known limitation).
  3. The owner-keyed sweep then treats the current quarter as missing for each owner (its lookup is owner-scoped) and creates a fresh owner-keyed row alongside the ownerless seed row — both spanning the same 2026-07-01→09-30 window.

Result: any consumer grouping forecasts by owner sees a phantom ownerless duplicate for the current quarter after every re-seeded dev boot. (This also compounds the display_title: null issue #690 — the phantom row renders with no title AND no owner.)

Contributing factors, each individually known

  • seeds can't declare owner (platform seed limitation),
  • demo_bootstrap claims ownership on 8 objects × 2 columns but does not claim crm_forecast,
  • warm-boot re-seed re-upserts rows that a runtime writer (the snapshot flow) has since taken over.

Suggested direction (CRM-side, pick one)

  • add crm_forecast to demo_bootstrap's claim list (cheapest), or
  • stop seeding current-quarter forecast rows entirely and let the snapshot flow own that window (seed only historical quarters), or
  • make the snapshot flow's lookup fall back to adopting an ownerless current-quarter row instead of creating a sibling.

Attribution

CRM (seed data + demo_bootstrap claim list interplay); the platform pieces (ownerless seeds, warm-boot re-upsert) are each behaving as documented.

Refs #690 #617 #671

Activity

  1. added
    bugSomething isn't working
    metadataDeclarative metadata — schema, security posture, UI surfaces
    on Aug 5, 2026
  2. self-assigned this
    on Aug 5, 2026
  3. yinlianghui commented on Aug 5, 2026

    @yinlianghui
    CollaboratorAuthor

    认领:PM 循环(17.0 发布修复线)第 1 轮(顶替 #708 空出的槽位)
    会话:session_01VHrPAGEgFDoHjphqYG4BMa
    分支:claude/issue-702-forecast-phantom-row
    Worktree:hotcrm-issue-702
    文件面:三选一落点 —— src/flows/demo-bootstrap.flow.ts(认领清单加 crm_forecast)或 forecast 种子数据(不再播当季行)或 src/flows/forecast-snapshot.flow.ts(收养无主当季行),外加相关测试与 changeset。⛔ 不触 #684 在飞的七个 record-change flow 文件。

    派发注记:本单证据采自验收线 pre-#677 基线(5a78f88),而 #677 重写过 demo-bootstrap.flow.ts(±126 行,owner 双列已并成 owner_id 单列)且 #708 已核实认领谓词现为 {owner_id: null}。三个 contributing factor 需逐一对 origin/main 重核(尤其「demo_bootstrap 不认领 crm_forecast」与「seed 行无 owner」两条)后再选修法。


    Generated by Claude Code

  4. yinlianghui commented on Aug 5, 2026

    @yinlianghui
    CollaboratorAuthor

    验收 ACCEPT(PM 复核,对照 GitHub 实况):PR #717,CI 9/9 绿,已转 ready 并挂自动合并。

    复核要点:


    Generated by Claude Code

  5. yinlianghui commented on Aug 5, 2026

    @yinlianghui
    CollaboratorAuthor

    [17.0-rc2验收复核] 运行时实测复核 · 环境 hotcrm@0899b4f + @objectstack 17.0.0-rc.2(独立 scratch DB,端口 4098)。⚠ 本基线 0899b4f(09:39Z)早于 PR #717 合入(~14:54Z),故 #717 的修复不在本树内。即便如此,幻影行不复现。

    实测

    1. 冷启动:crm_forecast 8 行(与声明一致),全部 owner_id=SET(admin)。原因:平台 claimSeedOwnership 首管交接(packages/runtime/src/app-plugin.ts:951-956)把所有 NULL-owner 种子行改归提升后的 admin —— 包含 crm_forecast,而 demo_bootstrap 的 CLAIMED_OBJECTS 并不含它。故种子 forecast 行在本基线不是无主的,本单机制第 2/3 环的前提(「种子无主 → owner 域查找落空 → 建兄弟行」)被推翻。
    2. 触发 forecast_snapshot:总数保持 8;当季 Q3-2026(2026-07-01→09-30)quarter 行原地更新(pipeline 0→2.91M),无无主兄弟行。
    3. 暖重启(重播种)后:re-upsert 保留 owner_id(金额被重置回种子值,owner 不动);Q3-2026 quarter 行=1、有主、无主=0。再次触发 forecast_snapshot → 仍 8 行、1 有主、0 无主。

    两次复现均为:total=8, Q3-2026-quarter=1 (owned=1, ownerless=0)。

    结论

    本验收基线上幻影不可复现 —— claimSeedOwnership 把种子 forecast 行预先归给了 snapshot flow 所键控的同一个 admin,owner 域查找命中既有行并原地更新。补充一条发布风险事实:#717 的「种子退出当季窗口」不在 0899b4f,故若发布从 0899b4f 切,仍会播一条当季 forecast 种子行(但它是有主行,不是幻影)。仅记录实测,不动标签。


    Generated by Claude Code

  6. added and removed on Sep 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingmetadataDeclarative metadata — schema, security posture, UI surfacespm:dispatchedDispatched to a dev agent by /pm-dispatchpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions