Repository navigation
fix(graphql): add time range support and point cap validation to getPriceHistory (#370) - #390
Conversation
…riceHistory (Divinity-Labs#370) - Add optional from and to ISO 8601 string arguments to getPriceHistory query. - Document boundary inclusivity in schema description (bucket >= from AND bucket <= to). - Validate from and to as valid ISO 8601 dates and enforce from before to. - Enforce MAX_HISTORY_POINTS bound matching the REST route to reject over-large ranges. - Dynamically add parameterized bucket >= and bucket <= conditions to PostgreSQL query. - Add comprehensive test suite in src/__tests__/graphqlPriceHistory.test.ts covering valid bounded ranges, invalid dates, inverted ranges, over-large windows, and legacy calls. Closes Divinity-Labs#370
|
Resolved merge conflicts with latest |
Miracle656
left a comment
There was a problem hiding this comment.
Every criterion met, and one of them met in the way I actually wanted rather than the way that was easiest.
Boundary inclusivity is stated, not assumed. The schema description says it outright and names the consequence:
The time range is inclusive at both ends… Because both endpoints are inclusive, querying adjacent windows (e.g. [t0, t1] and [t1, t2]) will…
That was the point of the criterion. Range queries in this codebase are inclusive at both ends, so adjacent windows double-count the boundary — and the failure mode is that nobody notices until a sum is quietly wrong. Writing it into the schema puts it in front of the one person who can act on it, and documents boundary inclusivity in the schema description is a test that keeps it there.
The cap is imported, not reimplemented. HISTORY_INTERVAL_SECONDS and MAX_HISTORY_POINTS come from ./history, so GraphQL and REST cannot drift into disagreeing about how large a window is too large. Copying the constant is the obvious shortcut and it is how two surfaces end up with different limits that nobody can explain a year later.
The test set covers the right shapes too — invalid from, invalid to, from after to, an over-large range, a bounded range asserting the query really is inclusive, only-from, and legacy calls with neither argument. That last one is what says existing clients still work.
Merging.
The drift guard this PR adds caught its own artifact going stale:
× committed schema.graphql matches the code-defined schema exactly
Between this branch being cut and now, Divinity-Labs#380 (invalid/unknown/empty pair
distinctions), Divinity-Labs#381 (the oracle query and OracleSourceStatus enum) and
Divinity-Labs#390 (from/to on getPriceHistory) all changed the code-defined schema.
npm run graphql:schema:gen
Which is the guard doing exactly what it was written for, on its first
outing.
graphqlSchemaDrift.test.ts: 6 passed.
Claude-Session: https://claude.ai/code/session_01USgemLt4Rnz4SGB1Srf3GB
#476) * feat(graphql): export schema SDL artifact, add drift guard and breaking change check * chore(graphql): regenerate schema.graphql after the schema moved on main The drift guard this PR adds caught its own artifact going stale: × committed schema.graphql matches the code-defined schema exactly Between this branch being cut and now, #380 (invalid/unknown/empty pair distinctions), #381 (the oracle query and OracleSourceStatus enum) and #390 (from/to on getPriceHistory) all changed the code-defined schema. npm run graphql:schema:gen Which is the guard doing exactly what it was written for, on its first outing. graphqlSchemaDrift.test.ts: 6 passed. Claude-Session: https://claude.ai/code/session_01USgemLt4Rnz4SGB1Srf3GB --------- Co-authored-by: Miracle656 <iupacnumen2020@gmail.com>
Summary
Implements optional
fromandtoISO 8601 time range filtering for thegetPriceHistoryGraphQL query, documents boundary inclusivity in the schema description, and enforces point cap bounds matching the REST route.Fixes
Fixes #370
Details of Changes
from: Stringandto: Stringarguments togetPriceHistoryin the GraphQL schema.bucket >= from AND bucket <= to), noting that adjacent query windows intentionally share boundary buckets.fromandtoas ISO 8601 timestamps, rejecting invalid date strings with descriptive error messages.frommust be before or equal toto, rejecting inverted ranges (from must be before to).MAX_HISTORY_POINTS(10,000) cap matching the REST/prices/historyroute to prevent unbounded DB scans over large time spans at fine resolutions.src/api/graphql.tsto addbucket >=andbucket <=conditions when provided.limitat 1000.fromorto.src/__tests__/graphqlPriceHistory.test.tsverifying:fromandtostrings.fromis afterto.MAX_HISTORY_POINTS.from/to.Checklist
fromandtoare supported and validatedfromaftertois an errornpm test)