| name | postman |
| description | Generate, extend, or fix the local Postman collection + environment for hitting the dinotable API. Use when Zoha wants to import the API into Postman, add a request for an endpoint, regenerate the collection after routes change, or debug token/OTP/id-chaining in the saved requests. The collection is GENERATED — edit the SPEC in gen-postman.sh, never hand-edit the JSON. |
Maintaining the dinotable Postman collection
The Postman collection and environment under
docs/dev-tooling/postman/ are generated artifacts, not hand-maintained
JSON. The single source of truth is the SPEC list inside
docs/dev-tooling/postman/gen-postman.sh. Walkthrough for humans:
docs/dev-tooling/api-testing.md.
Never hand-edit dinotable.postman_collection.json or
dino-local.postman_environment.json — a re-run of the generator overwrites
the collection. Make the change in the SPEC, then regenerate.
Why generated, not OpenAPI import
/api/docs-json (Swagger) gives routes + schemas but drops the automation
layer Postman can't express from a spec: post-response scripts that save
accessToken/refreshToken/strangerToken, id chaining
(restaurantId → branchId → slotId → reservationId), the idempotency replay
test, and the owner-vs-stranger 403 assertion. The generator keeps those as
data so a re-import never wipes them. Use OpenAPI import only to eyeball
"what endpoints exist"; use this generated collection to run the flow.
The prime-directive boundary (read this)
- Allowed: edit the
SPEC in gen-postman.sh, run the script, let it
write the collection/env. These live under docs/** and are test
scaffolding, not application code.
- Not allowed: adding or changing the actual NestJS route in
apps/. A
SPEC entry only exercises an endpoint Zoha has already built. If the
endpoint doesn't exist in code yet, that route is a milestone/snippet for
Zoha to type — never wire it yourself, then add the Postman request after.
Adding or changing a request
Edit the SPEC in gen-postman.sh — one dict per request:
dict(name="...", method="POST", path="/branches/{{branchId}}/...",
auth="inherit",
idem="guid",
body='{ "...": {{var}} }',
test=["pm.environment.set('xId', pm.response.json().id);"])
path is everything after {{baseUrl}} and may carry a ?query. Chain a new
id by saving it in one request's test and referencing {{thatId}} in a
later request's path/body. Then regenerate:
cd docs/dev-tooling/postman
./gen-postman.sh # rewrite the collection only
./gen-postman.sh --env # also rewrite env; refreshes `today`, resets tokens to ''
./gen-postman.sh --stdout # print, write nothing (diff/preview)
./gen-postman.sh --help
Default run leaves the env untouched — only --env regenerates it (it resets
the saved tokens/ids to empty, so don't pass it mid-session). Zoha re-imports
the collection in Postman after a regenerate.
OTP / tokens
Dev OTP is fixed: otp = 123456 in the env, matching AUTH_DEV_OTP. So there
is no "capture the code from the response" script and you don't need one —
Verify just sends "code": "{{otp}}". Run the Auth folder top-down: Verify
OTP (owner) saves the tokens; collection-level bearer {{accessToken}} then
flows to every later request. Me returning 200 confirms the token wired.
Verifying a change
After regenerating, sanity-check the output is still importable and the scripts
survived — diff the generated collection against expectations with --stdout,
or run the flow end-to-end with Newman against a running API
(newman run dinotable.postman_collection.json -e dino-local.postman_environment.json).
If you add a request, confirm its test/chaining lands the new variable in the
environment.