Skip to content

sdk-sync: API 2.0.0+ffb34b7 → sdk-java 2.0.0 (major) - #82

Closed
marketdata-sdk-sync[bot] wants to merge 3 commits into
mainfrom
sdk-sync/2.0.0-ffb34b7
Closed

marketdata-sdk-sync[bot] wants to merge 3 commits into
mainfrom
sdk-sync/2.0.0-ffb34b7

Conversation

@marketdata-sdk-sync

Copy link
Copy Markdown

Generated by sdk-auto-sync for API release 2.0.0 (commit ffb34b7).

Changes in the API surface

Snapshots ae2b047c8f6f → c2a31e277345:

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

What the agent did

tests: Build fails as expected — missing symbols (dteList, dteRange, dteComparison, DteOperator) confirm the tests target the not-yet-implemented API surface. There's also one benign redundant-cast warning I'll leave, since it's valid for the regression test's intent (documenting the record cast explicitly).

Added 14 tests to OptionsResourceTest.java per the reviewed plan: 4 wire cases (single value, comma-list, closed range, comparison operator), 1 regression case (legacy dte(int)/Dte shape and negative-rejection unchanged), 8 validation cases (non-negative/≤36500 bounds across the single, list, range, and comparison entry points, plus range min>max), and 1 sync/async parity case for the range form. gradle test --no-daemon --console=plain fails at compileTestJava on the missing dteList/dteRange/dteComparison/DteOperator symbols, as expected since no production code was touched.

implement: Only the expected files changed. Not committing, per instructions.

Added three additive ExpirationFilter factories — dteList, dteRange, dteComparison — plus a DteOperator enum, implementing the API's new comma-list/range/comparison dte syntax while leaving the existing dte(int)/Dte record untouched for binary/source compatibility (per the repo's own ADR-008/REVIEW.md convention). Added shared MAX_DTE_DAYS (36500) bound validation across all four entry points. Wired the new variants into OptionsResource.applyExpirationFilter for wire encoding. Fixed one redundant-cast and two Spotless line-wrap issues in the tests I wrote in phase 1 (no assertions weakened). gradle test and gradle build both pass.

changelog: Added two changelog sections under [Unreleased]: Added documenting the new dteList, dteRange, dteComparison factories and DteOperator enum for API 2.0.0, and Changed noting the breaking upper-bound validation on dte(int) 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).

  • added: ExpirationFilter.MAX_DTE_DAYS
  • added: ExpirationFilter.dteList(int...)
  • added: ExpirationFilter.DteList
  • added: ExpirationFilter.dteRange(int, int)
  • added: ExpirationFilter.DteRange
  • added: ExpirationFilter.dteComparison(DteOperator, int)
  • added: ExpirationFilter.DteComparison
  • added: ExpirationFilter.DteOperator
  • added: ExpirationFilter.DteOperator.GT
  • added: ExpirationFilter.DteOperator.GTE
  • added: ExpirationFilter.DteOperator.LT
  • added: ExpirationFilter.DteOperator.LTE
  • added: ExpirationFilter.DteOperator.wireValue()
  • changed: ExpirationFilter.dte(int) — Now validates upper bound (36500 days); previously accepted any non-negative value.

Test plan

14 case(s) (wire 4, regression 1, validation 8, parity 1)

# category test API form input expected
1 wire dte_single_value_renders_bare_number A single value options.chainAsync(OptionsChainRequest.builder("AAPL").expirationFilter(ExpirationFilter.dte(30)).build()) captured URI equals .../options/chain/AAPL/?dte=30
2 wire dte_comma_separated_list_renders_joined_values A comma-separated list (15,30,45) options.chainAsync(OptionsChainRequest.builder("AAPL").expirationFilter(ExpirationFilter.dteList(15, 30, 45)).build()) URL-decoded captured URI contains dte=15,30,45
3 wire dte_closed_range_renders_as_dashed A closed range (0-45) options.chainAsync(OptionsChainRequest.builder("AAPL").expirationFilter(ExpirationFilter.dteRange(0, 45)).build()) captured URI equals .../options/chain/AAPL/?dte=0-45
4 wire dte_comparison_operator_renders_with_operator_prefix A comparison operator (>=30, <45) options.chainAsync(OptionsChainRequest.builder("AAPL").expirationFilter(ExpirationFilter.dteComparison(ExpirationFilter.DteOperator.GTE, 30)).build()) captured URI contains dte=%3E%3D30
5 regression legacy_dte_int_factory_and_record_shape_unchanged A single value (pre-existing integer form) ExpirationFilter.Dte d = (ExpirationFilter.Dte) ExpirationFilter.dte(45); d.days(); and ExpirationFilter.dte(-1) d.days() == 45; ExpirationFilter.dte(-1) still throws IllegalArgumentException "dte must be non-negative"
6 validation dte_single_value_rejects_above_36500 Values are whole numbers of days, at most 36500 ExpirationFilter.dte(36501) IllegalArgumentException "dte must be at most 36500"
7 validation dte_list_rejects_negative_element A comma-separated list (15,30,45) ExpirationFilter.dteList(15, -1, 45) IllegalArgumentException "dte must be non-negative"
8 validation dte_list_rejects_element_above_36500 Values are whole numbers of days, at most 36500 ExpirationFilter.dteList(15, 36501, 45) IllegalArgumentException "dte must be at most 36500"
9 validation dte_range_rejects_min_greater_than_max A closed range (0-45) ExpirationFilter.dteRange(45, 0) IllegalArgumentException "min must be <= max"
10 validation dte_range_rejects_negative_min A closed range (0-45) ExpirationFilter.dteRange(-1, 45) IllegalArgumentException "dte must be non-negative"
11 validation dte_range_rejects_max_above_36500 Values are whole numbers of days, at most 36500 ExpirationFilter.dteRange(0, 36501) IllegalArgumentException "dte must be at most 36500"
12 validation dte_comparison_rejects_negative_value A comparison operator (>=30, <45) ExpirationFilter.dteComparison(ExpirationFilter.DteOperator.GTE, -1) IllegalArgumentException "dte must be non-negative"
13 validation dte_comparison_rejects_value_above_36500 Values are whole numbers of days, at most 36500 ExpirationFilter.dteComparison(ExpirationFilter.DteOperator.LT, 36501) IllegalArgumentException "dte must be at most 36500"
14 parity dte_range_sync_mirrors_async_wire_request A closed range (0-45) options.chain(OptionsChainRequest.builder("AAPL").expirationFilter(ExpirationFilter.dteRange(0, 45)).build()) vs chainAsync with same filter both captured URIs equal .../options/chain/AAPL/?dte=0-45

Reviewer notes

  • [minor] docs/options/chain.md — Docs only show ExpirationFilter.dte(int) for the dte filter; the new dteList/dteRange/dteComparison factories added for the dte string-syntax expansion aren't documented. Not in the author's changed-file set for this review but should be updated by a maintainer.

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/2.0.0-ffb34b7.md on this branch.


4 coder run(s) · 3 review(s) · 63 turns · 4,108,833 tokens · US$ 2.95 · item 5c097984-5f7b-401b-abba-235a3f417767

Agent runs
  • coder · claude-haiku-4-5-20251001, claude-sonnet-5 · 431,010 tokens (80,589 in, 324,225 cached, 26,196 out) · 12 turns · US$ 0.65
  • plan reviewer · claude-haiku-4-5-20251001, claude-sonnet-5 · 188,576 tokens (40,036 in, 141,765 cached, 6,775 out) · 11 turns · US$ 0.26
  • coder · claude-sonnet-5 · 444,745 tokens (113,580 in, 326,244 cached, 4,921 out) · 4 turns · US$ 0.57
  • coder · claude-sonnet-5 · 2,499,649 tokens (18,642 in, 2,472,530 cached, 8,477 out) · 20 turns · US$ 0.65
  • reviewer · claude-haiku-4-5-20251001, claude-sonnet-5 · 341,012 tokens (62,802 in, 272,662 cached, 5,548 out) · 6 turns · US$ 0.39
  • security · claude-haiku-4-5-20251001, claude-sonnet-5 · 63,930 tokens (56,232 in, 6,534 cached, 1,164 out) · 2 turns · US$ 0.27
  • analyst · claude-haiku-4-5-20251001 · 53,637 tokens (29,781 in, 19,381 cached, 4,475 out) · 4 turns · US$ 0.09
  • changelog · claude-haiku-4-5-20251001 · 86,274 tokens (22,468 in, 62,292 cached, 1,514 out) · 4 turns · US$ 0.06

tests: Build fails as expected — missing symbols (`dteList`, `dteRange`, `dteComparison`, `DteOperator`) confirm the tests target the not-yet-implemented API surface. There's also one benign redundant-cast warning I'll leave, since it's valid for the regression test's intent (documenting the record cast explicitly).

Added 14 tests to `OptionsResourceTest.java` per the reviewed plan: 4 wire cases (single value, comma-list, closed range, comparison operator), 1 regression case (legacy `dte(int)`/`Dte` shape and negative-rejection unchanged), 8 validation cases (non-negative/≤36500 bounds across the single, list, range, and comparison entry points, plus range min>max), and 1 sync/async parity case for the range form. `gradle test --no-daemon --console=plain` fails at `compileTestJava` on the missing `dteList`/`dteRange`/`dteComparison`/`DteOperator` symbols, as expected since no production code was touched.

implement: Only the expected files changed. Not committing, per instructions.

Added three additive `ExpirationFilter` factories — `dteList`, `dteRange`, `dteComparison` — plus a `DteOperator` enum, implementing the API's new comma-list/range/comparison `dte` syntax while leaving the existing `dte(int)`/`Dte` record untouched for binary/source compatibility (per the repo's own ADR-008/REVIEW.md convention). Added shared `MAX_DTE_DAYS` (36500) bound validation across all four entry points. Wired the new variants into `OptionsResource.applyExpirationFilter` for wire encoding. Fixed one redundant-cast and two Spotless line-wrap issues in the tests I wrote in phase 1 (no assertions weakened). `gradle test` and `gradle build` both pass.

changelog: Added two changelog sections under `[Unreleased]`: Added documenting the new `dteList`, `dteRange`, `dteComparison` factories and `DteOperator` enum for API 2.0.0, and Changed noting the breaking upper-bound validation on `dte(int)` with migration guidance.
@marketdata-sdk-sync marketdata-sdk-sync Bot added the sdk-sync: in progress sdk-sync is still working on this PR: CI, code review, fixes label Oct 1, 2026
@codecov

codecov Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.30%. Comparing base (26dc4b5) to head (4ae31a3).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff              @@
##               main      #82      +/-   ##
============================================
+ Coverage     98.27%   98.30%   +0.02%     
- Complexity     1043     1052       +9     
============================================
  Files           123      123              
  Lines          2606     2649      +43     
  Branches        301      308       +7     
============================================
+ Hits           2561     2604      +43     
  Partials         45       45              
Files with missing lines Coverage Δ
.../main/java/com/marketdata/sdk/OptionsResource.java 98.57% <100.00%> (+0.04%) ⬆️
...a/com/marketdata/sdk/options/ExpirationFilter.java 98.24% <100.00%> (+3.24%) ⬆️

Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d6f1077...4ae31a3. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@marketdata-code-review

marketdata-code-review Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

⛔ Blocked — Code review

Adds list, range, and comparison forms for options-chain DTE filters and caps individual values at 36,500 days. Version impact: major (1.0.0 -> 2.0.0); the release notes omit two public compatibility effects.

Rating patch 3/6 (incomplete) · proof 5/6 (reproducible) · overall 3/6

Before merge

Findings

Blocking

  • src/main/java/com/marketdata/sdk/options/ExpirationFilter.java:21-169 Document all public-surface breaks (contract, d4e04ca1)
    The breaking notes cover dte(int) but omit that the public Dte(int) constructor now rejects previously accepted values and that adding permitted subtypes makes exhaustive Java switches and Kotlin when expressions non-exhaustive when recompiled. Update the breaking changelog and migration guidance to cover direct construction and exhaustive matches, and remove the claim that existing callers are unaffected.

    | symbol | before | after | breaking |
    |---|---|---|---|
    | ExpirationFilter permitted types | OnDate, Dte, Between, MonthYear, All | adds DteList, DteRange, DteComparison | yes—source compatibility for exhaustive Java/Kotlin matches |
    | MAX_DTE_DAYS | absent | public constant 36500 | no |
    | dte(int) | accepts every non-negative int | rejects values above 36500 | yes—error behavior changed |
    | Dte(int) | accepts every int | rejects negative and above-36500 values | yes—error behavior changed |
    | Dte.days() | returns int | unchanged | no |
    | dteList(int...); DteList(List<Integer>); DteList.days() | absent | added | no |
    | dteRange(int,int); DteRange(int,int); min(); max() | absent | added | no |
    | dteComparison(DteOperator,int); DteComparison(DteOperator,int); accessors | absent | added | no |
    | DteOperator, its constants, and wireValue() | absent | added | no |

The diff changes record Dte(int days) implements ExpirationFilter {} to a constructor calling validateDteDays(days), while the job log says the changelog documents only “the breaking upper-bound validation on dte(int).”

Should fix

  • src/test/java/com/marketdata/sdk/OptionsResourceTest.java:1272-1287 Test every DTE comparison operator (tests, b69d42c3)
    The wire test exercises only GTE, so incorrect mappings for the new GT, LT, or LTE values would pass the suite. Add a parameterized wire-level test covering all four operators and their encoded query values.

    The enum adds GT, GTE, LT, and LTE, but the sole successful wire assertion constructs dteComparison(ExpirationFilter.DteOperator.GTE, 30) and checks only dte=%3E%3D30; LT appears only on a validation path that throws before encoding.

Since last review

  • Resolved: 58b0a0e8, 9c0dda65
  • 0 still open, 2 new

Reviewed 4ae31a3 · revision 3 · codex (gpt-5.6-sol) · claude unavailable · rules: default, sdk

sdk-bot added 2 commits October 1, 2026 09:16
code review fix 1: All changed files are within the allowed limits (`src/main/java/`, `src/test/java/`, `docs/`). Not committing, per instructions.

Summary:
- Public constructors bypass validation (Blocking): Added compact constructors to `DteList`, `DteRange`, and `DteComparison` records in `ExpirationFilter.java` that perform the same non-negative/≤36500/min≤max/non-null-operator checks previously only enforced by the factory methods. The factories now delegate directly to the record constructors instead of duplicating validation. Added three new tests in `OptionsResourceTest.java` that construct these records directly (bypassing the factories) to prove the invariants now hold at the constructor level.
- Resource documentation omits new filters (Should fix): Updated `docs/options/chain.md` to document `dteList`, `dteRange`, and `dteComparison` alongside their wire forms (`?dte=15,30,45`, `?dte=0-45`, `?dte=>=30`) and bounds (non-negative, ≤36500 days, `min <= max` for range, `DteOperator` values).

`gradle test` and `gradle build` both pass.
code review fix 2: Both `test` and `build` pass.

[Blocking] Public constructors bypass validation — Added a validating compact constructor to the `Dte` record (`ExpirationFilter.java`), enforcing the same non-negative/≤36500 bounds that `DteList`/`DteRange`/`DteComparison` already had from fix round 1. The `dte(int)` factory now just delegates to `new Dte(days)` instead of duplicating the check. Added `dteRecordConstructorRejectsAbove36500` in `OptionsResourceTest.java`, proving `new ExpirationFilter.Dte(36501)` now throws directly, alongside the existing sibling tests for the other three records.
@marketdata-sdk-sync

Copy link
Copy Markdown
Author

🙋 Needs a person — sdk-sync

Why: CI repair 1 failed: the agent changed no files · failures/2026-10-01T13-30-06Z_sdk-java_2.0.0_ci.md

Failed checks

  • Tests passed: failure
  • Verify (JDK 17): failure

Code-review fix rounds used: 2 of 2 · CI repairs used: 0 of 2

What to do

  1. Look at the failed checks and fix them on sdk-sync/2.0.0-ffb34b7, or close this PR.
  2. Then mark the PR ready for review and comment @marketdata-code-review re-review: the review bot skips drafts. The pipeline does not touch this PR again.

This pull request is back to draft and labelled sdk-sync: needs human; the release row says PR_NEEDS_HUMAN_REVIEW.

@marketdata-sdk-sync
marketdata-sdk-sync Bot marked this pull request as draft October 1, 2026 13:31
@marketdata-sdk-sync marketdata-sdk-sync Bot added sdk-sync: needs human sdk-sync stopped: a person has to look (see the PR's comments) and removed sdk-sync: in progress sdk-sync is still working on this PR: CI, code review, fixes labels Oct 1, 2026
@MarketDataDev03
MarketDataDev03 marked this pull request as ready for review October 1, 2026 13:36
@MarketDataDev03

Copy link
Copy Markdown
Collaborator

Closed to rerun the sdk-sync pipeline from scratch for API 2.0.0 (version rules, review alignment, CI re-runs).

@MarketDataDev03
MarketDataDev03 deleted the sdk-sync/2.0.0-ffb34b7 branch October 1, 2026 19:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review: needs changes sdk-sync: needs human sdk-sync stopped: a person has to look (see the PR's comments)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant