Skip to content

Require win/loss reasons on close and surface win/loss analytics #593

Description

@os-zhuang

Batch-2 (business completeness) item from the 2026-08-02 review. Small scope, closes an existing loop.

Problem

crm_opportunity.win_reason / loss_reason / loss_details exist, and the loss_reason field comment even says "required when stage moves to closed_"* — but nothing enforces it (crm_case has exactly the pattern needed: resolution_required_for_closed). No report or dashboard widget consumes the fields either, so they are empty and invisible.

Scope

  1. Enforce capture: requiredWhen conditional rules (v17, server-enforced — already available on the pinned protocol) or a cross_field validation — loss_reason required on closed_lost, win_reason on closed_won.
  2. Analytics: win-rate metric (won / (won+lost)) by owner and by lead source; loss-reason breakdown widget; both feed from opportunity_metrics (add measures as needed).
  3. i18n for any new labels in all 4 locales (the reason picklist values are among the 15 keys already missing in ja/es — see i18n: 205 warnings hidden by --skip-i18n; broken option keys and untranslated navigation #494).

Acceptance

  • Closing an opportunity without the applicable reason is rejected server-side.
  • Sales dashboard shows win rate and a loss-reason breakdown with seeded data.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or requestpm:dispatchedDispatched to a dev agent by /pm-dispatchpm:queueReady for the PM dispatch loopprio:p0Blocking the current release goal — do first

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions