Skip to content

Split the Lead agreements by customer kind and drop the consent-count cap - #1061

Merged
bsiaotickchong merged 2 commits into
mainfrom
09-23-split-lead-agreements-by-customer-kind
Sep 23, 2026
Merged

bsiaotickchong merged 2 commits into
mainfrom
09-23-split-lead-agreements-by-customer-kind

Conversation

@bsiaotickchong

Copy link
Copy Markdown
Contributor

Summary

  • Splits LEAD_CARDHOLDER_AGREEMENT and LEAD_ACCOUNTHOLDER_AGREEMENT into consumer and commercial variants. A consumer and a commercial customer accept different documents, so a single type cannot identify which one was accepted.
  • Removes the maxItems: 7 cap on agreementConsents in the customer create and update requests.

Why the cap goes

It restated a bound the type list already implies, and it silently became wrong the moment a type was added — as this change demonstrates, since the list is now nine. A caller reading maxItems: 7 learns nothing they could act on.

The constraint that matters is already stated in the field description and enforced server-side: at most one entry per type. That one does not drift when the enum grows.

Compatibility

The two replaced values are not yet recorded against any customer, so no existing consent evidence refers to them.

LEAD_ACCOUNTHOLDER_AGREEMENT  →  LEAD_ACCOUNTHOLDER_CONSUMER_AGREEMENT
                                 LEAD_ACCOUNTHOLDER_COMMERCIAL_AGREEMENT
LEAD_CARDHOLDER_AGREEMENT     →  LEAD_CARDHOLDER_CONSUMER_AGREEMENT
                                 LEAD_CARDHOLDER_COMMERCIAL_AGREEMENT

Test plan

  • npm run build:openapi regenerates both bundles; verified the new values are present and the replaced ones are gone from openapi.yaml and mintlify/openapi.yaml.
  • npm run lint:openapi exits 0. The only agreement-related output is a pre-existing informational note about a missing example on AgreementConsentRequest.acceptedAt, untouched by this change.

Original PR: #1053

… cap

A consumer and a commercial customer accept different Lead cardholder and
accountholder documents, so each is its own agreement type rather than one
type covering both.

The array cap went with them. It restated a bound the type list already
implies, and any new agreement silently invalidated it. The per-type
uniqueness the description states is the real constraint.
@ls-bolt ls-bolt Bot added bolt breaking-change Introduces a breaking change to the OpenAPI spec labels Sep 23, 2026

Copy link
Copy Markdown

This stack of pull requests is managed by Graphite. Learn more about stacking.

@github-actions

github-actions Bot commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

⚠️ Breaking OpenAPI changes detected

oasdiff reports 31 error / 55 warning changes to openapi.yaml.
This PR will need approval from an API reviewer before merge.

