fix(ui-react): stop editing an existing model input from failing at save (#91) - #93
Conversation
Every edit to an existing input failed with: expected one of the values ['_PLACEHOLDER'] for type 'modelcatalog_configuration_input_update_column', but found 'is_optional' Role `user` has insert/select/delete on modelcatalog_configuration_input and no update permission, so under that role Hasura emits the update-column enum with `_PLACEHOLDER` alone and the upsert's `update_columns: [is_optional]` is rejected before it runs. The committed SDL snapshot is the admin schema, where the column does exist, which is why codegen accepted a document no signed-in user can send. Replace the upsert with SetConfigurationInputOptional: delete_by_pk + insert_one in one document, so both root fields run in a single Hasura transaction and the row is never left missing. Call it only when is_optional actually changed — the old code fired it for every row in toUpdate, so editing a label, a format, a description, or the standard variable and unit was enough to fail. Also refetch GetConfiguration before onSaved. ConfigurationDetail reads the same cache entry and nothing wrote to it, so a successful save rendered stale until a manual reload. Fixes #91
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Verified live against TACC, signed in as The core claim was settled with a zero-write probe — Hasura validates before it executes, so
So the new document is accepted where the old one never could be. Nothing was written. End-to-end through the form on
CI note: the first |
Fixes #91. Found on #76, walking the signed-in form against TACC's live catalog.
Fault 1 — the save hard-fails (blocker)
Editing any existing input failed:
Role
userholds insert/select/delete onmodelcatalog_configuration_inputand noupdate permission (
graphql_engine/metadata/tables.yaml:3088). Under that role Hasuraemits the update-column enum with
_PLACEHOLDERalone, soon_conflict.update_columns: [is_optional]is rejected before it runs.InsertConfigurationInputJunctionis replaced bySetConfigurationInputOptional—delete_by_pk+insert_onein one document, so both root fields run in a singleHasura transaction and the row is never left missing. This is the same delete-then-insert
the API layer already uses for junction updates.
The mutation is now called only when
is_optionalactually changed. The old code firedit for every row in
toUpdate, so editing a label, a format, a description — or thestandard variable and unit, which is the SOW workflow — was enough to fail.
Not TACC-specific: it came from this repo's metadata, so it reproduced everywhere.
No metadata change is needed, so nothing has to be applied to TACC's Hasura.
Why codegen never caught it. The committed SDL snapshot is the admin schema, where
is_optionalis an updatable column. Codegen and the offline tests validate against that,never against the
userrole the app actually runs as.Fault 2 — a successful save rendered stale (minor)
ConfigurationDetailreads the sameGetConfigurationcache entry the form does, and nomutation wrote to the cache, so a successful save looked as though nothing happened until a
manual reload. The form now refetches before
onSaved. A failed refresh is swallowed — itmust not report a successful save as failed.
Verification
npm run buildclean; Prettier clean.write unconditional fails the label-edit test, and removing the refetch fails the
refetch test.
graphql.tsdiffis +21/-15, confined to the renamed mutation.
Still unverified: the new document has not been run under a real Tapis token. Both root
fields are individually proven under the
userrole (#76 wrote and deleted junction rows),but the composite mutation needs one live save at
localhost:3000signed in asmosorio@portalsto close #91.