fix issues with orders api - #3823
Open
gumaerc wants to merge 1 commit into
Open
Conversation
gumaerc
force-pushed
the
cg/orders-api-fixes
branch
from
August 5, 2026 21:20
9b4655a to
3fc62b3
Compare
OpenAPI ChangesShow/hide changesUnexpected changes? Ensure your branch is up-to-date with |
gumaerc
force-pushed
the
cg/orders-api-fixes
branch
from
August 12, 2026 18:38
3fc62b3 to
02500b6
Compare
Three narrow fixes to the v0 orders endpoints, which are what the generated
`@mitodl/mitxonline-api-axios` clients target (`/api/v0/orders/receipt/{id}/` and
`/api/v0/orders/history/`). The unversioned `/api/orders/...` implementation is a
separate near-duplicate that is not in the generated spec, so it is left alone.
1. `get_purchaser` was annotated `ExtendedLegalAddressSerializer(many=True)` but
returns a single object. Generated clients therefore declared
`Array<ExtendedLegalAddress>` for an object, so a consumer could not read
`purchaser.email` without casting around the type.
2. `OrderHistoryViewSet` used a bare `LimitOffsetPagination`, whose `default_limit`
is None. DRF skips pagination entirely in that case, so omitting `limit`
returned a bare list while passing any `limit` returned the
`{count, next, previous, results}` envelope. The generated spec has always
declared the envelope, so a client that trusted the type and omitted `limit`
would read `.results` off an array. Two tests that asserted the bare list are
updated and one now pins the envelope for a request with no pagination
parameters.
3. `TransactionLineSerializer` dereferenced `content_object.start_date` without
checking that `purchasable_object` resolved. It is a GenericForeignKey with no
database constraint, so deleting a courseware object leaves the product pointing
at nothing and the receipt endpoint returns a 500. Added a regression test that
deletes the course run and asserts the line still serializes.
Only (1) changes the OpenAPI spec, from `array` to `allOf`. That is a spec
correction rather than a behavioral change — response bodies are unchanged — so the
six oasdiff findings are recorded in oasdiff-err-ignore.txt with that reasoning.
The DRF lint baseline is regenerated. Beyond the line shifts in the file this
change touches, it also picks up five stale line numbers for users/serializers.py
that had drifted on main; the violation set per file and code is unchanged.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
gumaerc
force-pushed
the
cg/orders-api-fixes
branch
from
August 12, 2026 19:25
02500b6 to
9d494dc
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What are the relevant tickets?
https://github.com/mitodl/hq/issues/12684
Description (What does it do?)
Fixes three things that were fundamentally broken about the v0 Orders API, so we
don't have to work around them in the new receipt page.
purchaserwas typed as an array but returns an object.get_purchaserwasannotated
many=True, so generated clients declaredArray<ExtendedLegalAddress>for a single object — unusable without castingaround the type.
orders/historyreturned a different shape depending on whetherlimitwaspassed.
OrderHistoryViewSethad nodefault_limit, so DRF skipped paginationentirely and returned a bare list; with any
limitit returned the documented{count, next, previous, results}envelope.The receipt endpoint 500s when a product's courseware object has been deleted.
TransactionLineSerializerdereferencedcontent_object.start_datewithoutchecking that the
GenericForeignKeyresolved.Scoped to v0, which is what the generated clients target. The unversioned
/api/orders/...duplicate isn't in the spec and produces no TypeScript, so it'sleft alone.
Only (1) changes the OpenAPI spec (
array→allOf). Response bodies areunchanged, so the oasdiff findings are recorded as a spec correction.
How can this be tested?
Data you need: one fulfilled order on your own account. If you don't have one,
make a 100%-off code and use it to create a verified enrollment, which fulfills an
order as a side effect:
Note the order id from
/api/v0/orders/history/for the checks below.(2) — order history shape. Hit the endpoint both ways:
(1) — purchaser type.
GET /api/v0/orders/receipt/<order id>/and confirmpurchaseris a single object, not a list. That was always true at runtime; the fixis that
openapi/specs/v0.yamlnow agrees, so a regenerated client types it as anobject. Worth a glance at the spec diff to confirm.
(3) — dangling courseware object. Delete the course run behind the order's
product, then reload the receipt:
GET /api/v0/orders/receipt/<order id>/500s on main and returns 200 here, withnull
start_date/end_dateon the line. (Do this on a throwaway run — it alsoremoves the enrollment.)