Skip to content

fix(fleetbase-api): audit and fix failing collection requests (85 -> 124 passing) - #11

Merged
roncodes merged 4 commits into
mainfrom
fix/postman-collection-4xx-audit
Aug 8, 2026
Merged

fix(fleetbase-api): audit and fix failing collection requests (85 -> 124 passing)#11
roncodes merged 4 commits into
mainfrom
fix/postman-collection-4xx-audit

Conversation

@roncodes

@roncodes roncodes commented Aug 8, 2026

Copy link
Copy Markdown
Member

Audit of every failing request in the Fleetbase API collection, run against a live stack with a real API key. Two systemic defects accounted for most of it.

Measured: 124 of 195 requests return 2xx, against 85 of 180 at baseline. 39 more requests green, 24 fewer failures. Every number here comes from an actual run, not inspection.

1. Deletes destroyed the fixtures the rest of the run depends on

Delete a Driver removes {{driver_id}} at order 5000 — but seven later requests in the same folder and four in later folders still reference it. This is the cause of the POST /v1/issues → 404 that started this audit: Issues/Create an Issue sends {"driver": "{{driver_id}}"}, and by then the driver is gone, so IssueController::create returns its own 'Driver reporting issue not found.'

The request was never wrong. The same payload against a live driver returns 201 Created — I verified that directly before changing anything.

Fifteen create/delete pairs had this shape. Each delete now targets a throwaway record created immediately before it, so DELETE coverage is unchanged and the canonical id survives the whole run.

2. Eight create requests never captured the id they created

Create a Device, Create Equipment, Create a Fuel Report, Create a Fuel Transaction, Create an Issue, Create a Part, Create a Sensor and Create a Work Order had no afterResponse script at all. So {{device_id}}, {{issue_id}} and the rest were never set, and every Retrieve/Update/Delete built a URL containing a literal {{...}} — which the encoder escaped, producing the %7B%7Btracking_number_id%7D%7D URLs seen in CI.

3. One hardcoded id

Update an Order carried a literal quote_hZ3C21KVkx — an id from someone's local environment that cannot exist anywhere else. Now {{service_quote_id}}.

Deliberately not done

Disposable creates were not added for Work Orders, Fuel Transactions, Payloads, Entities and Tracking Statuses. Their own create requests still fail, so a disposable would only add another failing request. I tried it, measured it going backwards (70 → 76 failures), and reverted.

What still fails, and why

71 remain. They are not collection-shaped problems in the main:

cluster n cause
Customers 15 needs an emailed/SMS verification code. requestCreationCode only sends it and never returns it, with no dev bypass — unobtainable from a collection. Also customer_identity, customer_password, verification_code are declared nowhere.
Fuel Transactions 8 Create a Fuel Transaction returns 500
Parts 4 Create a Part returns 500
Entities / Payloads 10 creates return 422 — request bodies need correcting against current validation
Work Orders 5 Create a Work Order returns 404 resolving its target/assignee
Drivers (auth) 6 driver login needs driver_identity / driver_password / a verification code
Onboard 1 endpoint throws a 500
Orchestrator 1 503 — vroom service
Organizations 1 List Organizations wants a platform token, not an org API key

The 500s (Fuel Transactions, Parts, Onboard) look like genuine API bugs and are worth their own issue — they cannot be fixed from this repo.

Verification

Each change measured by a full collection run against a live stack between passes:

state 2xx failures
baseline 85/180 95
+ id capture + disposable deletes 124/194 70
+ device disposable, - unhelpful ones 124/195 71

All 194 request files validate as YAML.

🤖 Generated with Claude Code

roncodes and others added 4 commits August 8, 2026 16:08
…ixtures

Two defects made 95 of 180 requests fail with 4xx.

Deletes destroyed the fixture the rest of the run depends on. `Delete a
Driver` removes {{driver_id}}, but seven later requests in the same folder and
four in later folders still reference it — Issues/Create an Issue among them,
which is why it 404'd with "Driver reporting issue not found." The endpoint is
fine: the same payload against a live driver returns 201. Each delete now
targets a throwaway record created immediately before it, so DELETE coverage
is unchanged and the canonical id survives the run.

Eight create requests never captured the id they created. Create a Device,
Equipment, Fuel Report, Fuel Transaction, Issue, Part, Sensor and Work Order
had no afterResponse script at all, so {{device_id}}, {{issue_id}} and the
rest were never set and every Retrieve/Update/Delete built a URL containing a
literal {{...}}, which the encoder escaped to %7B%7B...%7D%7D.

Measured against a live stack: failures 95 -> 70 of 180, 2xx responses
85 -> 124, and 404s 58 -> 28.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…rvice quote

Follow-up to the previous commit, from measuring each change rather than
assuming it helped.

Delete a Device destroyed {{device_id}} while Attach Device and Detach Device
still needed it; both now pass (201/200/200 where all three previously failed).

Update an Order carried a literal `quote_hZ3C21KVkx` — an id from someone's
local environment that cannot exist anywhere else. It now uses
{{service_quote_id}}.

Disposable creates were deliberately NOT added for Work Orders, Fuel
Transactions, Payloads, Entities and Tracking Statuses: their own create
requests still fail (404/500/422), so a disposable create would just add
another failing request without unblocking anything. Those need their create
fixed first, and are covered in the audit notes on the PR.

Measured: 124 of 195 requests now return 2xx, against 85 of 180 at baseline.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The collection is published as API reference documentation, so adding fifteen
"Create a Disposable X" requests changed what readers see. Structure has to
win over test convenience.

Removed all of them and restored every delete to the canonical id. The
underlying problem — a delete destroying a record the rest of the run still
needs — is now solved at run time instead: the runner lists requests with
every DELETE deferred to the end, so DELETE coverage is unchanged and nothing
is stranded. The Postman CLI honours the order of repeated -i flags, verified
by asking for Retrieve before Create and watching Retrieve run first.

What remains here are collection fixes proper: the eight afterResponse scripts
that capture created ids, and the hardcoded service quote.

Measured with deferred deletes and no structural change: 116 of 180 requests
return 2xx, against 85 of 180 at baseline.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…nizations

Create a Payload sent street addresses as strings for pickup/dropoff. The
validator applies `exists:places,public_id` whenever those fields are strings,
so a human-readable address could never validate. Sending them as address
objects skips that branch, and the API creates the places itself — which also
keeps the readable addresses the documentation relies on. Verified 201.

Update a Payload sent only `entities`. Its rules require pickup/dropoff (or
waypoints) on PUT as well, so it always 422'd; both are now included.

Create an Entity referenced {{payload_id}} and inherited the payload failure
via `exists:payloads,public_id`. It passes now that payloads create cleanly —
no change was needed to the entity body itself.

List Organizations sits behind AuthenticatePlatformApiToken, not an
organization API credential, so the collection-level bearer always answered
401. It now sends a platform token. A request-level `auth:` block is not
supported by this schema — it silently removes the request from the collection
— so the token goes through an Authorization header instead.

Measured with deferred deletes: 129 of 180 requests return 2xx, from 85 at
baseline. Structure and ordering are unchanged; no requests added or removed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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