feat(cli): support custom schemas in records commands via --schema#187
feat(cli): support custom schemas in records commands via --schema#187Fermionic-Lyu wants to merge 1 commit into
Conversation
records list/create/update/delete gain a --schema option that maps to PostgREST's Accept-Profile (reads) / Content-Profile (writes) header, leaving the table path bare. Omitted → backend default (public). Pairs with v2.2.3 custom-schema exposure (InsForge migration 056) and the SDK .schema() support. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
WalkthroughAdds a new ChangesSchema Profile Headers for Records Commands
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
jwfing
left a comment
There was a problem hiding this comment.
Review: feat(cli): support custom schemas in records commands via --schema
Summary: Small, well-scoped change that adds a --schema option to the four records data-API commands by mapping it to PostgREST profile headers via a single centralized helper; the implementation is correct and I found no blocking issues.
Requirements context
No matching spec/plan found under a /docs/superpowers/ directory — this repo keeps design docs in docs/specs/, and the three present there (*-diagnose-*, *-db-migrations-command-design.md) don't cover the records data-API. Assessed against the PR description, the referenced backend migration 056, and SDK PR InsForge-sdk-js#98.
Findings
Critical
(none)
Suggestion
- Software engineering — no command-level test for the header wiring.
src/commands/records/profile.test.ts:1-22thoroughly covers the pure helper, but nothing asserts that each command passes the rightkind. The read/write distinction is easy to mis-wire (a future copy-paste could send'read'fromupdate.ts), and that class of bug would slip past the current suite. I acknowledge there are currently no command-level tests forrecordsat all, so this is consistent with the existing pattern — but a thin test that stubsossFetchand assertslist→Accept-Profileandcreate/update/delete→Content-Profilewould lock in the contract cheaply. Non-blocking.
Information
- Functionality — "default = public" depends on backend
db-schemasordering. The option help text and the doc comment insrc/commands/records/profile.ts:5-6state that omitting--schemafalls back topublic. Per PostgREST semantics (verified against the v14 docs), an absent profile header selects the first schema indb-schemas, not literallypublic. This holds only as long as the InsForge backend listspublicfirst — true today, just worth being aware the guarantee lives in backend config, not the CLI. - Security —
--schemareaches an HTTP header unvalidated, but this is low risk. The value flows intoAccept-Profile/Content-Profile(src/commands/records/profile.ts:14). Node'sfetch/undici rejects header values containing CR/LF, so request-splitting isn't feasible, and PostgREST rejects unknown schemas server-side. No change needed; noting it for completeness. - Verified API correctness. Confirmed against PostgREST v14 docs that reads use
Accept-Profileand all writes — includingDELETE(which carries no body) — useContent-Profile. The mapping inprofile.ts:13is correct. Header merge inossFetch(src/lib/api/oss.ts:166-170) preservesContent-Type/Authorizationwhile adding the profile header, so there's no clobbering.
Dimension coverage
- Software engineering: Helper is unit-tested; import style (
./profile.jsESM extension), error handling, and naming all match surrounding code. Only gap is the wiring test above. - Functionality: All four record commands updated; scope matches the PR claim. No gaps in the CLI layer (cross-schema enforcement is correctly delegated to the backend).
- Security: No auth weakening, no new secrets/PII logged, no new dependencies. See header note above.
- Performance: No new queries, loops, allocations, or blocking I/O — one tiny synchronous object construction per request.
Verdict
approved (informational — no Critical findings; the two Suggestion/Information items are non-blocking). Posted as a comment; explicit GitHub approval remains a human action.
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/commands/records/profile.test.ts (1)
4-22: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd one command-level test for the
ossFetchheader wiring.This suite locks the helper, but not the actual
list/create/update/deleteintegrations. A small mock-based test for one read command and one write command would catch regressions where a subcommand forgets to pass the helper output toossFetch.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/commands/records/profile.test.ts` around lines 4 - 22, Add a command-level test that verifies the `ossFetch` header wiring through at least one read and one write command, since the current suite only covers `schemaProfileHeaders`. Use a mock-based assertion around one of the subcommand handlers (for example `list` and `create`, or equivalent command entry points) to confirm they pass the helper output into `ossFetch` with the expected `Accept-Profile`/`Content-Profile` headers when a schema is provided.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@src/commands/records/profile.test.ts`:
- Around line 4-22: Add a command-level test that verifies the `ossFetch` header
wiring through at least one read and one write command, since the current suite
only covers `schemaProfileHeaders`. Use a mock-based assertion around one of the
subcommand handlers (for example `list` and `create`, or equivalent command
entry points) to confirm they pass the helper output into `ossFetch` with the
expected `Accept-Profile`/`Content-Profile` headers when a schema is provided.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: f0ef0f38-4851-44e5-862b-4fd083f16377
📒 Files selected for processing (6)
src/commands/records/create.tssrc/commands/records/delete.tssrc/commands/records/list.tssrc/commands/records/profile.test.tssrc/commands/records/profile.tssrc/commands/records/update.ts
What
Adds a
--schema <name>option torecords list/create/update/delete. It maps to PostgREST's profile header —Accept-Profilefor reads,Content-Profilefor writes — with the table path left bare. Omitted → backend default (public).New
src/commands/records/profile.ts(schemaProfileHeaders) centralizes the verb→header mapping; covered byprofile.test.ts(3 cases, green on Node 20).Why
Pairs with v2.2.3 custom-schema exposure (InsForge migration 056) and the SDK
.schema()support (InsForge-sdk-js#98), giving the records commands parity for custom schemas.Note
db query(raw SQL) and migrations remain the primary, fully schema-aware data path in the CLI — this just brings therecordsdata-API commands in line.🤖 Generated with Claude Code
Summary by cubic
Adds a
--schema <name>option torecords list/create/update/deleteto target custom schemas via PostgREST profile headers. Defaults topublicwhen omitted.Accept-Profilefor reads andContent-Profilefor writes; table path stays bare.schemaProfileHeadershelper with unit tests..schema().Written for commit 18be0ee. Summary will update on new commits.
Note
Add
--schemaflag to records CLI commands for custom PostgREST schema support--schema <name>option to therecords create,update,delete, andlistcommands.schemaProfileHeadersutility that returnsAccept-Profilefor read operations andContent-Profilefor write operations, or an empty object when no schema is provided.Macroscope summarized 18be0ee.
Summary by CodeRabbit
--schemaoption to records create, list, update, and delete commands, withpublicas the default.