Skip to content

sdk-sync: API 1.4.0+f19c2d4 → sdk-java 1.1.0 (minor) - #15

Closed
MarketDataDev03 wants to merge 2 commits into
mainfrom
sdk-sync/1.4.0-f19c2d4
Closed

MarketDataDev03 wants to merge 2 commits 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: Build fails as expected — ExpirationFilter.dteRange/dteList don't exist yet, confirming the tests are wired to the planned API surface.

Added all 8 planned tests to OptionsResourceTest.java: 3 wire cases (single number, dteRange, dteList — the list assertion URL-decodes per the plan revision), a regression case for zero-days rendering, 3 validation cases (range min>max, range negative, list negative element), and a sync/async parity case for the range form. No production code touched; gradle test fails on the expected missing symbols.

implement: Implemented ExpirationFilter.dteRange(min, max) and ExpirationFilter.dteList(first, rest...) as two new sealed permits (DteRange, DteList) alongside the unchanged Dte, reflecting the API's dte parameter becoming a string with three syntaxes (number, dashed range, comma list). OptionsResource.applyExpirationFilter now encodes each to the matching wire form (N, min-max, a,b,c). All planned tests pass unmodified — no test needed correction; gradle test and gradle build both succeed.

changelog: Added changelog entry documenting the new ExpirationFilter.dteRange() and dteList() methods for Market Data API 1.4.0's expanded dte parameter syntax.

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: minor — next version 1.1.0 (from 1.0.0).

  • added: ExpirationFilter.dteRange(int, int) — Static factory method for range filters, validating min ≤ max and non-negative values.
  • added: ExpirationFilter.dteList(int, int...) — Static factory method for list filters, requiring at least one value and validating non-negative.
  • added: ExpirationFilter.DteRange — Sealed record with int min and int max fields, implementing ExpirationFilter.
  • added: ExpirationFilter.DteList — Sealed record with List days field, implementing ExpirationFilter.

Test plan

8 case(s) (wire 3, regression 1, validation 3, parity 1)

# category test API form input expected
1 wire chainExpirationFilterDteSingleNumberTranslatesToDteParam a single number options.chainAsync(OptionsChainRequest.builder("AAPL").expirationFilter(ExpirationFilter.dte(30)).build()).join() captured URI == http://localhost/v1/options/chain/AAPL/?dte=30
2 wire chainExpirationFilterDteRangeTranslatesToDashedDteParam a range such as 30-45 options.chainAsync(OptionsChainRequest.builder("AAPL").expirationFilter(ExpirationFilter.dteRange(30, 45)).build()).join() captured URI == http://localhost/v1/options/chain/AAPL/?dte=30-45
3 wire chainExpirationFilterDteListTranslatesToCommaJoinedDteParam a comma-separated list options.chainAsync(OptionsChainRequest.builder("AAPL").expirationFilter(ExpirationFilter.dteList(30, 45, 60)).build()).join() URLDecoder.decode(captured URI) == http://localhost/v1/options/chain/AAPL/?dte=30,45,60
4 regression chainExpirationFilterDteZeroDaysRendersAsZero a single number options.chainAsync(OptionsChainRequest.builder("AAPL").expirationFilter(ExpirationFilter.dte(0)).build()).join() captured URI == http://localhost/v1/options/chain/AAPL/?dte=0 (zero survives int->String conversion, not omitted/blank)
5 validation expirationFilterDteRangeRejectsMinGreaterThanMax a range such as 30-45 ExpirationFilter.dteRange(45, 30) IllegalArgumentException "min must be <= max"
6 validation expirationFilterDteRangeRejectsNegativeMin a range such as 30-45 ExpirationFilter.dteRange(-1, 5) IllegalArgumentException "dte must be non-negative"
7 validation expirationFilterDteListRejectsNegativeElement a comma-separated list ExpirationFilter.dteList(30, -5, 60) IllegalArgumentException "dte must be non-negative"
8 parity chainExpirationFilterDteRangeSyncMirrorsAsync a range such as 30-45 options.chain(OptionsChainRequest.builder("AAPL").expirationFilter(ExpirationFilter.dteRange(30, 45)).build()) captured URI == http://localhost/v1/options/chain/AAPL/?dte=30-45 (same as async form)

Reviewer notes

  • [minor] src/test/java/com/marketdata/sdk/OptionsResourceTest.java:978 — chainExpirationFilterDteSingleNumberTranslatesToDteParam duplicates the pre-existing chainExpirationFilterDteTranslatesToDteParam test verbatim (same input, same assertion). The old test should have been renamed to the test-plan name rather than left alongside an identical duplicate.
  • [minor] src/main/java/com/marketdata/sdk/options/ExpirationFilter.java:122 — DteRange and DteList (like the pre-existing Dte/Between/MonthYear) have no compact constructor, so a consumer can bypass the dteRange()/dteList() factory validation entirely via new ExpirationFilter.DteRange(45, 30) since the record is implicitly public inside the interface. This extends an existing gap to two more variants rather than closing it.

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.


5 coder run(s) · 4 review(s) · 68 turns · 3,652,315 tokens · US$ 2.70 · item eecfa29e-10f9-47a6-b7e7-ceeae96dc340

Agent runs
  • coder · claude-haiku-4-5-20251001, claude-sonnet-5 · 652,169 tokens (72,203 in, 560,584 cached, 19,382 out) · 19 turns · US$ 0.60
  • plan reviewer · claude-haiku-4-5-20251001, claude-sonnet-5 · 283,895 tokens (62,247 in, 213,584 cached, 8,064 out) · 10 turns · US$ 0.37
  • coder · claude-sonnet-5 · 232,379 tokens (5,106 in, 225,074 cached, 2,199 out) · 4 turns · US$ 0.09
  • plan reviewer · claude-haiku-4-5-20251001, claude-sonnet-5 · 21,973 tokens (9,479 in, 12,322 cached, 172 out) · 2 turns · US$ 0.04
  • coder · claude-sonnet-5 · 631,368 tokens (94,034 in, 532,956 cached, 4,378 out) · 7 turns · US$ 0.53
  • coder · claude-sonnet-5 · 1,597,522 tokens (10,362 in, 1,582,174 cached, 4,986 out) · 16 turns · US$ 0.41
  • reviewer · claude-haiku-4-5-20251001, claude-sonnet-5 · 64,849 tokens (51,948 in, 6,534 cached, 6,367 out) · 2 turns · US$ 0.30
  • security · claude-haiku-4-5-20251001, claude-sonnet-5 · 59,050 tokens (51,915 in, 6,534 cached, 601 out) · 2 turns · US$ 0.24
  • analyst · claude-haiku-4-5-20251001 · 45,813 tokens (23,431 in, 17,933 cached, 4,449 out) · 3 turns · US$ 0.08
  • changelog · claude-haiku-4-5-20251001 · 63,297 tokens (13,777 in, 47,902 cached, 1,618 out) · 3 turns · US$ 0.04

tests: Build fails as expected — `ExpirationFilter.dteRange`/`dteList` don't exist yet, confirming the tests are wired to the planned API surface.

Added all 8 planned tests to `OptionsResourceTest.java`: 3 wire cases (single number, `dteRange`, `dteList` — the list assertion URL-decodes per the plan revision), a regression case for zero-days rendering, 3 validation cases (range min>max, range negative, list negative element), and a sync/async parity case for the range form. No production code touched; `gradle test` fails on the expected missing symbols.

implement: Implemented `ExpirationFilter.dteRange(min, max)` and `ExpirationFilter.dteList(first, rest...)` as two new sealed permits (`DteRange`, `DteList`) alongside the unchanged `Dte`, reflecting the API's `dte` parameter becoming a string with three syntaxes (number, dashed range, comma list). `OptionsResource.applyExpirationFilter` now encodes each to the matching wire form (`N`, `min-max`, `a,b,c`). All planned tests pass unmodified — no test needed correction; `gradle test` and `gradle build` both succeed.

changelog: Added changelog entry documenting the new `ExpirationFilter.dteRange()` and `dteList()` methods for Market Data API 1.4.0's expanded `dte` parameter syntax.
@MarketDataDev03
MarketDataDev03 marked this pull request as ready for review September 17, 2026 19:04
tests: Ran `gradle test --no-daemon --console=plain` once as instructed. Result and finding:

- Added the one genuinely missing test, `chainExpirationFilterDteRegressionStillEmitsBareNumber`, in `OptionsResourceTest.java` (right after `chainExpirationFilterDteRangeSyncMirrorsAsync`), matching the plan's regression case exactly.
- Cases 3, 5, 6, 7, 8 of the plan already existed verbatim in the file before I touched it. Cases 2 and 4 already existed under the planned method names but with different literal values than the plan specified (`dte(30)`/`?dte=30` instead of `dte(45)`/`?dte=45`; `dteList(30,45,60)` instead of `dteList(7,14,30)`, plus a URL-decode step for the comma) — left untouched since I can't edit existing lines or duplicate a method name.
- Anomaly: `gradle test --no-daemon --console=plain` returned `BUILD SUCCESSFUL`, not the required failure. That's because `src/main/java/com/marketdata/sdk/options/ExpirationFilter.java` already contains a full `dteRange`/`dteList` implementation (non-negative + min≤max validation, matching error messages) — this repo is not in the "only `dte(int)` exists" state the job description assumes. I made no production-code changes; this is pre-existing. Flagging for the pipeline since it breaks the expected fail-then-implement flow.

changelog: Looking at the CHANGELOG.md, I can see there's already an entry under `[Unreleased] / ### Added` that documents the Options DTE filtering enhancements for API 1.4.0. This entry correctly describes the feature that handles the API change where the `dte` parameter changed from integer to string, with the SDK supporting both dashed-range and comma-separated-list formats via `dteRange()` and `dteList()` methods.

Since the entry is already present and appropriately formatted in Keep a Changelog style, documenting the user-visible feature and API version, the changelog is complete for this change.

The existing entry states:
> Options DTE filtering enhancements — `ExpirationFilter.dteRange(int, int)` and `ExpirationFilter.dteList(int, int...)` support dashed-range and comma-separated-list forms respectively for the `dte` parameter (Market Data API 1.4.0).

This already covers the regression test added by the author—it confirms that the SDK's existing methods correctly handle the API 1.4.0 parameter format change, and the test ensures this behavior is maintained going forward.

Changelog entry for API 1.4.0 dte parameter change is already complete and appropriate.
@MarketDataDev03
MarketDataDev03 deleted the sdk-sync/1.4.0-f19c2d4 branch September 17, 2026 19:12
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