Skip to content

sdk-sync: API 1.4.0+f19c2d4 → sdk-java 2.0.0 (major) - #13

Closed
MarketDataDev03 wants to merge 1 commit into
mainfrom
sdk-sync/1.4.0-f19c2d4
Closed

MarketDataDev03 wants to merge 1 commit into
mainfrom
sdk-sync/1.4.0-f19c2d4

Conversation

@MarketDataDev03

Copy link
Copy Markdown
Owner

Generated by sdk-auto-sync for API release 1.4.0 (commit f19c2d4).

Changes in the API surface

Snapshots 9c18fbb1f58e → 72b3d15f59ad:

~ GET /v1/options/chain/{underlying}/ ?dte: string  (was integer)

What the agent did

tests: Only the test file was touched, as required.

Summary

Added unit tests in src/test/java/com/marketdata/sdk/OptionsResourceTest.java specifying the new string-typed dte chain-query behavior (API delta: ?dte changed from integer to string, accepting a single number, a range like 30-45, or a comma-separated list):

  • chainExpirationFilterDteRangeTranslatesToDashedDteParam — ExpirationFilter.dteRange(30, 45) → ?dte=30-45
  • chainExpirationFilterDteInTranslatesToCommaSeparatedDteParam — ExpirationFilter.dteIn(List.of(7, 14, 30)) → ?dte=7,14,30
  • expirationFilterDteRangeRejectsMinGreaterThanMax, expirationFilterDteRangeRejectsNegativeMin, expirationFilterDteRangeRejectsNegativeMax — validation for the new dteRange(int, int) factory
  • expirationFilterDteInRejectsEmptyList, expirationFilterDteInRejectsNegativeEntry — validation for the new dteIn(List<Integer>) factory

The existing single-number ExpirationFilter.dte(int) test/behavior is left unchanged since ?dte=30 remains valid under the new string type. Ran gradle test --no-daemon --console=plain: it fails at compileTestJava because dteRange/dteIn don't exist yet on ExpirationFilter — confirming the tests correctly specify not-yet-implemented behavior.

implement: Only files under src/main/java and src/test/java were touched, all within the allowed limits.

Summary

Implemented the dte query-parameter type change (integer → string) on GET /v1/options/chain/{underlying}/:

  • ExpirationFilter.java: Dte is now record Dte(String value) instead of record Dte(int days). Added two new factory methods alongside the existing dte(int): dteRange(int minDays, int maxDays) for the MIN-MAX form (validates non-negative, min <= max) and dteIn(List<Integer> days) for the comma-separated list form (validates non-empty, all entries non-negative), mirroring the existing StrikeFilter sealed-variant convention already used for the sibling strike parameter.
  • OptionsResource.java: applyExpirationFilter now writes v.value() (the pre-formatted wire string) instead of the old v.days() int accessor.
  • OptionsResourceTest.java: fixed one test I wrote in phase 1 — chainExpirationFilterDteInTranslatesToCommaSeparatedDteParam asserted the raw (unencoded) URI, but the transport percent-encodes commas like it does for columns/symbols; updated it to URL-decode before asserting, matching the existing convention used elsewhere in this same test file (no weakening — same assertion, just decoded first).

gradle test and gradle build (including Spotless formatting) both pass.

changelog: Only CHANGELOG.md was touched in this step, under [Unreleased], no version heading added.

Added an [Unreleased] entry noting the response to API 1.4.0: new Added items for dteRange/dteIn, and a Changed/BREAKING note explaining ExpirationFilter.Dte now wraps a String instead of int (days() → value(), constructor shape change) with migration guidance.

Files

  • CHANGELOG.md
  • src/main/java/com/marketdata/sdk/OptionsResource.java
  • src/main/java/com/marketdata/sdk/options/ExpirationFilter.java
  • src/test/java/com/marketdata/sdk/OptionsResourceTest.java

Version

Public-surface change computed by the pipeline: major — next version 2.0.0 (from 1.0.0).

  • removed: ExpirationFilter.Dte.days() — Record accessor removed along with the int-typed days component; consumers calling .days() on a Dte no longer compile.
  • added: ExpirationFilter.Dte.value() — New record accessor exposing the raw wire-form dte string (single number, MIN-MAX range, or comma list).
  • changed: ExpirationFilter.Dte(int) — Canonical record constructor's sole component changed from int days to String value; becomes ExpirationFilter.Dte(String). Any consumer code constructing new ExpirationFilter.Dte(n) directly no longer compiles.
  • added: ExpirationFilter.dteRange(int, int) — New static factory producing a Dte filter for an inclusive day range, wire form dte=MIN-MAX; throws IllegalArgumentException for negative bounds or minDays > maxDays.
  • added: ExpirationFilter.dteIn(java.util.List<Integer>) — New static factory producing a Dte filter for a discrete set of days, wire form dte=D1,D2,...; throws NullPointerException on null list/entries and IllegalArgumentException on empty list or negative entries.

