Repository navigation
[finding] Seed data puts every ≥$100K opportunity into a pending approval — ~90% of open kanban cards are undraggable in a fresh demo database #1902
Description
Activity
objectstack-fleet commented
on Sep 25, 2026 ContributorMore actionsrepo:hotcrmseat,session_01X8U3asekbiC7yWoEPWR4Dg· stock re-triage group 6 (maintainer-confirmed ten-card group; maintainer reply verbatim: 「同意」) · 2026-09-25T04:39ZRuled B →
pm:queue, p2The maintainer confirmed group 6 with this card's recommendation B: re-price the seeded active pipeline so that only 1–2 deals sit at or above
LARGE_DEAL_AMOUNT(100,000) to exhibit the approval flow; the rest fall below it so the kanban is draggable out of the box. ⛔ Not A: no fabricated approved-approval records.Measured: 9 of the 10 open seeded deals are ≥
LARGE_DEAL_AMOUNT; both approval start conditions are true for them, and the approval nodes setlockRecord: true(src/sales/flows/opportunity-approval.flow.ts:122,:148). The counts match the card (23 / 14 / Initech). This contradicts the seed comment "Two cards in each active stage make the kanban immediately legible".⚠️ Unverified: whether dashboard/forecast pipeline figures or docs quote these amounts (agit grepovercontent/andtest/for the deal names/amounts found 0 hits) — the dispatch must re-check.
Generated by Claude Code
- addedbugSomething isn't workingSomething isn't workingpm:queueReady for the PM dispatch loopReady for the PM dispatch looppriority:p2Medium: important, M3Medium: important, M3pm:dispatchedDispatched to a dev agent by /pm-dispatchDispatched to a dev agent by /pm-dispatchand removedpm:queueReady for the PM dispatch loopReady for the PM dispatch loop
on Sep 25, 2026 objectstack-fleet commented
on Sep 25, 2026 ContributorMore actionsClaim: PM loop round R64 (serial dispatch, maintainer instruction verbatim: 「串行派发」) · 2026-09-25T14:12Z
Session:session_01X8U3asekbiC7yWoEPWR4Dg
Branch:claude/issue-1902-seed-pipeline-pricing
Worktree:hotcrm-issue-1902
Domain:repo:hotcrm(single-lane repo — nodomain:*taxonomy)
Seat:repo:hotcrm#1
File surface: the curated active-pipeline seed undersrc/sales/data/(opportunity amounts / their line items,OPPORTUNITY_LINES), any revenue seed that derives from those amounts (src/revenue/data/), tests that pin the seeded amounts or approval counts, docs that quote the seeded figures, one.changeset/(stop on breach; explain in the report)
Container & model:M,mode:subagent,model: opus— default judgement tier, hand-picked (dispatch-gates --tierrefuses hotcrm paths from the objectstack checkout)
Clause-②: no
Thread-read: 5826849592
Serial constraints cleared: #1258 (PR #1959,src/sales/data/activity.seed.ts) is MERGED. #1828 (PR #1960, line-item hooks) is MERGED, so seeded line items now get runtime ordinals; the seed's own 1..n numbers are kept. Open: #1956 (src/revenue/objects/{quote,contract}.object.ts, profiles, docsadministration/revenue/contracts*) and #1950 (epic,src/sales/objects/opportunity*); ⛔ this card edits neither. Ruling: maintainer confirmed option B in re-triage group 6 (comment 5826849592).- added a commit that references this issue
on Sep 25, 2026 objectstack-fleet commented
on Sep 25, 2026 ContributorMore actionsos-dev-report
{ "issue": 1902, "status": "done", "branch": "claude/issue-1902-seed-pipeline-pricing", "pr": "https://github.com/objectstack-ai/hotcrm/pull/1961", "session": "session_01X8U3asekbiC7yWoEPWR4Dg (subagent; parent's id, per the claim comment 5833851637 that names this branch)", "premise_still_valid": true, "summary": "Ruling B implemented. The seven curated active-pipeline deals were re-scoped at the source of truth (OPPORTUNITY_LINES in src/sales/data/sales.seed.ts; dealValue() still derives amount and expected_revenue), so each comes in under LARGE_DEAL_AMOUNT: Globex 500000 to 95000, Northwind 240000 to 86500, Lattice SSP 125000 to 53000, Vertex Analytics 320000 to 79000, Apex 275000 to 93000, Lattice Renewal 210000 to 87000, Vertex Enterprise Rollout 675000 to 94000. Exactly two open deals stay over the line, one per tier: Acme Platform Upgrade 150000 (manager review only) and Wayne Enterprise License 1200000 (manager, then director, over HIGH_VALUE_DEAL_AMOUNT). Those two were kept because other seed prose already quotes their amounts: the Acme account description says $150K, and the Wayne in_approval contract has contract_value 1200000. A seed-row pin in test/seed-consistency.test.ts names both deals and their tiers, and asserts that every active stage keeps a card under the line. The flow, the thresholds and quote/contract.object.ts are untouched. Fresh-DB measurement: before, 23 total / 14 non-pending, 10 open, 9 open at or above 100K, 9 locked by a pending approval, 1 draggable (Initech); after, 23 / 21, 10 open, 2 at or above 100K, 2 locked, 8 draggable, and each of the 5 active stages holds 2 cards. Browser drag check in headless Chromium on the Sales Pipeline view: dragging Northwind Grid Modernization from Prospecting to Qualification got PATCH 200, and the API read-back shows stage qualification. Control: dragging the locked Acme Platform Upgrade got PATCH 409 RECORD_LOCKED plus a toast, and its stage stayed proposal. Before the fix, the API PATCH on Northwind got RECORD_LOCKED. PM assumption checks: A1 confirmed (the lock mechanism and the card's counts reproduced exactly). A2 confirmed (amounts are derived from lines; the seed's own line numbers were not touched). A3: the only consumer I had to update is the Globex Manufacturing Suite Proposal quote in src/revenue/data/revenue.seed.ts (tax 38000 to 7220, re-derived at the 8% every non-Acme quote bills; description no longer mentions implementation services). Its quote lines follow automatically through QUOTE_LINES. content/**, src/docs/** and test/** have 0 hits for the deal names or amounts. forecast.seed.ts is hand-typed rather than derived, so I left it. Campaign derived metrics count won deals only, so they are unaffected. A4: two deals kept over the line, one exhibiting each tier.", "tests": "All at HEAD 521de4e5 (the only commit), each command run under os-verify-lock. pnpm validate exit 0; typecheck 0; lint 0 (5 warnings, 14 suggestions, pre-existing); lint:i18n-gate 0 ('0 i18n/missing-* issues'); hygiene 0 ('source hygiene clean'); hygiene:tokens 0 ('source token ratchet clean'); build 0; test 0 ('Test Files 173 passed (173) / Tests 3716 passed | 1 skipped (3717)'). Token ratchet before and after: every measured line is identical on base 1551914b and on HEAD. Only the excluded bucket moved (src/*/data is outside the ratchet by ruling, EXCLUDED_DIR_NAMES = translations, data): about 96,270 tokens before, about 96,254 after. Seed data being outside the ratchet is confirmed. Ablation of the new pin: ablation-replace changed the Lattice SSP SMB line quantity from 2 to 7 (126000). The anchor went from 1 hit to 0, the replacement from 0 to 1, and the blob changed. seed-consistency went red: 'x exactly two open deals sit at or above LARGE_DEAL_AMOUNT, one per approval tier', AssertionError expected [ ...(3) ] to deeply equal [ ...(2) ], 1 failed / 39 passed. Restored: blob equals HEAD and git diff HEAD is empty. vitest reads src directly, so no build or dist step applies. Control-byte scan over the changed files returned no matches (grep exit 1). Changed files: .changeset/seed-pipeline-draggable-kanban.md (hotcrm patch), src/sales/data/sales.seed.ts, src/revenue/data/revenue.seed.ts, test/seed-consistency.test.ts.", "mcp_calls": "0", "api_writes": "2 via the fleet-write relay (POST /repos/objectstack-ai/objectstack/dispatches, each executed as objectstack-fleet[bot]): pr_create, which made POST /repos/objectstack-ai/hotcrm/pulls (draft #1961), and this report comment, POST /repos/objectstack-ai/hotcrm/issues/1902/comments. Plus git push x2, which is not REST. Zero label writes: #1961 carries only the labeler's path labels (ci/cd, metadata), and a changeset is included, so skip-changeset does not apply. Zero issue or PR assignee writes.", "open_questions": [], "out_of_scope_findings": [ "carrier: none (承接者:无) - noted, not filed: an existing demo DB is not re-priced in place. Line-item seeds upsert on (opportunity, product), so product lines a deal no longer carries would stay behind as orphans, and approval requests already open stay open. The changeset points to pnpm demo:reset. This path was not measured. Recorded in the PR's Acceptance notes.", "carrier: none (承接者:无) - noted, not filed: the current-month forecast snapshot in src/sales/data/forecast.seed.ts (pipeline_amount 760000) is a hand-typed positional demo figure. It never tracked the seeded open pipeline (3,775,000 before) and does not now (2,017,500 after). It is an observation, not a defect class. Recorded in the PR's Acceptance notes." ], "gates": { "validate": 0, "typecheck": 0, "lint": 0, "lint:i18n-gate": 0, "hygiene": 0, "hygiene:tokens": 0, "build": 0, "test": 0, "ci": "in_progress (not waited on, per contract)" }, "counts": { "before": { "total": 23, "non_pending": 14, "open": 10, "open_ge_100k": 9, "open_locked_pending": 9, "draggable_open": 1 }, "after": { "total": 23, "non_pending": 21, "open": 10, "open_ge_100k": 2, "open_locked_pending": 2, "draggable_open": 8 } }, "files_changed": [ ".changeset/seed-pipeline-draggable-kanban.md", "src/sales/data/sales.seed.ts", "src/revenue/data/revenue.seed.ts", "test/seed-consistency.test.ts" ], "deviations": [ "The verify chain ran step by step (the same eight scripts, in order) so that each step's exit code was captured, rather than as one pnpm verify.", "The PR footer uses the role file's session-URL form instead of the harness attribution block, because the role file takes precedence.", "The commit subject carries (#1902) as a reference. It has no card trailer.", "Worktree removed after the PR opened. The branch tip on origin is 521de4e5." ] }
Generated by Claude Code
objectstack-fleet commented
on Sep 25, 2026 ContributorMore actionsPM review — ACCEPT → landing once CI converges · 2026-09-25T14:36Z
Reviewer of record:
repo:hotcrmseat,session_01X8U3asekbiC7yWoEPWR4Dg. Reviewed against GitHub.-
PR fix(seed): price the active pipeline so the demo kanban is draggable #1961 at
521de4e5:Fixes #1902, a real changeset, 4 files (+92 −24): seeds, one test and the changeset. The flow, the thresholds and the object files are untouched. -
Ruling B executed: seven active deals re-scoped at the source of truth (
OPPORTUNITY_LINES; amounts stay derived). Exactly two stay overLARGE_DEAL_AMOUNT, one per approval tier:- Acme Platform Upgrade, 150,000 — manager review.
- Wayne Enterprise License, 1,200,000 — manager, then director.
Both amounts are already quoted by other seed prose.
-
Measured on a fresh DB:
open ≥100K locked by a pending approval draggable before 10 9 9 1 after 10 2 2 8 Every active stage keeps 2 cards. Browser: Northwind dragged Prospecting → Qualification (PATCH 200). Control: the locked Acme gets 409
RECORD_LOCKED. -
Pin:
test/seed-consistency.test.tsnames the two over-the-line deals. An ablation that pushes a third deal over the line turns it red. -
Consumer updated: the Globex quote in
src/revenue/data/revenue.seed.ts(tax re-derived).content/,test/and docs: 0 hits for the deal names and amounts. -
Acceptance notes (no carrier): an existing demo DB is not re-priced in place (
pnpm demo:reset), and the hand-typed forecast snapshot never tracked the pipeline.
-
- removedpm:dispatchedDispatched to a dev agent by /pm-dispatchDispatched to a dev agent by /pm-dispatch
on Sep 25, 2026
Filing class: ① reproducible exhibit defect — landing: src/sales/data/ (the curated active opportunity pipeline)
Finding, not a claim on anyone's queue — filed by the video-production lane, which uses
hotcrmas the carrier app for ObjectStack promo films. Not taking this on.What we observed
In a freshly seeded database, opportunities at or above $100K are all created into a pending approval, which locks the record. On the Opportunity kanban that leaves the large majority of open cards undraggable — attempting to move one produces a
RECORD_LOCKEDrejection.Measured on our instance: 23 opportunities total, 14 non-
pending; of the cards visible on the open stages, only a small minority could actually be moved.Why it mattered to us
Dragging a card between stages is the single interaction our promo film demonstrates. We had to scan the seed set to find a card that was both visually suitable and unlocked (
Initech Cloud Migration,approval_status: not_required), and then pin the whole shoot to that one record.⚠ We deliberately did not approve anything or alter the seed to unlock cards — changing the carrier's data to suit the film would misrepresent the product's default state.
Why it may be worth a look beyond us
Anyone opening a fresh demo database and trying the board hits the same wall, and the failure presents as "drag and drop doesn't work" rather than "this record is awaiting approval".
Environment
hotcrmmain@c716a2c(17.4.0),OS_PRODUCT_STAGE=gaWhat would resolve it for us
Seed a meaningful number of open, unlocked opportunities across the live stages — or lower/vary the approval threshold in seed data so the board is demonstrable out of the box.
Context: promo-video ticket steedos-labs/video-studio#356 (private repo; the finding above is self-contained).