Skip to content

th crm: top-level module + deal economics (--mrr/--upfront) + deals update#277

Merged
brentrager merged 5 commits into
mainfrom
th-89e2b5-crm-top-level
Jul 26, 2026
Merged

th crm: top-level module + deal economics (--mrr/--upfront) + deals update#277
brentrager merged 5 commits into
mainfrom
th-89e2b5-crm-top-level

Conversation

@brentrager

Copy link
Copy Markdown
Contributor

Problem

th api crm was the only daily product surface not promoted to the top level (org/config/testing/booking/files/knowledge all are). Deals had no update command — changing value/stage after creation meant hand-rolled REST PATCHes (pearl th-cfd814) — and the economics triple the API already stores (value / mrr / implementationCost) was invisible to the CLI.

Changes

  • Top-level th crm — same Cmd tree as th api crm, promotion pattern identical to th booking et al.
  • deals create --mrr / --upfront (--upfrontimplementationCost, alias --implementation-cost)
  • New deals update <deal-id-or-title>--value/--mrr/--upfront/--title/--stage/--close-date; only passed flags change; bails when no flags given
  • deals show: MRR / Upfront / computed Year 1 (upfront + 12×mrr) lines
  • deals list: MRR column + org MRR run-rate in the totals row

Verification

  • 383 unit tests pass, incl. new parse assertions for th crm deals list and the economics flags on update
  • Dogfooded live against the Clark Insurance Group deal: th crm deals update ec7d9af6… --value 13600 --mrr 550 --upfront 7000 → PATCH 200, show renders all three + Year 1 = $13,600 ✓ (= 7000 + 12×550, matches deal value exactly)

Pearl: th-89e2b5

🤖 Generated with Claude Code

@changeset-bot

changeset-bot Bot commented Jul 26, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 1899cf8

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@brentrager
brentrager enabled auto-merge (squash) July 26, 2026 20:05
@brentrager
brentrager force-pushed the th-89e2b5-crm-top-level branch 2 times, most recently from 781b24d to 92aa00b Compare July 26, 2026 21:44
brentrager and others added 4 commits July 26, 2026 18:11
…--upfront) + deals update

th api crm was the only daily product surface not promoted to the top
level (org/config/testing/booking/files/knowledge all are). Deals also
had no update command at all — changing value/stage after creation
meant hand-rolled REST PATCHes (th-cfd814) — and the economics triple
the API already stores (value / mrr / implementationCost) was
invisible to the CLI.

- top-level `th crm` (same Cmd tree as `th api crm`)
- `deals create --mrr/--upfront` (upfront ⇄ implementationCost)
- new `deals update <deal>` — value/mrr/upfront/title/stage/close-date,
  only passed flags change, accepts id or title
- `deals show`: MRR / Upfront / computed Year-1 lines
- `deals list`: MRR column + org MRR run-rate in the totals row

Dogfooded live against the Clark Insurance Group deal (value 13600,
mrr 550, upfront 7000 — Year 1 = 7000 + 12×550 = 13600 ✓).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…d clippy allow

The Clark deal was written with stage "proposal" while the board's
column is "Proposal". The board groups by the literal deal.stage
string, so it rendered in NO column and — having no stage row, hence no
probability — counted $0 toward the forecast, while `deals show` looked
perfectly fine. $13.6k invisible.

resolve_stage_name() now canonicalizes case-insensitively against the
org's stages and refuses an unknown stage, naming the valid columns.
All three stage-writing paths (create / update / move) route through it.

Also drops the duplicated #[allow(clippy::too_many_arguments)] that
failed CI (clippy::duplicated_attributes, denied via workspace lints).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@brentrager
brentrager force-pushed the th-89e2b5-crm-top-level branch from 92aa00b to f41f547 Compare July 26, 2026 22:11
@brentrager
brentrager merged commit 2c2165d into main Jul 26, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant