Document and test expanded Fleet resource APIs - #59
Merged
Conversation
Brings the Fleetbase API collection in line with the expanded public Fleet, Vehicle and Driver contracts, and adds request-specific response assertions so a collection run proves the behaviour rather than only that a 2xx came back. Fleets - Create/Update accept name, color, task, status and the service_area, zone, vendor and parent_fleet relationships as public IDs. - New "Create a Subfleet" request covering the parent_fleet hierarchy, with 422 self-parent and 404 cross-company examples. - Four new membership requests, plus a repeat of each, covering assignment, idempotent reassignment, removal and no-op re-removal for both vehicles and drivers, with a single stable response shape. - Relationships documented as public IDs, with the nested-object shape kept for ?with= requests. - Query parameters documented: name, public_id, status, task, parent_fleet, parents_only, vendor, service_area, zone. Vehicles - Every safe business field the vehicle record holds is now documented on create and update. - The status enum is reconciled with the implementation: nineteen values were accepted while three were documented. - Query parameters documented, including internal_id, which an importer keys on. Drivers - email and phone documented as optional, with a dedicated "Create an Operational Driver" request for a record with neither. - Identity, operational, structured and orchestrator fields documented. - password removed from the update contract, which the API does not accept. - Query parameters documented, including internal_id and licence number. The Vehicles and Drivers folders delete their own resources before the Fleets folder runs, so the membership requests create and clean up a vehicle and a driver of their own rather than reaching for ids that no longer resolve. Validation: npm run postman:lint — 0 errors, 0 warnings across all five collections. Live collection execution is pending deployment of the Fleet-Ops branch. No credentials, real API keys or customer data are included.
This was referenced Sep 4, 2026
…okup Follows the Fleet-Ops contract correction: a relationship is two separate keys, never one key with two types. Relationship shape - `<name>_id` is the public identifier and is always present. `<name>` is the nested object. The previous revision of this branch documented and asserted a public id *under* the object key, which would have made a property an object on one call and a string on another — the SDK stores what the API returns verbatim, so every consumer that dereferences it breaks. - Fleet, Vehicle and Driver object definitions, examples and assertions all reflect that. Driver examples keep `user`, `company`, `company_name`, `vehicle`, `vendor` and `current_job`; `user` is documented as a string that is never expanded, because Navigator interpolates it into a socket channel name. - Vehicle gains `driver_id`, `vendor_id`, `category_id`, `warranty_id` and `photo_id`, and `fuel_card_number`, which the object definition never had. Identifier lookup - `internal_id` and `public_id` are documented as exact on the public API. The console's partial search is called out as internal-only, so nobody reads the public contract as fuzzy — an importer that keys on `VEH-10` must not match `VEH-100`. Expansion - `?with=vendor`, `?with[]=vendor`, `?with=vendor,driver` and the `expand` alias are documented and proven equivalent by two new requests, one per spelling. Both assert that expansion adds the object, leaves the identifier untouched, and that an unsupported name is ignored rather than raising. Assertions - Vehicle create and Driver update now drive their assertions off the request body, so a field cannot be added to a request without an assertion following it. `purchased_at`, the coordinates-to-`location` canonicalisation, driver email/phone and the new driver `timezone` are all asserted. - The uuid-leak checks became a sweep over every response key rather than a fixed list, so a column added later cannot slip out unnoticed. Validation: npm run postman:lint — 0 errors, 0 warnings across all five collections. Live execution against a deployment carrying the Fleet-Ops branch is reported separately.
… them
The cross-repository contract run failed two driver assertions comparing the
response's email against pm.request.body.raw. The body carries
{{$randomEmail}} and {{$randomPhoneNumber}}, which Postman resolves afresh
every time that body is read — so the comparison was against a different address
than the one actually sent, and the assertion could only ever fail.
Both now assert shape rather than a value that cannot be recovered after the
fact, and a new 'Update a Driver Unchanged Contact' request resends the address
and number the response reported. That is the case the update-time uniqueness
rule has to let through: without its ignore-own-user clause a driver could not
resend its own address.
This was referenced Sep 7, 2026
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.
Summary
Documents and asserts the public Fleet, Vehicle and Driver contracts as
implemented in fleetbase/fleetops#311.
This revision corrects the relationship design from the first one. The earlier
commit documented and asserted a public ID under the object key, which would
have made a property an object on one call and a string on another. The SDK
stores what the API returns verbatim, so every consumer that dereferences such a
property breaks — Navigator interpolates
driver.userstraight into a socketchannel name, where an object becomes
user.[object Object].Implementation PR: fleetbase/fleetops#311
Type of Change
Implementation Notes
Relationships are two keys
<name>_idis the public identifier and is always present.<name>is thenested object, returned only when it was asked for through
?with=, and never astring. Object definitions, examples and assertions all say so, and an automated
sweep confirms no Fleet, Vehicle or Driver response example renders a
relationship key as a string.
driver_id,vendor_id,category_id,warranty_id,photo_id, andfuel_card_number— which the object definition never carriedeven though the API returned it.
photo_idis documented as the filereference, with
photo_urlas the convenience URL andavatar_urlcalled outseparately as a display asset.
service_area_id,zone_id,vendor_id,parent_fleet_id,photo_id.user,company,company_name,vehicle,vendorandcurrent_jobin every example, alongsidevehicle_id,vendor_idandjob_id.useris documented as a string that is never expanded, with thereason.
Expansion
?with=vendor,?with[]=vendor,?with=vendor,driverand theexpandaliasare documented, and two new requests prove the array and scalar spellings
equivalent rather than assuming it:
with[]=vendoradds the object,vendor_idunchanged and equal tovendor.id, an unsupported name is ignoredwith=vendorproduces the identical resultIdentifier lookup
internal_idandpublic_idare documented as exact on the public API,with the console's partial search called out as internal-only — an importer that
keys on
VEH-10must not matchVEH-100.Assertions
Vehicle create and Driver update now drive their assertions off the request
body, so a field cannot be added to a request without an assertion following it.
Specifically asserted:
purchased_at, the coordinates-to-locationcanonicalisation, vehicle status normalisation, driver
email,phoneand thenew
timezone, relationship public-ID prefixes, and the object/identifierinvariants under expansion. The uuid-leak checks became a sweep over every
response key rather than a fixed list.
Response shapes are the real ones — bare objects and bare arrays, no invented
{data: ...}wrapper.200/201are accepted only where the implementationpermits either.
Validation
$ npm run postman:lint Validated 5 Postman Native Git collections and 3 environments. Linting Fleetbase API... No issues found. Scanned: 214 | Errors: 0 | Warnings: 0 Linting Fleetbase Core API... No issues found. Scanned: 24 | Errors: 0 | Warnings: 0 Linting Fleetbase Integrated Vendor Flow... No issues found. Scanned: 7 | Errors: 0 | Warnings: 0 Linting Fleetbase Ledger API... No issues found. Scanned: 8 | Errors: 0 | Warnings: 0 Linting Fleetbase Storefront API... No issues found. Scanned: 62 | Errors: 0 | Warnings: 0Both
scripts/validate-collections.jsand the Postman Native Git schema lint ran(Postman CLI 1.46.0).
Live run — passed. fleetbase/fleetops#311 temporarily pinned its contract job
to this branch's commit so the two were validated together. Run
33953882575,
fleetops
a249e7df× postman91e72fe, against a booted stack carrying theFleet-Ops branch:
The pin has been reverted on that PR. Running this collection against a
deployment that does not carry #311 will fail, because the endpoints it asserts
do not exist there.
The first pinned run failed and was worth running: it caught a
500onGET /v1/vehicles/{id}?with[]=…in the implementation, and two assertions herethat compared the response against
pm.request.body.raw— which re-resolves{{$randomEmail}}every time it is read, so they could only ever fail. Both arefixed.
Documentation Impact
API Reference Impact
fleetbase/postmanIf the
fleetbase.ioAPI reference is generated from this repository it needsregeneration once both PRs land. No change was made to
fleetbase/fleetbase.io.Risk
Specification and tests only. The Fleets folder creates and deletes its own
vehicle and driver because the Vehicles and Drivers folders delete theirs before
it runs. The driver authentication and password requests are untouched:
driver_identity,driver_passwordanddriver_phoneare still not written byanything here.
Confirmation
No credentials, API keys, tokens or customer data. All identifiers in examples
are illustrative. Not merged.