Reviewer notes

  • [minor] src/main/java/com/marketdata/sdk/options/ExpirationFilter.java:117 — Dte's canonical constructor (record Dte(String value)) is implicitly public and has no compact-constructor validation, so a caller can bypass dte()/dteRange()/dteIn() entirely via new ExpirationFilter.Dte("garbage") and send an arbitrary, unvalidated string as the dte query value. This mirrors the pre-existing pattern for Between/MonthYear, but widening the field from int to String meaningfully broadens what can slip through unvalidated (any string vs. any int) now that the wire format has specific shapes (N, MIN-MAX, or comma list) to enforce.
  • [minor] src/main/java/com/marketdata/sdk/options/ExpirationFilter.java:118 — ExpirationFilter.Dte(String value) has no compact constructor, so its canonical constructor (implicitly public, since it's a member of a public sealed interface) accepts any string — including null or an arbitrary value containing characters never validated by dte()/dteRange()/dteIn() — bypassing the non-negative/format checks those factories enforce. Add a compact constructor that rejects null and validates the format (digits, optional single dash, optional comma list) to keep the invariant enforced regardless of construction path.

Job log

The full record of this job — every phase, test and build result, review findings and how they were resolved — is in .sdk-sync/1.4.0-f19c2d4.md on this branch.


3 coder run(s) · 2 review(s) · 69 turns · 3,842,438 tokens · US$ 1.92 · item 84b5f2fe-6494-44de-ab3d-64d36d965eeb

Agent runs
  • coder · claude-haiku-4-5-20251001, claude-sonnet-5 · 1,191,857 tokens (38,761 in, 1,142,404 cached, 10,692 out) · 25 turns · US$ 0.49
  • coder · claude-sonnet-5 · 1,626,333 tokens (18,931 in, 1,601,412 cached, 5,990 out) · 22 turns · US$ 0.46
  • reviewer · claude-haiku-4-5-20251001, claude-sonnet-5 · 308,922 tokens (50,389 in, 246,096 cached, 12,437 out) · 9 turns · US$ 0.40
  • security · claude-haiku-4-5-20251001, claude-sonnet-5 · 238,614 tokens (55,298 in, 179,134 cached, 4,182 out) · 5 turns · US$ 0.33
  • analyst · claude-haiku-4-5-20251001, claude-sonnet-5 · 50,862 tokens (25,509 in, 23,170 cached, 2,183 out) · 3 turns · US$ 0.13
  • coder · claude-sonnet-5 · 425,850 tokens (3,292 in, 421,360 cached, 1,198 out) · 5 turns · US$ 0.11

tests: Only the test file was touched, as required.

## Summary

Added unit tests in `src/test/java/com/marketdata/sdk/OptionsResourceTest.java` specifying the new string-typed `dte` chain-query behavior (API delta: `?dte` changed from `integer` to `string`, accepting a single number, a range like `30-45`, or a comma-separated list):

- `chainExpirationFilterDteRangeTranslatesToDashedDteParam` — `ExpirationFilter.dteRange(30, 45)` → `?dte=30-45`
- `chainExpirationFilterDteInTranslatesToCommaSeparatedDteParam` — `ExpirationFilter.dteIn(List.of(7, 14, 30))` → `?dte=7,14,30`
- `expirationFilterDteRangeRejectsMinGreaterThanMax`, `expirationFilterDteRangeRejectsNegativeMin`, `expirationFilterDteRangeRejectsNegativeMax` — validation for the new `dteRange(int, int)` factory
- `expirationFilterDteInRejectsEmptyList`, `expirationFilterDteInRejectsNegativeEntry` — validation for the new `dteIn(List<Integer>)` factory

The existing single-number `ExpirationFilter.dte(int)` test/behavior is left unchanged since `?dte=30` remains valid under the new string type. Ran `gradle test --no-daemon --console=plain`: it fails at `compileTestJava` because `dteRange`/`dteIn` don't exist yet on `ExpirationFilter` — confirming the tests correctly specify not-yet-implemented behavior.

implement: Only files under `src/main/java` and `src/test/java` were touched, all within the allowed limits.

## Summary

Implemented the `dte` query-parameter type change (`integer` → `string`) on `GET /v1/options/chain/{underlying}/`:

- `ExpirationFilter.java`: `Dte` is now `record Dte(String value)` instead of `record Dte(int days)`. Added two new factory methods alongside the existing `dte(int)`: `dteRange(int minDays, int maxDays)` for the `MIN-MAX` form (validates non-negative, `min <= max`) and `dteIn(List<Integer> days)` for the comma-separated list form (validates non-empty, all entries non-negative), mirroring the existing `StrikeFilter` sealed-variant convention already used for the sibling `strike` parameter.
- `OptionsResource.java`: `applyExpirationFilter` now writes `v.value()` (the pre-formatted wire string) instead of the old `v.days()` int accessor.
- `OptionsResourceTest.java`: fixed one test I wrote in phase 1 — `chainExpirationFilterDteInTranslatesToCommaSeparatedDteParam` asserted the raw (unencoded) URI, but the transport percent-encodes commas like it does for `columns`/`symbols`; updated it to URL-decode before asserting, matching the existing convention used elsewhere in this same test file (no weakening — same assertion, just decoded first).

`gradle test` and `gradle build` (including Spotless formatting) both pass.

changelog: Only `CHANGELOG.md` was touched in this step, under `[Unreleased]`, no version heading added.

Added an `[Unreleased]` entry noting the response to API 1.4.0: new `Added` items for `dteRange`/`dteIn`, and a `Changed`/BREAKING note explaining `ExpirationFilter.Dte` now wraps a `String` instead of `int` (`days()` → `value()`, constructor shape change) with migration guidance.
@MarketDataDev03
MarketDataDev03 marked this pull request as ready for review September 17, 2026 14:07
@MarketDataDev03
MarketDataDev03 deleted the sdk-sync/1.4.0-f19c2d4 branch September 17, 2026 14:37
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.

1 participant