Skip to content

fix: align Kotlin sample EUR beneficiary with OpenAPI schema#572

Open
claude[bot] wants to merge 1 commit into
mainfrom
docs/sync-20260611
Open

fix: align Kotlin sample EUR beneficiary with OpenAPI schema#572
claude[bot] wants to merge 1 commit into
mainfrom
docs/sync-20260611

Conversation

@claude

@claude claude Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Fixed buildEurBeneficiary in Kotlin sample to match the EurBeneficiary OpenAPI schema
  • The schema requires countryOfResidence (not address) as a required field
  • Made address optional since it's not required in the schema

Context

This fix was identified during the documentation sync review of recent schema changes:

The EurBeneficiary.yaml schema has:

required:
- beneficiaryType
- countryOfResidence
- fullName

But the Kotlin sample was:

  1. Requiring address (which is optional in the schema)
  2. Not setting countryOfResidence (which is required)

Test plan

  • Run make lint - passes
  • Verify Kotlin sample compiles with Grid SDK

🤖 Generated with Claude Code

The EurBeneficiary schema requires countryOfResidence (not address).
Updates buildEurBeneficiary to:
- Set countryOfResidence (required field)
- Make address optional (not required in schema)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@claude claude Bot requested review from pengying and shreyav June 11, 2026 09:37
@vercel

vercel Bot commented Jun 11, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
grid-flow-builder Ignored Ignored Jun 11, 2026 9:37am

Request Review

@greptile-apps

greptile-apps Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR updates buildEurBeneficiary in the Kotlin sample to match the EurBeneficiary OpenAPI schema — replacing the mandatory address field with a mandatory countryOfResidence field and making address optional.

  • countryOfResidence is now required as per the schema, and address is applied conditionally via the builder's apply block.
  • The countryOfResidence resolution logic contains a silent fallback through f.nationality, which already merges countryOfResidence and nationality in parseBeneficiaryFields; a caller who supplies only nationality (no countryOfResidence) will not get the expected IllegalArgumentException, and the two values will be conflated.

Confidence Score: 3/5

The fix correctly removes the hard address requirement, but the countryOfResidence validation guard can be bypassed by any caller that supplies nationality instead, silently producing incorrect data.

The countryOfResidence fallback chain reaches into f.nationality (which itself conflates countryOfResidence and nationality from parseBeneficiaryFields), meaning a request with only a nationality field would pass validation and have the nationality value used as the country of residence — a real data correctness problem on the changed path.

samples/kotlin/src/main/kotlin/com/grid/sample/routes/ExternalAccounts.kt — specifically the countryOfResidence resolution block in buildEurBeneficiary.

Important Files Changed

Filename Overview
samples/kotlin/src/main/kotlin/com/grid/sample/routes/ExternalAccounts.kt Aligns EUR beneficiary builder with schema by setting countryOfResidence as required and making address optional, but the fallback chain silently accepts nationality as a substitute for countryOfResidence, undermining the validation guard.

Sequence Diagram

sequenceDiagram
    participant Caller
    participant buildEurBeneficiary
    participant parseBeneficiaryFields
    participant EurBeneficiaryBuilder

    Caller->>buildEurBeneficiary: node (JSON with beneficiary data)
    buildEurBeneficiary->>parseBeneficiaryFields: node
    parseBeneficiaryFields-->>buildEurBeneficiary: "BeneficiaryFields(fullName, nationality=countryOfResidence??nationality, birthDate, address)"
    Note over buildEurBeneficiary: val countryOfResidence = node?.optText(countryOfResidence)<br/>?: f.nationality  <- may silently use nationality<br/>?: throw IllegalArgumentException
    buildEurBeneficiary->>EurBeneficiaryBuilder: beneficiaryType, fullName, countryOfResidence
    buildEurBeneficiary->>EurBeneficiaryBuilder: (optional) nationality, birthDate, address
    EurBeneficiaryBuilder-->>buildEurBeneficiary: EurBeneficiary
    buildEurBeneficiary-->>Caller: EurExternalAccountCreateInfo.Beneficiary
Loading
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
samples/kotlin/src/main/kotlin/com/grid/sample/routes/ExternalAccounts.kt:292-294
**Silent fallback from `nationality` to `countryOfResidence`**

`parseBeneficiaryFields` (line 196) sets `f.nationality` to `node.optText("countryOfResidence") ?: node.optText("nationality")`. The fallback chain here means that when `countryOfResidence` is absent but `nationality` is present (e.g., `"nationality": "DE"`), the nationality value is silently used as the country of residence. This bypasses the `IllegalArgumentException` guard entirely despite the validation message. Additionally, `node?.optText("countryOfResidence")` in the first line is redundant — it is always equal to the `countryOfResidence` portion of `f.nationality`, so the first `?:` never changes the outcome.

Reviews (1): Last reviewed commit: "fix: align Kotlin sample EUR beneficiary..." | Re-trigger Greptile

Comment on lines +292 to +294
val countryOfResidence = node?.optText("countryOfResidence")
?: f.nationality
?: throw IllegalArgumentException("EUR beneficiary requires countryOfResidence")

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 Silent fallback from nationality to countryOfResidence

parseBeneficiaryFields (line 196) sets f.nationality to node.optText("countryOfResidence") ?: node.optText("nationality"). The fallback chain here means that when countryOfResidence is absent but nationality is present (e.g., "nationality": "DE"), the nationality value is silently used as the country of residence. This bypasses the IllegalArgumentException guard entirely despite the validation message. Additionally, node?.optText("countryOfResidence") in the first line is redundant — it is always equal to the countryOfResidence portion of f.nationality, so the first ?: never changes the outcome.

Prompt To Fix With AI
This is a comment left during a code review.
Path: samples/kotlin/src/main/kotlin/com/grid/sample/routes/ExternalAccounts.kt
Line: 292-294

Comment:
**Silent fallback from `nationality` to `countryOfResidence`**

`parseBeneficiaryFields` (line 196) sets `f.nationality` to `node.optText("countryOfResidence") ?: node.optText("nationality")`. The fallback chain here means that when `countryOfResidence` is absent but `nationality` is present (e.g., `"nationality": "DE"`), the nationality value is silently used as the country of residence. This bypasses the `IllegalArgumentException` guard entirely despite the validation message. Additionally, `node?.optText("countryOfResidence")` in the first line is redundant — it is always equal to the `countryOfResidence` portion of `f.nationality`, so the first `?:` never changes the outcome.

How can I resolve this? If you propose a fix, please make it concise.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants