Skip to content

[finding] What should a drafted contract inherit from its accepted quote? contract_term_months / start_date / contract_type are unexamined hardcoded defaults #1129

Description

@yinlianghui

Split out of #873 by the PM's Q1 ruling on that card. #873 fixed one specific thing — a rationale the code did not honour: _picklists.ts justified Quote and Contract sharing one payment-terms vocabulary with "an accepted quote's terms carry over to the contract" and no such copy existed. That is now fixed (PR for #873).

This card is the different question that #873 deliberately refused to fold in: nobody ever claimed the rest of the drafted contract was inherited, so those values are unexamined defaults, not falsified claims. They deserve one deliberate answer rather than a one-line patch each.

What quote_on_accepted hardcodes today

src/objects/quote.hook.ts, the contract document it drafts:

  • contract_term_months: 12 — a literal. The field is required + notNull + min: 1 on crm_contract, so the hook must supply something; 12 is a guess with nothing behind it.
  • start_date: today — the date the quote happened to be accepted, which is not necessarily the date the customer's term begins.
  • end_date — derived from those two, so it inherits both guesses.
  • contract_type: 'subscription' — a literal. crm_contract.contract_type declares six values (subscription / service / license / partnership / nda / msa) and has no option default, so this hardcode is the only thing that ever picks one. Every auto-drafted contract in the app is a subscription.

The other half: quote fields that reach nothing

crm_quote also carries shipping_terms, billing_address, shipping_address and description, none of which reach the contract. That may well be correct — but it has never been decided either, which is the same gap seen from the other side.

Why this is a product question, not a bug

The three hardcodes are internally consistent and nothing crashes. Judging them needs a business answer about what an auto-drafted contract is for:

  1. Is the draft a faithful transcription of what was sold (in which case the term and type have to come from somewhere on the quote, and the quote has nowhere to put them — that is a schema change), or
  2. is it a starting point an admin completes (in which case today's defaults are fine, and what is missing is that nothing marks them as defaults rather than decisions — the exact complaint [观察] 共用 PAYMENT_TERMS_OPTIONS 的理由是「报价的付款条款要能原样落到合同上」,但 quote_on_accepted 根本不复制 payment_terms #873 recorded about payment_terms)?

Reading 1 implies new authorable fields on crm_quote and a wider copy. Reading 2 implies leaving the values alone and making their provenance visible. Both are larger than a hook edit, and picking one by accident is how the payment_terms drift happened in the first place.

Not in scope here

Filed unassigned as an observation, per Prime Directive #10. No user hits a crash today.

Refs #873 #490 #714


Generated by Claude Code

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    metadataDeclarative metadata — schema, security posture, UI surfaces

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions