Skip to content

Docs site accuracy: setup, products and campaigns pages state rules the code does not have (lead round-robin doors, product price rules, campaign end date, conversion attribution) #2362

Closed

Description

@objectstack-fleet

Source

hotcrm#2360 (PR #2361, report 6463509093) measured every lead door on the shipped 18.2.0 artifact with a two-rep pool:

Door Result
anonymous POST /api/v1/forms/contact-us/submit (web-to-lead) 201; the lead is owned by a pool rep, so the round-robin assigned it
POST /api/v1/data/crm_lead/import with a blank owner, as admin, sales manager or rep 200; the lead is owned by the importer each time
POST /api/v1/data/crm_lead with a session or an API key the lead is owned by the caller

PR #2361 corrected the in-app Leads page. The Fumadocs site still says the opposite in three languages:

  • content/docs/administration/setup.mdx:68: "An ownerless lead — web-to-lead, CSV import, API capture — is assigned on insert by src/sales/objects/lead.hook.ts …"
  • content/docs/administration/setup.zh-Hans.mdx:68: 「网页表单、CSV 导入、API 采集」
  • content/docs/administration/setup.zh-Hant.mdx:70: 「網頁表單、CSV 匯入、API 擷取」

content/docs/guides/importing-your-data.mdx already agrees with the measurement, so the site contradicts itself.

Target (all four rows)

The three setup pages name web-to-lead as the door into the lead round-robin. They say that an import or an API create keeps its writer as owner, and they link the importing guide. ⛔ No behaviour change.

Done when

Grade: priority:p3. A false statement in the admin docs, with no data effect. Size: S.

Dedupe: #2360 covered the in-app page only. No open card names administration/setup.

Added by the seat: three more measured drifts (from #2330's report, comment 6463662345)

# Page Text today Measured on 18.2.0
2 content/docs/revenue/products.mdx (and the zh pages) "List price must be greater than zero"; "Cost cannot exceed list price" is a warning only and does not block save Validation refuses only a price below 0. PATCH crm_product with cost 9500 over list 9000 returns 400 VALIDATION_FAILED from product.hook.ts.
3 content/docs/marketing/campaigns.mdx (and the zh pages) "End date must be on or after the start date" POST crm_campaign with end_date == start_date returns 400 "End Date must be after Start Date".
4 content/docs/marketing/campaigns.mdx (and the zh pages), Attribution Converting a lead from a campaign credits revenue back to the campaign lead_conversion's create-opportunity step (src/sales/flows/lead-conversion.flow.ts) writes no crm_campaign, so the deal is credited only when Campaign is set by hand.

The same rule applies to every row: the text follows the code. Re-measure each row before editing. ⛔ No behaviour change. In particular, do not make conversion carry the campaign; if that is wanted, it is a separate product decision.

Filed by the repo:hotcrm lane seat (session session_01J8VVAnPkgK6CWrJa6t7Fk5) from #2360's out-of-scope finding.

Activity

  1. changed the title [-]Docs site: administration/setup says CSV-imported and API-captured leads are ownerless and round-robined; measured, only web-to-lead is (follow-up of #2360)[/-] [+]Docs site accuracy: setup, products and campaigns pages state rules the code does not have (lead round-robin doors, product price rules, campaign end date, conversion attribution)[/+] on Oct 28, 2026
  2. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Dispatch order · #2362 · repo:hotcrm seat 1 · huangyiirene · session session_01J8VVAnPkgK6CWrJa6t7Fk5 · 2026-10-28T08:16Z

    This order takes a slot freed by #2360 (PR #2361, d5f6270) and #2330 (PR #2363, 6c52f22). Lane concurrency is 2, per Irene's 「后续并发降到2」. No other card is dispatchable today: #2328 is governed, and the rest are blocked. So this card runs alone. The card body is the spec, rows 1–4.

    Container & model: S · mode:thread · model TIER_DEFAULT · effort high (the thread runs at the project default).
    Role file: objectstack-ai/objectstack .claude/agents/os-dev.md. Read it in full. hotcrm AGENTS.md binds, including Documentation discipline: English first, then .zh-Hans.mdx and .zh-Hant.mdx. Re-measure every file:line against origin/main (6c52f22 or later).
    Writes:

    • The PR goes only through the relay op pr_create: draft, base main, assignees: [huangyiirene].
    • Comments go only through scripts/pm/post-stamped.mjs.
    • ⛔ No GitHub MCP write. ⛔ No issue filing: out-of-scope findings go in the report.
    • The write budget is tight, so make two writes: the PR and the report.

    Report: the os-dev-report JSON, posted as a comment on this card and sent as the final message to the seat thread. ⛔ Start editing only after the newest Claim: on this card names your branch. Push work in progress at each milestone, so a stop loses nothing.

    Ruling (not to be re-decided)

    • The text follows the code. ⛔ No behaviour change: no new validation, no relaxed validation, and no campaign written by lead conversion.
    • Re-measure each of the four rows on the 18.2.0 dev server before editing, and record each probe in the PR. Where a row no longer holds, say so and leave that page alone.
    • Rows:
      1. administration/setup: the lead round-robin doors. Use Docs accuracy: the Leads page says CSV-imported leads are round-robined to reps, but an import makes the importer the owner; task.hook.ts header says "warns" where it refuses #2360's probes, and link the importing guide.
      2. revenue/products: the list-price floor, and the cost-over-list refusal.
      3. marketing/campaigns: the end date must be after the start date, so a same-day campaign is refused.
      4. marketing/campaigns Attribution: conversion does not carry the campaign, and crediting needs Campaign set by hand.
    • The in-app pages (src/**/docs/) already state rows 2–4 correctly. Make the site agree with them, and do not copy text across.
    • If a docs guard pins the old sentence, update its expectation to the measured text in the same commit.

    PM mechanism assumptions

    1. In-app docs, batch 2 (modules): case triage, billing hand-off, products and price books, and a marketing book with its Help entry #2330's three measurements and Docs accuracy: the Leads page says CSV-imported leads are round-robined to reps, but an import makes the importer the owner; task.hook.ts header says "warns" where it refuses #2360's door probes still hold on 6c52f22. If one does not, stop and report it.

    Serial constraints: none.


    Generated by Claude Code

  3. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Oct 28, 2026
  4. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1
    Session: session_01J8VVAnPkgK6CWrJa6t7Fk5
    Account: huangyiirene
    Branch: claude/project-thread-3dm407
    Worktree: hotcrm-issue-2362 (card thread; branch is platform-designated, the measured platform exception to claude/issue-N-slug; implementing session session_01J8VVAjhzCx8F4c3imwn9RP)
    Domain: repo:hotcrm (single-lane repo, no domain:*)
    Seat: repo:hotcrm#1
    File surface: content/docs/administration/setup*.mdx, content/docs/revenue/products*.mdx, content/docs/marketing/campaigns*.mdx (en, zh-Hans, zh-Hant); a docs guard's expectation only if it pins an old sentence; one changeset (stop on breach; explain in the report)
    Container & model: M, mode:thread, model: TIER_DEFAULT (sister repo, hand-derived), effort: the order asked high; the thread runs at the project default, which only the maintainer sets
    Clause-②: no
    Metadata-protocol: none
    Responsibility: #2362 rows 1–4: the docs site states measured behaviour; no behaviour change
    Thread-read: 6464089379
    Premise: holds — re-read at claim on hotcrm origin/main 6c52f22 (order comment 6464089379)
    Serial constraints cleared: none

  5. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 2362,
      "status": "done",
      "branch": "claude/project-thread-3dm407",
      "pr": "https://github.com/objectstack-ai/hotcrm/pull/2364",
      "session": "session_01J8VVAjhzCx8F4c3imwn9RP",
      "premise_still_valid": true,
      "summary": "All four rows re-measured on a fresh 18.2.0 dev server (origin/main 6c52f22) and all four still hold; probes are in the PR's Verification section. Setup (row 1): web-to-lead is named as the one door into the round-robin; app, API and CSV/JSON-import leads keep their writer as owner; links Import your own data (en #owners, zh pages link the page and name the section, which has no English anchor). Products (row 2): zero list price accepted, negative refused; cost above list refused, equal saves; also fixed the Pricing-fields note that said the system only warns. Campaigns (rows 3-4): end date must be after start (same-day refused); conversion does not set Campaign on the new opportunity, crediting needs it set by hand; the field is named by its shipped label Campaign instead of Source Campaign, in the Attribution paragraph and the matching sales-rep tip. en, zh-Hans, zh-Hant; no behaviour change; one patch changeset.",
      "tests": "head 737e0f0. npx vitest run test/docs-*.test.ts: Test Files 31 passed (31), Tests 585 passed (585). pnpm verify (validate, typecheck, lint, hygiene, hygiene:tokens, build, test): exit 0, Test Files 242 passed (242), Tests 4612 passed | 1 skipped (4613). No guard pinned an old sentence, so no expectation changed. Ablation: n/a, docs only.",
      "gates": "local: pnpm verify exit 0 captured before any pipe (VERIFY_EXIT=0 appended by the run). hotcrm has no dispatch-gates script, so no --ran reconciliation. PR check-runs at report time on 737e0f0: Vercel Preview Comments success, Label Pull Request success; Check Changeset, Typecheck and Build, Analyze Code (javascript), Playwright, link-check, Build and Test (22.x) in_progress.",
      "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
      "mcp_calls": "5 — reads only: issue_read x3 (get, get_comments x2), pull_request_read x1 (get_check_runs), plus subscribe_pr_activity (platform harness, not a GitHub write)",
      "api_writes": "2 — relay pr_create (fw-20261028T083607Z-09c27d, run 40657976121, objectstack-ai/hotcrm#2364, assignee huangyiirene, body read back identical 6735/6735 bytes); this os-dev-report comment via post-stamped. Plus one git push (not a REST write).",
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: none · noted, not filed — after lead conversion the campaign member's move to Converted and the campaign's Converted Leads count arrive a few seconds later (immediate read responded / 0, re-read converted / 1); the site says kept current, which holds, so nothing to change.",
        "carrier: none · noted, not filed — the setup page's checklist line under Lead routing still says assign sales_rep to every rep who should receive intake; true for web-to-lead, left as is to keep the diff on the four rows."
      ]
    }

    Generated by Claude Code

  6. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · repo:hotcrm seat 1 · session session_01J8VVAnPkgK6CWrJa6t7Fk5 · 2026-10-28T09:09Z

    Reading Probe Result
    PR #2364 GET /pulls/2364 Merged 2026-10-28T08:40Z as 353dace from head 737e0f06c0. The seat ACCEPTed that head (6464489333).
    main CI on 353dace GET /commits/353dace/check-runs All 6 runs report success.

    State: the PR's closing line closed this card as completed, and this stroke removes its lane label. In en, zh-Hans and zh-Hant, the docs site now states the measured behaviour on four points:

    • web-to-lead is the only door into the lead round-robin;
    • products refuse a negative list price and a cost above list;
    • campaigns refuse a same-day end date;
    • lead conversion does not set the opportunity's Campaign.

    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions