test: guard the entity table against the platform's schema - #4
Merged
Merged
Conversation
The field table is hand-maintained rather than generated, and the docs have always said it can lag a platform release. What they never said is how you would find out: PocketBase silently discards writes to fields a collection does not have, so a flag for a field the platform removed keeps reporting success and doing nothing. That has already happened here -- `nebula-ca --rotate-keys` existed for a while against a collection with no such field. So the tests now compare the table against a vendored copy of the platform's schema, and fail in both directions: a spec field (or KeyColumn, or LookupKey) the platform does not have, and a platform field the CLI neither exposes nor records a reason for. The second is the one that catches lagging behind a release; the first catches writing into the void. Vendored rather than fetched in CI, deliberately. The drift this guards against is exactly the kind you want to see in a diff and approve, and a stale copy fails loudly in the same way a missing one would -- whereas fetching the platform's default branch would let an unrelated platform commit turn this repo's CI red. `cp ../platform/schema.json cmd/testdata/schema.json` is the refresh, documented in the README and in the test, and schema-source.txt records the version. Two lists carry the judgement, and a third test keeps them from rotting: deliberatelyOmitted, which answers "why is there no flag for this" per field, and libraryOwnedFields, which covers fields pb-nats creates on nats_roles that the platform's schema.json does not declare -- allow_response and its two companions. Worth reading that comment: pb-nats's createRolesCollection returns early when the collection exists, so a database created before those fields were added never acquires them and schema.json will not add them either. Same shape as the system_account_id bug the platform fixed in v0.2.0, flagged upstream. Each check was verified by planting the defect it describes -- a fictional spec field, a new platform field, a stale omission entry, a library-owned field the platform has since declared, a missing collection -- and confirming the failure before reverting. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Chore #4, with vendoring. The field table is hand-maintained rather than generated, and the docs have always warned it can lag a platform release — but nothing would ever tell you it had. PocketBase silently discards writes to fields a collection doesn't have, so a flag for a removed field keeps reporting success and doing nothing. That has already happened in this repo:
nebula-ca --rotate-keysexisted for a while against a collection with no such field.The guard
cmd/testdata/schema.jsonis a vendored copy of the platform's collection schema, and the tests fail in both directions:KeyColumn, orLookupKey) the platform doesn't have. Catches writing into the void.Refresh is one command, documented in the README and in the test itself:
cp ../platform/schema.json cmd/testdata/schema.json go test ./...Why vendored and not fetched in CI: the drift being guarded against is exactly the kind you want to see in a diff and approve, and a stale copy fails loudly the same way a missing one would. Fetching the platform's default branch would instead let an unrelated platform commit turn this repo's CI red.
cmd/testdata/schema-source.txtrecords the version the copy came from (currently platform v0.2.0).Two lists carry the judgement, and a third test stops them rotting — a stale entry hides the next real drift:
deliberatelyOmitted— per-collection, with the reason. Secrets (private_key,seed,creds_file), file uploads the CLI can't do (floorplan,logo), operator-only account keys, andnats_users.active, which is omitted because pb-nats consults it nowhere.libraryOwnedFields— see below.One finding worth your attention
nats_rolescarriesallow_response,allow_response_maxandallow_response_ttlin this CLI, and the platform'sschema.jsondeclares none of them. The CLI isn't wrong — pb-nats creates that collection with those fields (internal/collections/manager.go,createRolesCollection) and reads them back when generating a user JWT (internal/types/converters.go). So they exist on a live database while being absent from the platform's dump, which is why they're listed as library-owned rather than as an error.The part worth a second look is in the comment:
createRolesCollectionreturns early when the collection already exists, so a database created before those fields were added never acquires them — and since the platform's schema.json doesn't declare them either,migrate upwon't add them. That's the same shape as thesystem_account_idbug the platform fixed in v0.2.0, whererecord.Seton an undeclared field persisted nothing on every boot. If a database is in that state,allow_responsereads back false forever and role-driven response permissions never reach the JWT. I haven't touched it — it's a platform/pb-nats question, not a CLI one.Verified to fail
PocketBase discards the writeneither exposes nor explainsdrop the entryno longer library-ownedis not in the platform schemaCompanion: the docs fix for the verb columns is stone-age-io/platform-docs#4.
🤖 Generated with Claude Code