Errors (31)

  • POST /agents/me/quotes — removed the enum value ACH_SAME_DAY of the request property destination/oneOf[subschema #1: Account]/allOf[subschema #2]/paymentRail/allOf[#/components/schemas/PaymentRail]/ [request-property-enum-value-removed].
  • POST /cards/{id}/reveal — removed the request body [request-body-removed].
  • PATCH /config — removed the enum value ACH_SAME_DAY of the request property feeConfigs/items/oneOf[#/components/schemas/RailFeeConfig]/allOf[subschema #2]/rail [request-property-enum-value-removed].
  • POST /customers — removed the enum value LEAD_ACCOUNTHOLDER_AGREEMENT of the request property oneOf[subschema #1: Individual Customer Create Request]/allOf[#/components/schemas/CustomerCreateRequest]/agreementConsents/items/type [request-property-enum-value-removed].
  • POST /customers — removed the enum value LEAD_ACCOUNTHOLDER_AGREEMENT of the request property oneOf[subschema #2: Business Customer Create Request]/allOf[#/components/schemas/CustomerCreateRequest]/agreementConsents/items/type [request-property-enum-value-removed].
  • POST /customers — removed the enum value LEAD_CARDHOLDER_AGREEMENT of the request property oneOf[subschema #1: Individual Customer Create Request]/allOf[#/components/schemas/CustomerCreateRequest]/agreementConsents/items/type [request-property-enum-value-removed].
  • POST /customers — removed the enum value LEAD_CARDHOLDER_AGREEMENT of the request property oneOf[subschema #2: Business Customer Create Request]/allOf[#/components/schemas/CustomerCreateRequest]/agreementConsents/items/type [request-property-enum-value-removed].
  • PATCH /customers/{customerId} — removed the enum value LEAD_ACCOUNTHOLDER_AGREEMENT of the request property oneOf[subschema #1: Individual Customer Update Request]/allOf[subschema #1: Customer Update Request]/agreementConsents/items/type [request-property-enum-value-removed].
  • PATCH /customers/{customerId} — removed the enum value LEAD_ACCOUNTHOLDER_AGREEMENT of the request property oneOf[subschema #2: Business Customer Update Request]/allOf[subschema #1: Customer Update Request]/agreementConsents/items/type [request-property-enum-value-removed].
  • PATCH /customers/{customerId} — removed the enum value LEAD_CARDHOLDER_AGREEMENT of the request property oneOf[subschema #1: Individual Customer Update Request]/allOf[subschema #1: Customer Update Request]/agreementConsents/items/type [request-property-enum-value-removed].
  • PATCH /customers/{customerId} — removed the enum value LEAD_CARDHOLDER_AGREEMENT of the request property oneOf[subschema #2: Business Customer Update Request]/allOf[subschema #1: Customer Update Request]/agreementConsents/items/type [request-property-enum-value-removed].
  • POST /internal-accounts — removed the enum value ACH_SAME_DAY of the request property sweepRule/allOf[subschema #1: Sweep Rule Request]/destination/allOf[subschema #1: Sweep Rule Destination Request]/paymentRail/allOf[#/components/schemas/PaymentRail]/ [request-property-enum-value-removed].
  • POST /quotes — removed the enum value ACH_SAME_DAY of the request property destination/oneOf[subschema #1: Account]/allOf[subschema #2]/paymentRail/allOf[#/components/schemas/PaymentRail]/ [request-property-enum-value-removed].
  • POST /transfer-out — removed the enum value ACH_SAME_DAY of the request property destination/paymentRail/allOf[#/components/schemas/PaymentRail]/ [request-property-enum-value-removed].
  • POST webhook:agent-action — removed the enum value ACH_SAME_DAY of the request property allOf[subschema #2]/data/quote/allOf[#/components/schemas/Quote]/destination/oneOf[subschema #1: Account]/allOf[subschema #2]/paymentRail/allOf[#/components/schemas/PaymentRail]/ [request-property-enum-value-removed].
  • POST webhook:agent-action — removed the enum value ACH_SAME_DAY of the request property allOf[subschema #2]/data/quote/allOf[#/components/schemas/Quote]/paymentInstructions/items/accountOrWalletInfo/oneOf[subschema #1: USD Bank Account]/allOf[#/components/schemas/UsdAccountInfo]/allOf[subschema #2]/paymentRails/items/ [request-property-enum-value-removed].
  • POST webhook:agent-action — removed the enum value ACH_SAME_DAY of the request property allOf[subschema #2]/data/transaction/allOf[#/components/schemas/TransactionOneOf]/oneOf[subschema #1: Incoming Transaction]/allOf[subschema #2]/source/oneOf[subschema #3: External Funding Source]/allOf[subschema #2]/paymentRail/allOf[#/components/schemas/PaymentRail]/ [request-property-enum-value-removed].
  • POST webhook:agent-action — removed the enum value ACH_SAME_DAY of the request property allOf[subschema #2]/data/transaction/allOf[#/components/schemas/TransactionOneOf]/oneOf[subschema #2: Outgoing Transaction]/allOf[subschema #2]/paymentInstructions/items/accountOrWalletInfo/oneOf[subschema #1: USD Bank Account]/allOf[#/components/schemas/UsdAccountInfo]/allOf[subschema #2]/paymentRails/items/ [request-property-enum-value-removed].
  • POST webhook:agent-action — removed the enum value ACH_SAME_DAY of the request property allOf[subschema #2]/data/transaction/allOf[#/components/schemas/TransactionOneOf]/oneOf[subschema #2: Outgoing Transaction]/allOf[subschema #2]/paymentRail/anyOf[#/components/schemas/PaymentRail]/ [request-property-enum-value-removed].
  • POST webhook:agent-action — removed the enum value ACH_SAME_DAY of the request property allOf[subschema #2]/data/transaction/allOf[#/components/schemas/TransactionOneOf]/oneOf[subschema #2: Outgoing Transaction]/allOf[subschema #2]/source/oneOf[subschema #3: External Funding Source]/allOf[subschema #2]/paymentRail/allOf[#/components/schemas/PaymentRail]/ [request-property-enum-value-removed].
  • POST webhook:customer-update — removed the enum value LEAD_ACCOUNTHOLDER_AGREEMENT of the request property allOf[subschema #2]/data/oneOf[subschema #1: Individual Customer]/allOf[#/components/schemas/Customer]/agreementConsents/items/allOf[#/components/schemas/AgreementConsentRequest]/type [request-property-enum-value-removed].
  • POST webhook:customer-update — removed the enum value LEAD_ACCOUNTHOLDER_AGREEMENT of the request property allOf[subschema #2]/data/oneOf[subschema #2: Business Customer]/allOf[#/components/schemas/Customer]/agreementConsents/items/allOf[#/components/schemas/AgreementConsentRequest]/type [request-property-enum-value-removed].
  • POST webhook:customer-update — removed the enum value LEAD_CARDHOLDER_AGREEMENT of the request property allOf[subschema #2]/data/oneOf[subschema #1: Individual Customer]/allOf[#/components/schemas/Customer]/agreementConsents/items/allOf[#/components/schemas/AgreementConsentRequest]/type [request-property-enum-value-removed].
  • POST webhook:customer-update — removed the enum value LEAD_CARDHOLDER_AGREEMENT of the request property allOf[subschema #2]/data/oneOf[subschema #2: Business Customer]/allOf[#/components/schemas/Customer]/agreementConsents/items/allOf[#/components/schemas/AgreementConsentRequest]/type [request-property-enum-value-removed].
  • POST webhook:external-account-status — removed the enum value ACH_SAME_DAY of the request property allOf[subschema #2]/data/allOf[subschema #1]/accountInfo/oneOf[subschema #31: USD Account]/allOf[#/components/schemas/UsdAccountInfo]/allOf[subschema #2]/paymentRails/items/ [request-property-enum-value-removed].
  • POST webhook:incoming-payment — removed the enum value ACH_SAME_DAY of the request property allOf[subschema #2]/data/allOf[subschema #1: Incoming Transaction]/allOf[subschema #2]/source/oneOf[subschema #3: External Funding Source]/allOf[subschema #2]/paymentRail/allOf[#/components/schemas/PaymentRail]/ [request-property-enum-value-removed].
  • POST webhook:internal-account-status — removed the enum value ACH_SAME_DAY of the request property allOf[subschema #2]/data/fundingPaymentInstructions/items/accountOrWalletInfo/oneOf[subschema #1: USD Bank Account]/allOf[#/components/schemas/UsdAccountInfo]/allOf[subschema #2]/paymentRails/items/ [request-property-enum-value-removed].
  • POST webhook:internal-account-status — removed the enum value ACH_SAME_DAY of the request property allOf[subschema #2]/data/sweepRule/allOf[subschema #1: Sweep Rule]/destination/allOf[subschema #1: Sweep Rule Destination]/paymentRail/allOf[#/components/schemas/PaymentRail]/ [request-property-enum-value-removed].
  • POST webhook:outgoing-payment — removed the enum value ACH_SAME_DAY of the request property allOf[subschema #2]/data/allOf[subschema #2]/paymentInstructions/items/accountOrWalletInfo/oneOf[subschema #1: USD Bank Account]/allOf[#/components/schemas/UsdAccountInfo]/allOf[subschema #2]/paymentRails/items/ [request-property-enum-value-removed].
  • POST webhook:outgoing-payment — removed the enum value ACH_SAME_DAY of the request property allOf[subschema #2]/data/allOf[subschema #2]/paymentRail/anyOf[#/components/schemas/PaymentRail]/ [request-property-enum-value-removed].
  • POST webhook:outgoing-payment — removed the enum value ACH_SAME_DAY of the request property allOf[subschema #2]/data/allOf[subschema #2]/source/oneOf[subschema #3: External Funding Source]/allOf[subschema #2]/paymentRail/allOf[#/components/schemas/PaymentRail]/ [request-property-enum-value-removed].

Warnings (55)

Show sample
  • GET /config — removed the optional property cardConfigs/panRevealCssUrl from the response with the 200 status [response-optional-property-removed].
  • PATCH /config — removed the request property cardConfigs/panRevealCssUrl [request-property-removed].
  • PATCH /config — removed the optional property cardConfigs/panRevealCssUrl from the response with the 200 status [response-optional-property-removed].
  • GET /customers — added the new LEAD_ACCOUNTHOLDER_COMMERCIAL_AGREEMENT enum value to the data/items/oneOf[subschema #1: Individual Customer]/allOf[#/components/schemas/Customer]/agreementConsents/items/allOf[#/components/schemas/AgreementConsentRequest]/type response property for the response status 200 [response-property-enum-value-added]. Adding new enum values to response could be unexpected for clients, use x-extensible-enum instead.
  • GET /customers — added the new LEAD_ACCOUNTHOLDER_COMMERCIAL_AGREEMENT enum value to the data/items/oneOf[subschema #2: Business Customer]/allOf[#/components/schemas/Customer]/agreementConsents/items/allOf[#/components/schemas/AgreementConsentRequest]/type response property for the response status 200 [response-property-enum-value-added]. Adding new enum values to response could be unexpected for clients, use x-extensible-enum instead.
  • GET /customers — added the new LEAD_ACCOUNTHOLDER_CONSUMER_AGREEMENT enum value to the data/items/oneOf[subschema #1: Individual Customer]/allOf[#/components/schemas/Customer]/agreementConsents/items/allOf[#/components/schemas/AgreementConsentRequest]/type response property for the response status 200 [response-property-enum-value-added]. Adding new enum values to response could be unexpected for clients, use x-extensible-enum instead.
  • GET /customers — added the new LEAD_ACCOUNTHOLDER_CONSUMER_AGREEMENT enum value to the data/items/oneOf[subschema #2: Business Customer]/allOf[#/components/schemas/Customer]/agreementConsents/items/allOf[#/components/schemas/AgreementConsentRequest]/type response property for the response status 200 [response-property-enum-value-added]. Adding new enum values to response could be unexpected for clients, use x-extensible-enum instead.
  • GET /customers — added the new LEAD_CARDHOLDER_COMMERCIAL_AGREEMENT enum value to the data/items/oneOf[subschema #1: Individual Customer]/allOf[#/components/schemas/Customer]/agreementConsents/items/allOf[#/components/schemas/AgreementConsentRequest]/type response property for the response status 200 [response-property-enum-value-added]. Adding new enum values to response could be unexpected for clients, use x-extensible-enum instead.
  • GET /customers — added the new LEAD_CARDHOLDER_COMMERCIAL_AGREEMENT enum value to the data/items/oneOf[subschema #2: Business Customer]/allOf[#/components/schemas/Customer]/agreementConsents/items/allOf[#/components/schemas/AgreementConsentRequest]/type response property for the response status 200 [response-property-enum-value-added]. Adding new enum values to response could be unexpected for clients, use x-extensible-enum instead.
  • GET /customers — added the new LEAD_CARDHOLDER_CONSUMER_AGREEMENT enum value to the data/items/oneOf[subschema #1: Individual Customer]/allOf[#/components/schemas/Customer]/agreementConsents/items/allOf[#/components/schemas/AgreementConsentRequest]/type response property for the response status 200 [response-property-enum-value-added]. Adding new enum values to response could be unexpected for clients, use x-extensible-enum instead.
  • GET /customers — added the new LEAD_CARDHOLDER_CONSUMER_AGREEMENT enum value to the data/items/oneOf[subschema #2: Business Customer]/allOf[#/components/schemas/Customer]/agreementConsents/items/allOf[#/components/schemas/AgreementConsentRequest]/type response property for the response status 200 [response-property-enum-value-added]. Adding new enum values to response could be unexpected for clients, use x-extensible-enum instead.
  • POST /customers — added the new LEAD_ACCOUNTHOLDER_COMMERCIAL_AGREEMENT enum value to the oneOf[subschema #1: Individual Customer]/allOf[#/components/schemas/Customer]/agreementConsents/items/allOf[#/components/schemas/AgreementConsentRequest]/type response property for the response status 201 [response-property-enum-value-added]. Adding new enum values to response could be unexpected for clients, use x-extensible-enum instead.
  • POST /customers — added the new LEAD_ACCOUNTHOLDER_COMMERCIAL_AGREEMENT enum value to the oneOf[subschema #2: Business Customer]/allOf[#/components/schemas/Customer]/agreementConsents/items/allOf[#/components/schemas/AgreementConsentRequest]/type response property for the response status 201 [response-property-enum-value-added]. Adding new enum values to response could be unexpected for clients, use x-extensible-enum instead.
  • POST /customers — added the new LEAD_ACCOUNTHOLDER_CONSUMER_AGREEMENT enum value to the oneOf[subschema #1: Individual Customer]/allOf[#/components/schemas/Customer]/agreementConsents/items/allOf[#/components/schemas/AgreementConsentRequest]/type response property for the response status 201 [response-property-enum-value-added]. Adding new enum values to response could be unexpected for clients, use x-extensible-enum instead.
  • POST /customers — added the new LEAD_ACCOUNTHOLDER_CONSUMER_AGREEMENT enum value to the oneOf[subschema #2: Business Customer]/allOf[#/components/schemas/Customer]/agreementConsents/items/allOf[#/components/schemas/AgreementConsentRequest]/type response property for the response status 201 [response-property-enum-value-added]. Adding new enum values to response could be unexpected for clients, use x-extensible-enum instead.
  • POST /customers — added the new LEAD_CARDHOLDER_COMMERCIAL_AGREEMENT enum value to the oneOf[subschema #1: Individual Customer]/allOf[#/components/schemas/Customer]/agreementConsents/items/allOf[#/components/schemas/AgreementConsentRequest]/type response property for the response status 201 [response-property-enum-value-added]. Adding new enum values to response could be unexpected for clients, use x-extensible-enum instead.
  • POST /customers — added the new LEAD_CARDHOLDER_COMMERCIAL_AGREEMENT enum value to the oneOf[subschema #2: Business Customer]/allOf[#/components/schemas/Customer]/agreementConsents/items/allOf[#/components/schemas/AgreementConsentRequest]/type response property for the response status 201 [response-property-enum-value-added]. Adding new enum values to response could be unexpected for clients, use x-extensible-enum instead.
  • POST /customers — added the new LEAD_CARDHOLDER_CONSUMER_AGREEMENT enum value to the oneOf[subschema #1: Individual Customer]/allOf[#/components/schemas/Customer]/agreementConsents/items/allOf[#/components/schemas/AgreementConsentRequest]/type response property for the response status 201 [response-property-enum-value-added]. Adding new enum values to response could be unexpected for clients, use x-extensible-enum instead.
  • POST /customers — added the new LEAD_CARDHOLDER_CONSUMER_AGREEMENT enum value to the oneOf[subschema #2: Business Customer]/allOf[#/components/schemas/Customer]/agreementConsents/items/allOf[#/components/schemas/AgreementConsentRequest]/type response property for the response status 201 [response-property-enum-value-added]. Adding new enum values to response could be unexpected for clients, use x-extensible-enum instead.
  • GET /customers/agreements — added the new LEAD_ACCOUNTHOLDER_COMMERCIAL_AGREEMENT enum value to the data/items/type response property for the response status 200 [response-property-enum-value-added]. Adding new enum values to response could be unexpected for clients, use x-extensible-enum instead.
  • GET /customers/agreements — added the new LEAD_ACCOUNTHOLDER_CONSUMER_AGREEMENT enum value to the data/items/type response property for the response status 200 [response-property-enum-value-added]. Adding new enum values to response could be unexpected for clients, use x-extensible-enum instead.
  • GET /customers/agreements — added the new LEAD_CARDHOLDER_COMMERCIAL_AGREEMENT enum value to the data/items/type response property for the response status 200 [response-property-enum-value-added]. Adding new enum values to response could be unexpected for clients, use x-extensible-enum instead.
  • GET /customers/agreements — added the new LEAD_CARDHOLDER_CONSUMER_AGREEMENT enum value to the data/items/type response property for the response status 200 [response-property-enum-value-added]. Adding new enum values to response could be unexpected for clients, use x-extensible-enum instead.
  • DELETE /customers/{customerId} — added the new LEAD_ACCOUNTHOLDER_COMMERCIAL_AGREEMENT enum value to the oneOf[subschema #1: Individual Customer]/allOf[#/components/schemas/Customer]/agreementConsents/items/allOf[#/components/schemas/AgreementConsentRequest]/type response property for the response status 200 [response-property-enum-value-added]. Adding new enum values to response could be unexpected for clients, use x-extensible-enum instead.
  • DELETE /customers/{customerId} — added the new LEAD_ACCOUNTHOLDER_COMMERCIAL_AGREEMENT enum value to the oneOf[subschema #2: Business Customer]/allOf[#/components/schemas/Customer]/agreementConsents/items/allOf[#/components/schemas/AgreementConsentRequest]/type response property for the response status 200 [response-property-enum-value-added]. Adding new enum values to response could be unexpected for clients, use x-extensible-enum instead.
  • …and 30 more warnings.

Detected by oasdiff. Full report: job summary or the oasdiff-report artifact.

@greptile-apps

greptile-apps Bot commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 4/5

The PR is not safe to merge until the removed enum values are preserved or the breaking contract is released under a new API version.

Findings

  1. P1 Enum Removal Breaks Compatibility ▶
  2. P2 Customer Kind Mapping Missing ▶
Fix with agent prompt
### Issue 1
openapi/components/schemas/customers/AgreementType.yaml:14-18
Removing `LEAD_ACCOUNTHOLDER_AGREEMENT` and `LEAD_CARDHOLDER_AGREEMENT` makes previously valid requests and generated enum constants invalid in the existing `2025-10-13` API contract. This violates the repository directive that breaking OpenAPI changes must bump `info.version` and use a matching new `servers.url`. Preserve the old values or release the replacements under a new API version.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

### Issue 2
openapi/components/schemas/customers/AgreementType.yaml:5-8
The contract represents customer kind as `INDIVIDUAL` or `BUSINESS`, but this description introduces `consumer` and `commercial` without defining how they map. Because callers must choose an agreement type themselves, this ambiguity can cause them to submit and record the wrong consent. Explicitly state which `customerType` corresponds to each agreement variant.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Summary

The PR divides the Lead accountholder and cardholder agreement identifiers into consumer and commercial variants, removes the fixed agreementConsents item cap, and refreshes both generated OpenAPI bundles.

  • The shared agreement schema now exposes nine agreement identifiers.
  • Customer creation and update no longer advertise a fixed consent-array maximum.
  • The enum replacement is breaking under the repository’s compatibility policy and needs versioning or a compatibility path.
  • The consumer/commercial terminology should be mapped explicitly to the API’s INDIVIDUAL/BUSINESS customer types.
Diagram
%%{init: {'theme': 'neutral'}}%%
flowchart LR
  A[AgreementType source schema] --> B[Agreement catalog responses]
  A --> C[Customer consent requests]
  C --> D[Customer create]
  C --> E[Customer update]
  A --> F[Generated openapi.yaml]
  A --> G[Generated Mintlify bundle]
Loading

Reviews (1) · Last reviewed commit: "Split the Lead agreements by customer ki..."

Comment on lines +14 to +18
- LEAD_ACCOUNTHOLDER_CONSUMER_AGREEMENT
- LEAD_ACCOUNTHOLDER_COMMERCIAL_AGREEMENT
- LEAD_PRIVACY_POLICY
- LEAD_CARDHOLDER_AGREEMENT
- LEAD_CARDHOLDER_CONSUMER_AGREEMENT
- LEAD_CARDHOLDER_COMMERCIAL_AGREEMENT

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Enum Removal Breaks Compatibility

Removing LEAD_ACCOUNTHOLDER_AGREEMENT and LEAD_CARDHOLDER_AGREEMENT makes previously valid requests and generated enum constants invalid in the existing 2025-10-13 API contract. This violates the repository directive that breaking OpenAPI changes must bump info.version and use a matching new servers.url. Preserve the old values or release the replacements under a new API version.

Context Used: CLAUDE.md (source)

Knowledge Base Used:

Prompt To Fix With AI
This is a comment left during a code review.
Path: openapi/components/schemas/customers/AgreementType.yaml
Line: 14-18

Comment:
**Enum Removal Breaks Compatibility**

Removing `LEAD_ACCOUNTHOLDER_AGREEMENT` and `LEAD_CARDHOLDER_AGREEMENT` makes previously valid requests and generated enum constants invalid in the existing `2025-10-13` API contract. This violates the repository directive that breaking OpenAPI changes must bump `info.version` and use a matching new `servers.url`. Preserve the old values or release the replacements under a new API version.

**Context Used:** CLAUDE.md ([source](https://github.com/lightsparkdev/grid-api/blob/main/CLAUDE.md))

**Knowledge Base Used:**
- [Grid API contract](https://app.greptile.com/lightspark/-/custom-context/knowledge-base/lightsparkdev/grid-api/-/docs/api-contract.md)
- [Contract validation workflows](https://app.greptile.com/lightspark/-/custom-context/knowledge-base/lightsparkdev/grid-api/-/docs/contract-validation-workflows.md)

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not treating this as breaking: the two values shipped 8 days ago in #990 and no backend ever accepted them - sparkcore implements neither agreementConsents nor GET /customers/agreements, so no request using them was ever valid. The repo's breaking-change CI agrees (Detect breaking changes passes). Keeping dead aliases would instead ship four spellings for two documents. Happy to bump info.version and servers.url if you'd rather play it safe.


🤖 girded-zenith-16(#16) | Feedback

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That context is sufficient to resolve my concern. PR #990 explicitly shipped these as spec/docs-only changes, with backend support deferred, and documented that no consent evidence could yet exist. If Sparkcore implements neither the consent field nor the agreements endpoint, the removed enum values could not have been accepted by the service.

With the breaking-change check passing, this is a correction to an unimplemented contract rather than a live wire-compatibility break. I withdraw the version-bump finding; keeping the obsolete aliases would indeed leave four spellings for two documents.

Comment on lines +5 to +8
type does not. Accepting one agreement never implies acceptance of another,
even when two agreements share a hosted page.
even when two agreements share a hosted page. A consumer and a commercial
customer accept different cardholder and accountholder documents, so each is
its own type.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Customer Kind Mapping Missing

The contract represents customer kind as INDIVIDUAL or BUSINESS, but this description introduces consumer and commercial without defining how they map. Because callers must choose an agreement type themselves, this ambiguity can cause them to submit and record the wrong consent. Explicitly state which customerType corresponds to each agreement variant.

Knowledge Base Used: Customers and accounts API

Prompt To Fix With AI
This is a comment left during a code review.
Path: openapi/components/schemas/customers/AgreementType.yaml
Line: 5-8

Comment:
**Customer Kind Mapping Missing**

The contract represents customer kind as `INDIVIDUAL` or `BUSINESS`, but this description introduces `consumer` and `commercial` without defining how they map. Because callers must choose an agreement type themselves, this ambiguity can cause them to submit and record the wrong consent. Explicitly state which `customerType` corresponds to each agreement variant.

**Knowledge Base Used:** [Customers and accounts API](https://app.greptile.com/lightspark/-/custom-context/knowledge-base/lightsparkdev/grid-api/-/docs/customers-and-accounts-api.md)

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch - the description now says an INDIVIDUAL customer accepts the _CONSUMER_ variant and a BUSINESS customer the _COMMERCIAL_ one, using the contract's own customerType spellings.


🤖 girded-zenith-16(#16) | Feedback

Co-Authored-By: bsiaotickchong <bsiaotickchong@users.noreply.github.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

3 Skipped Deployments
Project Deployment Actions Updated
grid-cards-demo Ignored Ignored Preview Sep 23, 2026 8:42pm UTC
grid-flow-builder Ignored Ignored Preview Sep 23, 2026 8:42pm UTC
grid-wallet-demo Ignored Ignored Preview Sep 23, 2026 8:42pm UTC

Request Review

@mintlify

mintlify Bot commented Sep 23, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated
Grid 🟢 Ready View Preview Sep 23, 2026, 8:42 PM

@ls-bolt

ls-bolt Bot commented Sep 23, 2026

Copy link
Copy Markdown
Contributor

⚡ Review ledger

Round 1

  1. Greptile — "Customer Kind Mapping Missing": the description says consumer/commercial but the contract spells customer kind INDIVIDUAL/BUSINESS → FIXED in openapi/components/schemas/customers/AgreementType.yaml. The description now maps them explicitly: an INDIVIDUAL customer accepts the _CONSUMER_ variant, a BUSINESS customer the _COMMERCIAL_ one. A grep confirmed "consumer"/"commercial" appeared nowhere else in the contract as customer-kind terminology, so this was the only ambiguity of its kind. Bundles regenerated with make build; make lint-openapi reports no new findings.

  2. Greptile — "Enum Removal Breaks Compatibility": removing LEAD_ACCOUNTHOLDER_AGREEMENT and LEAD_CARDHOLDER_AGREEMENT invalidates previously valid requests under the 2025-10-13 contract, so info.version and servers.url must bump → NOT APPLICABLE, on three independent checks:

    • Nothing could have sent them. Both values landed 8 days ago in feat(customers): accept typed agreement consents for seven documents #990 (2026-09-15). No backend has ever accepted them: sparkcore implements neither the agreementConsents field nor GET /customers/agreements, which I verified against origin/main. A value no endpoint reads cannot appear in a previously valid request.
    • The repo's own gate disagrees. Detect breaking changes passes on this PR.
    • Keeping them would be worse. The two names are precisely what the reviewer asked to remove — @bsiaotickchong's review on webdev#35941 said these are different documents per consumer vs commercial. Retaining the ambiguous spellings alongside the new ones would ship four identifiers for two documents, with no rule saying which to send.

    Flagged rather than decided unilaterally: if we'd rather treat any enum removal as breaking regardless of reachability, the fix is a one-line info.version bump plus the matching servers.url, and I'll push it on request.

@bsiaotickchong
bsiaotickchong merged commit 18dd191 into main Sep 23, 2026
10 of 11 checks passed
@bsiaotickchong
bsiaotickchong deleted the 09-23-split-lead-agreements-by-customer-kind branch September 23, 2026 21:22

This branch was successfully deployed

1 active deployment
staging - mintlify — 9e0a7888 Deployed Sep 23, 2026 by mintlify[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bolt breaking-change Introduces a breaking change to the OpenAPI spec

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants