Uh oh!
There was an error while loading. Please reload this page.
Add idType/identifier to IndividualCustomerCreateRequest (ENG-10686) - #637
Conversation
…0686) Individual account-holder CIP capture — accept the individual's tax identification (SSN/ITIN) on customer creation so sparkcore can bridge it to paycore EntUserInfo.tax_identifier for Lead onboarding. Write-only: added to the create request only (not the shared IndividualCustomerFields), so the SSN is never echoed in customer responses. Mirrors the flat idType/identifier shape beneficial owners already use.
The latest updates on your projects. Learn more about Vercel for GitHub. 2 Skipped Deployments
|
|
akanter
commented
Jul 2, 2026
✱ Stainless preview builds for gridThis PR will update the cli csharp go kotlin openapi php python ruby typescript ✅ grid-rubystudio · code
|
Re-posting context from the original draft (#636) for the API reviewer, since the oasdiff
Verified in webdev#29658: the full existing create-customer suite (118 tests, none sending tax fields) passes unchanged. |
Greptile SummaryAdds
Confidence Score: 4/5Safe to merge after adding writeOnly: true to the identifier field; without it, generated clients may expose SSN/ITIN in deserialized GET responses. The identifier field carries sensitive PII (SSN/ITIN) and the schema description explicitly calls it write-only, but the writeOnly: true OpenAPI keyword is missing. Client generators used by the consuming webdev repo rely on this keyword to mark the field appropriately; its absence could cause the generated model to include the field when deserializing customer GET responses. openapi/components/schemas/customers/IndividualCustomerCreateRequest.yaml and its bundled copies in openapi.yaml and mintlify/openapi.yaml all need the writeOnly: true addition on the identifier property.
|
| Filename | Overview |
|---|---|
| openapi/components/schemas/customers/IndividualCustomerCreateRequest.yaml | Adds idType and identifier fields to the individual customer create request; missing writeOnly: true on identifier despite the description calling it write-only, and countryOfIssuance is absent compared to the BeneficialOwnerPersonalInfo pattern it claims to mirror. |
| openapi.yaml | Bundled output reflecting the same schema change; same writeOnly omission is present here. |
| mintlify/openapi.yaml | Mintlify documentation bundle regenerated from make build; mirrors the openapi.yaml changes faithfully. |
Sequence Diagram
%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Client as Web Client
participant API as Grid API
participant Lead as Lead (Banking Partner)
Client->>API: "POST /customers/individual<br/>{idType, identifier, ...}"
Note over API: IndividualCustomerCreateRequest<br/>idType (SSN/ITIN)<br/>identifier (write-only)
API->>Lead: "Onboard US individual<br/>EntUserInfo.tax_identifier = identifier"
Lead-->>API: Onboarding result
API-->>Client: "Customer response<br/>(identifier NOT echoed back)"
%%{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 as Web Client
participant API as Grid API
participant Lead as Lead (Banking Partner)
Client->>API: "POST /customers/individual<br/>{idType, identifier, ...}"
Note over API: IndividualCustomerCreateRequest<br/>idType (SSN/ITIN)<br/>identifier (write-only)
API->>Lead: "Onboard US individual<br/>EntUserInfo.tax_identifier = identifier"
Lead-->>API: Onboarding result
API-->>Client: "Customer response<br/>(identifier NOT echoed back)"
Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.
---### Issue 1 of 2
openapi/components/schemas/customers/IndividualCustomerCreateRequest.yaml:9-15
The description explicitly states this field is "Write-only — never returned in customer responses," but the `writeOnly: true` OpenAPI 3.0 property is missing. Without it, SDK/client generators (including the webdev `grid-api/update_schema.sh` mentioned in the PR) will not mark the field as write-only in generated models, potentially including it in GET response deserialization — a problem for a sensitive field like an SSN/ITIN.
```suggestion identifier: type: string writeOnly: true description: >- The individual's tax identification number (SSN or ITIN for a US account holder). Required to onboard the individual as a US account holder. Write-only — never returned in customer responses. example: 123-45-6789```### Issue 2 of 2
openapi/components/schemas/customers/IndividualCustomerCreateRequest.yaml:6-15
The PR description says this schema "mirrors the flat `idType`/`identifier`/`countryOfIssuance` shape beneficial owners already expose (`BeneficialOwnerPersonalInfo`)", but `countryOfIssuance` is absent here. The reused `IdentificationType` enum includes `NON_US_TAX_ID`, and without `countryOfIssuance` there's no way to identify which country issued a non-US tax ID — the field becomes ambiguous for any non-US account holder. If this endpoint is US-only, the description should say so explicitly and the available enum values should be narrowed accordingly.
Reviews (1): Last reviewed commit: "feat: add idType/identifier to Individua..." | Re-trigger Greptile
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
pengying
commented
Jul 2, 2026
Are you going to add masked identifier to the response? |
…#671) ## Summary Removes the csharp target from `.stainless/stainless.yml` so the `Build SDKs for pull request / preview` check stops failing on every spec-changing PR. **Why every spec PR is red**: Stainless's csharp build CI is broken upstream for ANY freshly generated code (content-independent, proven by bisect on #650, breakage window ~Jul 3). The preview check gates on a per-language head-vs-base regression, and with csharp in main's config the base build resolves to a cached pre-breakage csharp *success* — so every fresh head failure counts as a regression → red. **Why this fixes it**: with csharp out of the config on main, base builds have no cached csharp success to regress from — matching outcomes on base and head → "not a regression" → green. Proven end-to-end by probe #659: the exact previously-failing change class (doc-comment-only codegen delta) ran against a csharp-free base and `preview` **passed**. Full mechanics: [investigation writeup](#657 (comment)). **No shipping impact**: the csharp target is unpublished (`production_repo: null`, `publish.nuget: false`). Re-add the block when Stainless fixes their csharp build CI upstream. ## Sequencing (for #657 and other open spec PRs) 1. Merge this PR — **its own `preview` will be red** (its base is current main); merge through it (precedent: #633, #637). 2. Merge/rebase main into open spec PRs (e.g. #657) — their next `preview` run goes green. ## Verification - `make lint` passes; the file matches the exact removal previously validated on the #657 branch (commit 069ad9a) and by probe #659. --- 🤖 [thundering-graviton-3](https://zeus.dev.dev.sparkinfra.net/#/arc?id=thundering-graviton)[(#3)](https://zeus.dev.dev.sparkinfra.net/#/instance?id=thundering-graviton-3) | [Feedback](https://zeus.dev.dev.sparkinfra.net/feedback) Original PR: #663 Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…the Card resource (#657) ## Summary Follow-up #2 from [webdev#29877](lightsparkdev/webdev#29877) (Lithic card PAN-reveal POC), evolved per review: PAN reveal is now an **explicit, dedicated endpoint** rather than a side effect of reading the card. Server change: [webdev#29995](lightsparkdev/webdev#29995). - **New `POST /cards/{id}/reveal`** (`openapi/paths/cards/cards_{id}_reveal-session.yaml` + `CardRevealResponse` schema) — mints a signed, short-lived reveal URL and returns `{ panEmbedUrl, expiresAt }`. Every mint is audit-logged with the requesting actor; unattributable sessions get 403. - **`panEmbedUrl` is removed from the `Card` schema entirely** — get/list/create/update responses and webhook payloads never carry it. A live PAN-reveal credential only exists when a client explicitly asked for one (least-privilege + clean "reveal requested" audit semantics). - **Docs rewritten to the reveal-session flow**: issuing-cards gains the `POST …/reveal` example, quickstart/webhooks/terminology snippets updated, webhook examples no longer show the field, and `GET /cards/{id}` points at the reveal endpoint. - **Rode along from the folded #656**: a small `GtqAccountInfoBase` description clarification. `.stainless/stainless.yml` is byte-identical to main (the csharp experiments were fully reverted; the real csharp fix is #663). ## Verification - `make build` + `make lint` pass (0 errors; remaining warnings pre-exist on main). - Server implementation is TDD'd end-to-end on [webdev#29995](lightsparkdev/webdev#29995) (58 handler/proxy tests + dashboard dialog tests green). ## CI note — red `preview` check is expected until #663 merges The Stainless csharp target's upstream build CI fails on any codegen delta (content-independent); the fix is #663 (removes the unpublished csharp target on main). Until it merges, `preview` stays red on spec-changing PRs, this one included — merge through it (precedent #633, #637). Details: [investigation](#657 (comment)). --- 🤖 [thundering-graviton-5](https://zeus.dev.dev.sparkinfra.net/#/arc?id=thundering-graviton)[(#5)](https://zeus.dev.dev.sparkinfra.net/#/instance?id=thundering-graviton-5) | [Feedback](https://zeus.dev.dev.sparkinfra.net/feedback) --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: mohamedwane <mohamedwane@users.noreply.github.com> Co-authored-by: benwgold <benwgold@users.noreply.github.com> Co-authored-by: pengying <pengying@users.noreply.github.com>

Summary
Adds the individual account-holder's tax identification (SSN/ITIN) to
IndividualCustomerCreateRequestso Grid can capture it at customer creation and bridge it downstream toEntUserInfo.tax_identifierfor Lead (banking-partner) onboarding of a US individual.Part of ENG-10686 (Individual account-holder CIP). Consumed by the webdev PR (lightsparkdev/webdev#29658), which reads
idType/identifieroff the regenerated client model.Details
allOfinIndividualCustomerCreateRequest.yaml, not the sharedIndividualCustomerFields), so the identifier is write-only and never echoed in customer GET responses.IdentificationTypeenum (SSN/ITIN/EIN/NON_US_TAX_ID) and mirrors the flatidType/identifier/countryOfIssuanceshape beneficial owners already expose (BeneficialOwnerPersonalInfo).openapi.yaml,mintlify/openapi.yaml) viamake build;redocly lintclean.Test plan
npm run build:openapi+npx @redocly/cli lint openapi.yaml→ valid.grid-api/update_schema.sh) picks upid_type/identifier/country_of_issuanceon the individual create model.🤖 sovereign-nebula-2(#2) | Feedback
Original PR: #636