Skip to content

feat(openapi): add CardTransaction to TransactionOneOf for the transaction list#622

Merged
benwgold merged 2 commits into
mainfrom
06-25-grid-card-txn-in-transaction-oneof
Jun 27, 2026
Merged

feat(openapi): add CardTransaction to TransactionOneOf for the transaction list#622
benwgold merged 2 commits into
mainfrom
06-25-grid-card-txn-in-transaction-oneof

Conversation

@benwgold

Copy link
Copy Markdown
Contributor

Summary (draft / PoC — PR 2 of 2 spec change)

Adds CardTransaction as a third TransactionOneOf member with a CARD discriminator so card transactions appear in GET /transactions and deserialize cleanly via the discriminator. This is the canonical spec change behind the Lightspark webdev SDK regen + sparkcore handler change (the companion PR) that unblocks the documented Grid sandbox card loop (simulate auth → list → simulate clearing → simulate return): integrators discover the cardTransactionId from the public transaction list instead of needing the internal dashboard.

Changes

  • TransactionOneOf: add CardTransaction + CARD discriminator mapping.
  • CardTransaction: add a type: CARD discriminator property; relax cardId, pullSummary, refundSummary, settlementSummary to optional so the served card-transaction shape (the GET /transactions/{id} projection) validates and the list deserializes cleanly even for card transactions without a resolved card.
  • GET /transactions: document that card transactions are identified by type: CARD and that this is how integrators discover a CardTransaction id in Sandbox.

The bundled openapi.yaml / mintlify/openapi.yaml carry only this change (the redocly rebundle reorders unrelated schemas, so the diff is scoped to the actual change; run make build on merge to fully re-normalize).

Known limitations (PoC)

  • The served card payload uses processorTransactionToken; the schema exposes issuerTransactionToken. SDK deserialization still succeeds (the loop works via id), but the token isn't surfaced under the typed field — flagged for a follow-up rename.
  • GET /transactions?type=CARD is not yet a valid filter (TransactionType is INCOMING/OUTGOING); clients filter client-side on type: CARD. Follow-up.

🤖 arcing-fulcrum(#1) | Feedback

Original PR: #621

…ction list

Add CardTransaction as a third TransactionOneOf member with a CARD discriminator
so card transactions appear in GET /transactions and deserialize cleanly via the
discriminator. Add a type: CARD discriminator property to CardTransaction and
relax cardId / pullSummary / refundSummary / settlementSummary to optional so the
served card-transaction shape (the GET /transactions/{id} projection) validates.
Document on the list endpoint that card transactions are identified by type: CARD
and that this is how integrators discover a CardTransaction id in Sandbox.
@ls-bolt ls-bolt Bot added bolt breaking-change Introduces a breaking change to the OpenAPI spec labels Jun 25, 2026
@vercel

vercel Bot commented Jun 25, 2026

Copy link
Copy Markdown

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

2 Skipped Deployments
Project Deployment Actions Updated (UTC)
grid-flow-builder Ignored Ignored Preview Jun 25, 2026 11:44pm
grid-wallet-demo Ignored Ignored Preview Jun 25, 2026 11:44pm

Request Review

akanter commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

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

@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Breaking OpenAPI changes detected

This PR introduces breaking changes to openapi.yaml:

API Changelog 2025-10-13 vs. 2025-10-13

API Changes

GET /agents/approvals

  • ⚠️ added #/components/schemas/CardTransaction to the data/items/transaction/allOf[#/components/schemas/TransactionOneOf]/ response property oneOf list for the response status 200

GET /agents/me/actions

  • ⚠️ added #/components/schemas/CardTransaction to the data/items/transaction/allOf[#/components/schemas/TransactionOneOf]/ response property oneOf list for the response status 200

GET /agents/me/actions/{actionId}

  • ⚠️ added #/components/schemas/CardTransaction to the transaction/allOf[#/components/schemas/TransactionOneOf]/ response property oneOf list for the response status 200

POST /agents/me/quotes/{quoteId}/execute

  • ⚠️ added #/components/schemas/CardTransaction to the transaction/allOf[#/components/schemas/TransactionOneOf]/ response property oneOf list for the response status 200

GET /agents/me/transactions

  • ⚠️ added #/components/schemas/CardTransaction to the data/items/ response property oneOf list for the response status 200

GET /agents/me/transactions/{transactionId}

  • ⚠️ added #/components/schemas/CardTransaction to the response body oneOf list for the response status 200

POST /agents/me/transfer-in

  • ⚠️ added #/components/schemas/CardTransaction to the transaction/allOf[#/components/schemas/TransactionOneOf]/ response property oneOf list for the response status 201

POST /agents/me/transfer-out

  • ⚠️ added #/components/schemas/CardTransaction to the transaction/allOf[#/components/schemas/TransactionOneOf]/ response property oneOf list for the response status 201

POST /agents/{agentId}/actions/{actionId}/approve

  • ⚠️ added #/components/schemas/CardTransaction to the transaction/allOf[#/components/schemas/TransactionOneOf]/ response property oneOf list for the response status 200

POST /agents/{agentId}/actions/{actionId}/reject

  • ⚠️ added #/components/schemas/CardTransaction to the transaction/allOf[#/components/schemas/TransactionOneOf]/ response property oneOf list for the response status 200

POST /sandbox/cards/{id}/simulate/authorization

  • ⚠️ the response property cardId became optional for the status 200
  • ⚠️ the response property pullSummary became optional for the status 200
  • ⚠️ the response property refundSummary became optional for the status 200
  • ⚠️ the response property settlementSummary became optional for the status 200

POST /sandbox/cards/{id}/simulate/clearing

  • ⚠️ the response property cardId became optional for the status 200
  • ⚠️ the response property pullSummary became optional for the status 200
  • ⚠️ the response property refundSummary became optional for the status 200
  • ⚠️ the response property settlementSummary became optional for the status 200

POST /sandbox/cards/{id}/simulate/return

  • ⚠️ the response property cardId became optional for the status 200
  • ⚠️ the response property pullSummary became optional for the status 200
  • ⚠️ the response property refundSummary became optional for the status 200
  • ⚠️ the response property settlementSummary became optional for the status 200

GET /transactions

  • ⚠️ added #/components/schemas/CardTransaction to the data/items/ response property oneOf list for the response status 200

GET /transactions/{transactionId}

  • ⚠️ added #/components/schemas/CardTransaction to the response body oneOf list for the response status 200

POST /transactions/{transactionId}/confirm

  • ⚠️ added #/components/schemas/CardTransaction to the response body oneOf list for the response status 200

POST /transfer-in

  • ⚠️ added #/components/schemas/CardTransaction to the response body oneOf list for the response status 201

POST /transfer-out

  • ⚠️ added #/components/schemas/CardTransaction to the response body oneOf list for the response status 201

Detected by oasdiff. This PR will need approval from an API reviewer before merge.

@github-actions

github-actions Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

✱ Stainless preview builds for grid

This PR will update the grid SDKs with the following commit messages.

cli

chore(internal): regenerate SDK with no functional changes

csharp

feat(api): add card variant to transactions, type field to card transaction

go

feat(api): add type field to CardTransaction, include as TransactionUnion variant

kotlin

feat(api): add card variant to Transaction, type field, make CardTransaction fields optional

openapi

feat(api): add CardTransaction to transactions response, update type definition

php

feat(api): add CardTransaction to transactions/agents/transfers, type field, optional fields

python

feat(api): add CardTransaction to transactions response, make fields optional

ruby

feat(api): add CardTransaction variant to transaction union, update card transaction types

typescript

feat(api): add card transaction type to transaction union responses
⚠️ grid-openapi studio · code

Your SDK build had at least one "warning" diagnostic.
generate ⚠️

grid-ruby studio · code

Your SDK build had at least one "note" diagnostic.
generate ✅build ✅lint ✅test ✅

⚠️ grid-go studio · code

Your SDK build had a failure in the lint CI job, which is a regression from the base state.
generate ✅build ✅lint ❗test ❗

go get github.com/stainless-sdks/grid-go@ed3860342e807ddf43592838daf2c5803886bb73
⚠️ grid-kotlin studio · code

Your SDK build had a failure in the test CI job, which is a regression from the base state.
generate ⚠️build ✅lint ✅test ❗

⚠️ grid-python studio · code

Your SDK build had a failure in the lint CI job, which is a regression from the base state.
generate ✅build ✅lint ❗test ❗

pip install https://pkg.stainless.com/s/grid-python/9c4ba3abf980fb53a6283c372c15edc110fa52f6/grid-0.0.1-py3-none-any.whl
grid-typescript studio · code

Your SDK build had at least one "note" diagnostic.
generate ✅build ✅lint ✅test ✅

npm install https://pkg.stainless.com/s/grid-typescript/5f7a56011f66c418a088c7a5b6f9243251cb92e8/dist.tar.gz
⚠️ grid-csharp studio · code

Your SDK build had a failure in the build CI job, which is a regression from the base state.
generate ⚠️build ❗lint ✅test ❗

grid-php studio · code

Your SDK build had at least one "note" diagnostic.
generate ✅lint ✅test ✅

⚠️ grid-cli studio · code

Your SDK build had a failure in the test CI job, which is a regression from the base state.
generate ⚠️build ⏭️lint ⏭️test ❗


This comment is auto-generated by GitHub Actions and is automatically kept up to date as you push.
If you push custom code to the preview branch, re-run this workflow to update the comment.
Last updated: 2026-06-27 00:36:39 UTC

@greptile-apps

greptile-apps Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds CardTransaction as a third oneOf variant in TransactionOneOf with a CARD discriminator, so card transactions surface in GET /transactions and deserialize cleanly via the discriminator. CardTransaction gains a required type: CARD property and customerId/platformCustomerId fields, while cardId, pullSummary, refundSummary, and settlementSummary are relaxed to optional.

  • TransactionOneOf.yaml and CardTransaction.yaml are updated together to wire up the discriminator correctly.
  • GET /transactions gains documentation explaining the Sandbox card-loop discovery pattern (type: CARDid → simulate clearing/return).
  • Two known gaps are carried as follow-ups in the PR description: the issuerTransactionToken / processorTransactionToken field-name mismatch, and the absence of a ?type=CARD server-side filter.

Confidence Score: 4/5

Safe to merge with a follow-up to document the status-filter incompatibility for card transactions.

The status query parameter on GET /transactions only accepts payment-style values (CREATED, PENDING, etc.) but card transactions carry an entirely different status vocabulary (AUTHORIZED, SETTLED, EXCEPTION, etc.). Now that card transactions appear in the list, callers have no documented or spec-valid way to filter them by card status server-side — a gap that isn’t called out anywhere in the updated spec or description.

openapi/paths/transactions/transactions.yaml — the status query parameter schema needs a note (or an extension) to communicate that card-specific status values are not accepted.

Important Files Changed

Filename Overview
openapi/components/schemas/cards/CardTransaction.yaml Added type: CARD discriminator property and promoted customerId/platformCustomerId to required; cardId, pullSummary, refundSummary, settlementSummary relaxed to optional. Schema description inaccurately says "extends the Transaction model" (not an allOf inheritance).
openapi/components/schemas/transactions/TransactionOneOf.yaml Adds CardTransaction as a third oneOf member with CARD discriminator mapping. Straightforward and correct.
openapi/paths/transactions/transactions.yaml Added documentation that card transactions appear in the list via type: CARD. The status query parameter still only accepts TransactionStatus values (payment-style), making it impossible to server-side filter card transactions by their own status values (AUTHORIZED, SETTLED, etc.) — this limitation is undocumented.
openapi.yaml Generated bundle reflecting the spec changes — not edited directly per repo convention.
mintlify/openapi.yaml Mintlify copy of the generated bundle — mirrors openapi.yaml changes.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant Client
    participant GridAPI as GET /transactions
    participant SimAuth as POST /simulate/card-auth
    participant SimClear as POST /simulate/card-clearing

    Client->>SimAuth: Simulate card authorization
    SimAuth-->>Client: 200 OK (cardTransactionId in webhook)

    Client->>GridAPI: GET /transactions
    GridAPI-->>Client: "200 [{type: INCOMING,...},{type: CARD, id: CardTransaction:..., status: AUTHORIZED,...}]"

    Note over Client,GridAPI: Client filters on type === CARD to find cardTransactionId

    Client->>SimClear: "POST /simulate/card-clearing { cardTransactionId }"
    SimClear-->>Client: 200 OK (status to SETTLED)
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant Client
    participant GridAPI as GET /transactions
    participant SimAuth as POST /simulate/card-auth
    participant SimClear as POST /simulate/card-clearing

    Client->>SimAuth: Simulate card authorization
    SimAuth-->>Client: 200 OK (cardTransactionId in webhook)

    Client->>GridAPI: GET /transactions
    GridAPI-->>Client: "200 [{type: INCOMING,...},{type: CARD, id: CardTransaction:..., status: AUTHORIZED,...}]"

    Note over Client,GridAPI: Client filters on type === CARD to find cardTransactionId

    Client->>SimClear: "POST /simulate/card-clearing { cardTransactionId }"
    SimClear-->>Client: 200 OK (status to SETTLED)
Loading

Reviews (2): Last reviewed commit: "address Greptile review: add customerId/..." | Re-trigger Greptile

Comment thread openapi/components/schemas/cards/CardTransaction.yaml
…nsaction

Mirror the base Transaction model so listed card transactions are
attributable to a customer and consistent with the GET /transactions
customerId / platformCustomerId filters.

Co-Authored-By: greptile-apps[bot] <greptile-apps[bot]@users.noreply.github.com>
@benwgold benwgold enabled auto-merge (squash) June 27, 2026 00:30
@benwgold benwgold merged commit 3673d8a into main Jun 27, 2026
11 checks passed
@benwgold benwgold deleted the 06-25-grid-card-txn-in-transaction-oneof branch June 27, 2026 00:30
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.

3 participants