Skip to content

fix: make the README match the client, and say which inputs are never sent - #8

Merged
Alex (Alexkuva) merged 5 commits into
mainfrom
fix/readme-and-dropped-fields
Oct 14, 2026
Merged

Alex (Alexkuva) merged 5 commits into
mainfrom
fix/readme-and-dropped-fields

Conversation

@Alexkuva

Copy link
Copy Markdown
Contributor

What does this PR change?

  • AuditTrailsOptions.Offset is deprecated. Audit trails are paginated by cursor and the field was already never sent. Nothing is removed: the Deprecated: comment tells callers it has no effect. A nil or zero Limit walks the whole trail, and its comment now says so. A new test fails if the client ever sends offset.
  • Two inputs say what happens to a value that is never sent. LicenseInput.Version on create (the server assigns it; the API would answer 422 CreateLicense.VersionNotSettable) and ComponentInput.PreviousComponentID on update (create-only; the API refuses it on update, whatever its value). No behaviour change: sending either would break a caller that reads a resource and writes it back.
  • The README says what the client and the API do:
    • pagination, and the two options kept only so that callers still compile;
    • error codes in the <Operation>.<Reason> form the API returns (GetInstance.NotFound), also in the comment of Error.Code;
    • an audit event name that exists;
    • base URLs: https://app.kaiten.sh/api on Kaiten Cloud, http://localhost:6060/api and http://localhost:6001/api on a local Community Edition stack, with the Platform listener's default port;
    • /api/openapi.json for the document and /api/docs for the rendered reference;
    • what a refused usage report means for a grant that has an allowance.
  • The README's examples use Kaiten Sushi Shop, the Community Edition's demo dataset, in place of an Acme cast: a reader who loads the demo can run them as written.

Why?

The README stated several things the client does not do, and three inputs accepted a value that silently went nowhere, with nothing saying so.

Testing

Checklist

  • I have read CONTRIBUTING.md.
  • Every commit in this PR includes a valid DCO Signed-off-by line.
  • I have the right to submit all material in this PR.
  • I have not included secrets or confidential data.
  • I have updated tests where appropriate.
  • I have updated documentation where appropriate.
  • I have preserved required third-party licenses and attributions.

🤖 Generated with Claude Code · ✅ Tested and approved by Alex (@Alexkuva), maintainer

Alex (Alexkuva) and others added 5 commits October 13, 2026 23:57
Audit trails are paginated by cursor: the endpoint declares event_name,
after, before, limit and cursor, and no offset. ListAuditTrails stopped
sending Offset when it moved to the cursor walk, but the field still read
as an option that does something. It now carries a Deprecated notice that
says it has no effect and points at Limit. Nothing is removed, so every
caller still compiles.

The comment on Limit said audit trails are never walked to completion.
They are whenever no Limit is set: a nil or zero ceiling walks the whole
trail, like every other list.

TestListAuditTrailsSendsOnlyWhatTheEndpointDeclares pins both: 300 entries
come back over two pages without a Limit, and the query carries the three
filters and the paging pair, with no offset.

Signed-off-by: Alexandre Bergere <alexandre.bergere@kaiten.sh>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Two inputs accept a value that one of their two calls drops, and their
comments either did not say so or gave a reason the API contradicts.

- LicenseInput.Version on create. The comment said the create body declares
  no such field. It does, read-only: the server assigns the number and
  refuses a create that carries one, 422 CreateLicense.VersionNotSettable.
  Not sending it stays right, since an input filled once for both calls
  would otherwise fail every create. The comment now says the value is
  dropped, and what the API would answer.
- ComponentInput.PreviousComponentID on update. The field had no comment,
  and the payload's said the update body does not publish it. The body does
  declare it, and the API refuses any value there, the stored one included,
  422 UpdateComponent.PreviousComponentNotSettable. So Update still does not
  send it: a component read and written back would be refused. The type now
  says the field is create-only.

No behaviour changes: TestRequestBodiesMatchTheirSpecBodies already pins
both payloads without these keys.

Signed-off-by: Alexandre Bergere <alexandre.bergere@kaiten.sh>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Statements the code contradicts, each checked against the client and the
API it calls:

- AuditTrailsOptions.Offset was listed as still sent. It is not: the API
  paginates by cursor only. InstancesListOptions.IncludeDeleted is the one
  that is sent and ignored.
- ListAuditTrails was "the one exception" to lists returning everything.
  It is the one list that takes a ceiling; without a Limit it walks the
  whole trail.
- Error codes are <Operation>.<Reason>: GetInstance.NotFound and
  GetLicense.NotFound, not Instance.NotFound and License.NotFound. The
  comment on Error.Code carried the same example.
- Audit event names are upper snake case: the filter example used
  "instance.updated", which matches nothing.
- Port 3000 is the console's. The Core API is https://app.kaiten.sh/api on
  Kaiten Cloud and http://localhost:6060/api on a local Community Edition
  stack. The Platform API does default to 3001, and the local stack
  publishes it on 6001.
- The API's OpenAPI document is at /api/openapi.json. /api/docs is the
  reference page rendered from it.
- A usage report is refused past what the license grants, allowance
  included, not when it reaches the grant's value.

The Go blocks still compile against the module.

Signed-off-by: Alexandre Bergere <alexandre.bergere@kaiten.sh>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The examples named an Acme organization and entities that exist nowhere:
acme-production, team-v1, seats, api-calls. They now use Kaiten Sushi Shop,
the dataset the Community Edition's demo profile seeds, so a reader who
seeded it finds every name in their console:

- customer Sakura Tokyo and its instance sakura-tokyo-prod, created with
  the slug and the environment metadata the dataset gives it;
- licenses premium-v3, the draft a Publish needs, and premium-v2, the
  version that instance runs on and whose monthly-orders grant is the 1000
  with a 20% allowance the example already described;
- entitlements delivery-drivers and monthly-orders.

Only names and values change. The calls are the same, and every Go block
still compiles against the module.

Signed-off-by: Alexandre Bergere <alexandre.bergere@kaiten.sh>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A flag evaluation is recorded for the organization, not for an instance,
so filtering an instance's trail on it returns nothing on a live stack.
The example filters on INSTANCE_UPDATED.

Signed-off-by: Alexandre Bergere <alexandre.bergere@kaiten.sh>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Alexkuva
Alex (Alexkuva) requested a review from a team as a code owner October 13, 2026 22:03
@Alexkuva
Alex (Alexkuva) merged commit ac34d93 into main Oct 14, 2026
7 checks passed
@Alexkuva
Alex (Alexkuva) deleted the fix/readme-and-dropped-fields branch October 14, 2026 19:12
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.

3 participants