Skip to content

Lead and case detail pages: show the sections a user is expected to fill even while empty (hideEmpty: false), the way #1211 did for the opportunity page #2003

Description

@objectstack-fleet

Filing gate: ③ a task the maintainer ordered directly. It was item 2 of the decision batch the repo:hotcrm seat presented in its chat (session_01ER8ntXZhYebyQ66aXWdjfT). The maintainer agreed on 2026-10-03 at about 23:0xZ, verbatim: 「决裁的三张同意」. That ruled option A, as recommended.

Who acts on it: the repo:hotcrm seat dispatches one dev.

The problem, as measured

On freshly created records under @objectstack/* 17.6.0, the platform default (objectui#8603 ruling A) hides every all-empty section:

  • Lead: 5 of 10 groups vanish: contact_info, assignment, address, duplicates, additional.
  • Case: 3 of 6 groups vanish: origin, sla, resolution.

A rep or agent opening a new record cannot see what is still to be filled. The opportunity page already shows its expected-to-fill sections empty (#1211, PR #1991). The lead and case pages do not, so the three detail pages behave inconsistently.

The ruling's shape (option A)

  • hideEmpty: false only on the group sections a user is expected to fill.
  • Derived and system sections stay hidden while empty.
  • Each choice is justified in the PR against a before/after browser table.

Initial reading, to be confirmed by measurement and not taken as decided:

  • Lead: contact_info, assignment and address shown; duplicates and additional left hidden.
  • Case: origin and sla shown; resolution left hidden on a new case.

Done when

  • src/sales/pages/lead_detail.page.ts and src/service/pages/case_detail.page.ts carry the justified keys.
  • A browser before/after table exists for a fresh lead and a fresh case.
  • pnpm verify is green.
  • There is a patch changeset.

Duplicate check

All hotcrm issues, open and closed (748, 19 REST pages). The PR #1991 / #1211 thread is the only prior work, and it covered the opportunity page alone. The seat's earlier grep of AGENTS.md and the ADRs for hideEmpty|empty section|vanish returned 0 hits.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 3, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round R73
    Session: session_01ER8ntXZhYebyQ66aXWdjfT
    Account: hotlong (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/issue-2003-lead-case-empty-groups
    Worktree: hotcrm-issue-2003
    Domain: repo:hotcrm (single-lane repo, no domain:* taxonomy)
    Seat: repo:hotcrm#1
    File surface: src/sales/pages/lead_detail.page.ts, src/service/pages/case_detail.page.ts (the hideEmpty key on their { group } sections only), pins under test/ that read them, one .changeset/2003-*.md (stop on breach; explain in the report)
    Container & model: S, mode:subagent, model: default (dispatch-gates --tier --repo objectstack-ai/hotcrm answers "no path-derived mandate … the tier stays the PM's per-card judgment call")
    Clause-②: no. This is app metadata; it touches no published schema and no accept set.
    Thread-read: none
    Serial constraints cleared: three cards are dispatched together under the maintainer's 「决裁的三张同意」: #1992 (src/service/{objects/case.*,reports,datasets,dashboards,views,data}), #2003 (src/sales/pages/lead_detail.page.ts, src/service/pages/case_detail.page.ts) and #2004 (src/sales/objects/opportunity.hook.ts, the 立项 gate test, the qualification docs). Their files are disjoint. #1992 shrinks the sla group that #2003 decides hideEmpty for; each dev is told to measure on its own tree and name that coupling. No open PR exists.


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 3, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
     "issue": 2003,
     "status": "done",
     "branch": "claude/issue-2003-lead-case-empty-groups",
     "pr": "https://github.com/objectstack-ai/hotcrm/pull/2005",
     "session": "session_01ER8ntXZhYebyQ66aXWdjfT — subagent, so this is the parent seat's id",
     "premise_still_valid": true,
     "summary": "The premise held: on fresh records under 17.6.0, a lead lost 5 of its 10 group sections (contact_info, assignment, address, duplicates, additional) and a case lost 3 of 6 (origin, sla, resolution). PR #2005 (draft, assigned to hotlong) adds `hideEmpty: false` to four `{ group }` sections: lead contact_info, address and additional, and case origin. It also adds a patch changeset. No fieldGroups change. Chromium before/after on fresh records: the lead goes from 5 sections to 8, the case from 3 to 4, and each page shows exactly the chosen sections. Each group was decided from its members, and two decisions differ from the card's initial reading. (1) Lead `additional` is ON: every member (annual_revenue, number_of_employees, description, notes) is typed by a rep, none is readonly or written by any hook or flow, and the default create form asks for all four; it is the lead's equivalent of the opportunity `notes` group from #1211, and the revert is one key. (2) Case `sla` is OFF. I decided it on the six members other than created_date, as the coordinator directed (#1992 is blocked upstream on objectstack#21646). priority, sla_due_date and is_sla_violated are in the strip. The other three are system stamps (closed_date and resolution_time_hours from case.hook at close, first_response_date from event.hook.ts). The decision holds whether or not created_date is retired. Lead `assignment` stays off because the key is inert: owner_id is in the strip, the derived list is empty, and the probe confirms nothing renders even with the key. Lead `duplicates` (written by the lead_duplicate_check hook) and case `resolution` (collected by close_case) stay hidden.",
     "tests": "pnpm verify: `OS_VERIFY_LOCK_SLOT=hotcrm-issue-2003 bash /home/user/objectstack/scripts/pm/os-verify-lock.sh -c 'NODE_OPTIONS=--max-old-space-size=4096 pnpm verify'` at HEAD 6e68fa1e (git rev-parse --short HEAD read before and after the same run) gave `os-verify-lock: VERDICT command-exit 0 · held the lock 177s`. Chain: `✓ Validation passed` · tsc --noEmit clean · lint `1 warning(s), 18 suggestion(s)` · `✓ i18n lint gate: 0 i18n/missing-* issues` · `✓ source hygiene clean` · `✓ source token ratchet clean` · `✓ Build complete` (9 author-time warnings) · `Test Files 177 passed (177)`, `Tests 3794 passed | 1 skipped (3795)`. Lint, BASE vs HEAD pages: identical output, 1 warning and 18 suggestions both times. The pages were swapped to BASE with a trap restore; after restore `git diff HEAD` was empty and both blob hashes equalled the HEAD blobs (e45cd08b95ce, 8d73fa80ea01). Author-time warning list identical, 9 to 9. Token ratchet (node scripts/check-source-token-ratchet.mjs) before and after, src/sales rows verbatim: before `interaction layer 25 3,373 111,870 27,968 31,000` and `authored total 117 10,417 399,717 99,929 107,000`; after `interaction layer 25 3,373 111,924 27,981 31,000` and `authored total 117 10,417 399,771 99,943 107,000`. Business semantics unchanged at 56,418. src/service interaction layer went from 5,592 to 5,597. No ceiling changed. Legality: RecordDetailsProps (=== ComponentPropsMap['record:details']).safeParse succeeds on both pages and keeps hideEmpty false on contact_info, address, additional and origin. Three controls per page are refused: hideEmpty 'no' (invalid_type), hideEmptyX (unrecognized_keys), collapsible beside group (custom). PageSchema.safeParse accepts all three controls, so it is not the proof. Browser (Chromium /opt/pw-browsers/chromium, port 4821, a fresh OS_HOME per boot, served record:details sections EQUAL to dist/objectstack.json before every probe): before 94668373: lead 5 cards, case 3 cards. After 1ebe784c: lead 8 cards (+ Contact Information with 2 empty rows, + Address collapsed with 1, + Additional Info collapsed with 4); case 4 cards (+ Origin & Routing with 1 empty row). Probe-only artifact with the key on all four groups left off: lead 9 cards (assignment still absent; duplicates draws 4 empty rows); case 6 cards (sla draws 4 empty rows, resolution 2). The first probe boot was VOIDED: `--artifact` run from the worktree cwd served the worktree's dist instead (served != probe on both pages, the objectstack#21501 shape). The rerun from a cwd with no config gave EQUAL. NOT MEASURED: a seeded record with values in the browser, reason: covered by reading the console bundle (31971ff1), where hideEmpty is read only in the all-empty branch, and by #1211's measurement on the same bundle. Control-byte self-scan of the three changed files and the PR body: 0 hits. No test added; no test reads hideEmpty. Files changed: src/sales/pages/lead_detail.page.ts, src/service/pages/case_detail.page.ts, .changeset/2003-lead-case-empty-groups.md. Deviations: (a) the two departures from the initial reading, above; (b) commit trailers are the model-free pair (Co-authored-by Claude, Claude-Session), per the dev contract, rather than the harness reminder's model-named line. Cleanup: every server I started was stopped by its own process group (1815, 6138, 7240, 7869); the worktree was removed without --force.",
     "mcp_calls": "0",
     "api_writes": "3 relay writes as objectstack-fleet[bot], each one POST /repos/objectstack-ai/objectstack/dispatches executed by fleet-write: (1) pr_create, POST /repos/objectstack-ai/hotcrm/pulls (draft forced), giving #2005; read-back byte-identical, 10979 bytes. (2) label-write assign, POST /repos/objectstack-ai/hotcrm/issues/2005/assignees with hotlong; read-back MATCHES. (3) this os-dev-report comment, POST /repos/objectstack-ai/hotcrm/issues/2003/comments. Plus git push to the branch (not REST). The PR's `metadata` label was not written by me (labeler).",
     "open_questions": [],
     "out_of_scope_findings": [
      "carrier: none (承接者:无) · noted in PR Acceptance notes, not filed · the token ratchet prints a shrink-only hint to re-anchor the src/sales interaction-layer ceiling to ~30,000 and the src/service one to ~6,000; that is outside this card's file surface and not a defect · dedupe words: token ratchet re-anchor ceiling headroom",
      "carrier: objectstack-ai/objectstack#21501 (existing card) · noted, not filed · reproduced it once more: `objectstack dev --artifact X` run from a cwd that holds objectstack.config.ts serves that cwd's dist/objectstack.json, not X; the served-metadata check caught it · dedupe words: artifact flag overridden cwd config served stale"
     ]
    }

    Generated by Claude Code

  3. objectstack-fleet commented on Oct 3, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT: PR #2005 at 6e68fa1e. Lead and case detail pages show the sections a user is expected to fill. repo:hotcrm seat, session_01ER8ntXZhYebyQ66aXWdjfT, 2026-10-03T23:38Z. Report: the dev's os-dev-report 5974648404.

    Probes taken by the seat itself:

    • Ancestry and checks: main 94668373 is an ancestor of 6e68fa1e. CI 9/9 success. Governed check: 0 of 3 paths, NOT governed; 56 lines.
    • Read line by line: exactly four hideEmpty: false keys:
      • lead: contact_info, address, additional;
      • case: origin.
        Each has its reason beside it, plus a patch changeset. No fieldGroups change.

    Per-group decisions, accepted on their stated grounds:

    The dev's measurements, accepted:

    Landing:

    • Authority: the maintainer's 「决裁的三张同意」 (option A for this item), and 「授权你执行pr合并」.
    • Path: ready → auto-merge → queue.

    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

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions