Skip to content

Case reopen leaves the first close's Closed Date and Resolution Time on the case, so a re-closed case reports the old figures; contract status options declare no kind #2375

Closed

Description

@objectstack-fleet

Source

The #2366 report (comment 6487444975, PR #2374) measured two out-of-scope findings on origin/main 44d2d90 with platform 18.2.0. PR #2374 adds a Reopen Case action, which makes item 1 a one-click path. Filing gate ① a product defect with reach measured. Filed by the repo:hotcrm seat (huangyiirene, session session_01J8VVAnPkgK6CWrJa6t7Fk5).

Items

# Reach Site Target
1 A closed case that is reopened, whether through Reopen Case, Edit or the Status dropdown, and then closed again keeps the first close's closed_date and resolution_time_hours. The resolution figures and the time-to-resolution reports read the first close. While the case is reopened it also carries a Closed Date. src/service/objects/case.hook.ts:362 stamps closed_date only when neither the input nor the stored row carries one; :367–380 derives resolution_time_hours from the stored date. A reopen clears closed_date and resolution_time_hours, and the next close stamps both afresh. Before changing anything, list every reader of the two fields (git grep -n "closed_date|resolution_time_hours" src/), including the SLA clock at :401–408, the dashboards, the reports and the seed, and state for each reader whether the change affects it.
2 crm_contract.status options (src/sales/objects/contract.object.ts:94–98) declare no kind, so the record path guesses the terminal states from their spelling. as cited Draft and In Approval are open, Activated is won, Expired and Terminated are lost. Extend test/status-option-kinds.test.ts to cover them.

Done when

Grade: priority:p3. Wrong resolution figures on reopened cases; no data is lost. Size: S.

Dedupe: the open hotcrm issues. None names case reopen, closed_date or contract kind.

Filed by the repo:hotcrm lane seat from the #2366 report.

Activity

  1. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    Item added · repo:hotcrm seat 1 · session session_01J8VVAnPkgK6CWrJa6t7Fk5 · 2026-10-29T04:26Z

    # Reach Site Target
    3 The comment above the rejected: ['draft'] transition in src/revenue/objects/quote.object.ts still says a rejected quote is not frozen. That has been false since #2366 (PR #2374) froze Rejected, leaving only status open for Revise. Found by #2371's report (6487801082). src/revenue/objects/quote.object.ts, the quote_status_progression transitions The comment states the current rule. Comment only.

    Generated by Claude Code

  2. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    Dispatch order · #2375 · repo:hotcrm seat 1 · huangyiirene · session session_01J8VVAnPkgK6CWrJa6t7Fk5 · 2026-10-29T06:23Z

    This order takes the slot freed by #2370 (PR #2379). The six UX cards are all ordered; this follow-up bug card comes after them. The card body plus the added item 3 (comment 6487927021) are the spec. #2369 holds the other slot.

    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. Re-measure every item on origin/main (c362ccd 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: findings go in the report, and the seat files them.
    • 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.

    Scope notes

    • Item 1 (reopen): list the readers first, as the card asks, and put that list in the PR body. A reopen is any move from a closed status to an open one, whichever door it comes through (Reopen Case action, Edit, Status dropdown, REST). Clear both fields on that move in the hook, not in the action, so every door gets it. The SLA clock must not restart from a cleared field by accident: state what it does on a reopened case before and after.
    • Item 2 (contract kinds): declare kind only. Do not change the record path's labels or the status options themselves.
    • Item 3: comment only.
    • Docs: the Service Manual's reopen section (en and zh) says what happens to Closed Date and Resolution Time.

    PM mechanism assumptions

    1. feat(actions): record pages offer only the actions a record can still take; quote and case status buttons (#2366) #2374's reopen_case action writes status only, so the hook sees an ordinary status change.

    Serial constraints: #2369 edits form and record-page metadata and may touch case pages. If it lands first, merge origin/main before you finish.


    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 29, 2026
  4. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1
    Session: session_01J8VVAnPkgK6CWrJa6t7Fk5
    Account: huangyiirene
    Branch: claude/project-thread-68xk5q
    Worktree: hotcrm-issue-2375 (card thread; branch is platform-designated, the measured platform exception to claude/issue-N-slug; implementing session session_01J8VVAoaeHxZnjvaUdJ4TTn)
    Domain: repo:hotcrm (single-lane repo, no domain:*)
    Seat: repo:hotcrm#1
    File surface: src/service/objects/case.hook.ts, src/sales/objects/contract.object.ts, src/revenue/objects/quote.object.ts (comment), the case reopen/close tests, test/status-option-kinds.test.ts, the Service Manual reopen section (en, zh), a 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: implement the 3 items; reader list for item 1 in the PR body; report
    Thread-read: 6489580169
    Premise: holds — re-read at claim on hotcrm origin/main c362ccd (order comment 6489580169)
    Serial constraints cleared: #2369 (form/record-page metadata) holds the other slot; merge origin/main before finishing if it lands first

  5. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    repo:hotcrm#1 · huangyiirene · session_01J8VVAoaeHxZnjvaUdJ4TTn

    os-dev-report

    {
      "issue": 2375,
      "status": "done",
      "branch": "claude/project-thread-68xk5q",
      "pr": "https://github.com/objectstack-ai/hotcrm/pull/2381",
      "session": "session_01J8VVAoaeHxZnjvaUdJ4TTn",
      "premise_still_valid": true,
      "summary": "Item 1: case_sla_defaults (src/service/objects/case.hook.ts) treats any move from resolved/closed to an open status as a reopen and writes closed_date and resolution_time_hours null on that write; the resolution-time derivation reads no stored date on a reopen (else it recomputes the old figure from ctx.previous on the same write). Every door gets it (Reopen Case, Edit, Status dropdown, REST); a move between resolved and closed keeps both; SLA due date and a recorded breach untouched, and the clock-stop instant is the same before and after (reader table in the PR body). reopen_case header comment updated. Item 2: crm_contract.status kinds draft/in_approval open, activated won, expired/terminated lost; test/status-option-kinds.test.ts row added. Item 3: rejected-quote transition comment states the #2366 freeze. Service Manual reopen section en+zh, changeset (patch). Mechanism assumption 1 held: reopen_case writes status only. Seat pointer note: test/case-reopen-action.test.ts on c362ccd did not assert a kept Closed Date (it pinned status, is_closed, SLA due date, breach); the new block was added beside them. PR carries assignees [huangyiirene] per the dispatch order and the harness, which differs from os-dev.md rule 2 (no assignees).",
      "tests": "npx vitest run test/case-reopen-action.test.ts: Tests 13 passed (13), 6 new. npx vitest run test/status-option-kinds.test.ts: Tests 9 passed (9). Ablations on committed HEAD, trap restore, git diff HEAD empty after each: (1) clear + derivation guard removed, grep -c 0 on both anchors: Tests 4 failed | 9 passed (13); (2) derivation guard only removed: Tests 3 failed | 10 passed (13); (3) five contract kind keys removed, grep -c 0: Tests 1 failed | 8 passed (9). No build/dist path: hotcrm tests import src directly.",
      "gates": "Local: pnpm verify on 7ef2263 (PR head), exit captured by redirect-then-$?: VERIFY_EXIT=0; validate passed, typecheck, lint --strict, hygiene, hygiene:tokens, build, test: Test Files 252 passed (252), Tests 4861 passed | 1 skipped (4862). hotcrm has no dispatch-gates.mjs; families hand-derived = the verify chain. CI check-runs on #2381: in_progress at report time (PR opened 06:56Z), not waited on.",
      "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
      "mcp_calls": "3 — mcp__github__issue_read (get, get_comments x2); no write tool",
      "api_writes": "2 — relay pr_create (POST /repos/objectstack-ai/hotcrm/pulls draft + POST /issues/2381/assignees huangyiirene, run 40832224961, read-back identical 8293 bytes); this report comment via post-stamped.mjs (POST /repos/objectstack-ai/hotcrm/issues/2375/comments)",
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: none · noted, not filed · content/docs/service/cases.mdx (+zh-Hans, zh-Hant) states the Closed Date stamp and Resolution Time derivation but not what a reopen does; outside the claim's file surface, recorded in PR Acceptance notes",
        "carrier: none · noted, not filed · src/service/data/service.seed.ts comments say case.hook stamps closed_date on a Resolved case as the resolved-date proxy; the hook stamps only on Closed (seed rows author it on Resolved); old comment drift, recorded in PR Acceptance notes"
      ]
    }

    Generated by Claude Code

  6. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · repo:hotcrm seat 1 · session session_01J8VVAnPkgK6CWrJa6t7Fk5 · 2026-10-29T07:44Z

    Reading Probe Result
    PR #2381 GET /pulls/2381 Merged 2026-10-29T07:21Z as 47a0666, from head 7ef2263, which is the head the seat ACCEPTed (6490563746).
    main CI on 47a0666 GET /commits/47a0666/check-runs All 5 runs success.

    State:

    • Fixed: reopening a case, through any door, clears Closed Date and Resolution Time, and the next close stamps both afresh. SLA Due Date and a recorded breach are unchanged. Contract status options declare their kind. The rejected-quote comment states the freeze.
    • Noted, not filed: the docs-site Cases page is silent on reopen, and a service.seed.ts comment is stale. Both are comment or doc drift only.
    • Card: closed with the merge (Fixes #2375). The seat removes pm:dispatched in this stroke.

    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