Skip to content

fix: distinguish custom SQL function mutations from CRUD in codegen#1329

Merged
pyramation merged 3 commits into
mainfrom
fix/cli-delete-select-pk-mismatch
Jul 5, 2026
Merged

fix: distinguish custom SQL function mutations from CRUD in codegen#1329
pyramation merged 3 commits into
mainfrom
fix/cli-delete-select-pk-mismatch

Conversation

@pyramation

@pyramation pyramation commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Summary

matchMutationOperations in infer-tables.ts matched mutations purely by naming convention (delete{EntityName}, create{EntityName}). Custom SQL functions like delete_principal() / create_principal() are exposed by PostGraphile as deletePrincipal / createPrincipal — identical to CRUD naming — and were incorrectly claimed as CRUD mutations.

For Principal, the codegen then inferred PK constraints from DeletePrincipalInput { principalId: UUID } (the SQL function arg), produced select: { principalId: true } in the CLI delete handler, but PrincipalSelect only has id → TS error.

Fix: matchMutationOperations now checks the payload type before claiming a mutation as CRUD:

// New helper — CRUD payloads always return the entity:
//   DeleteUserPayload      → { user: User }        ✓ CRUD
//   DeletePrincipalPayload → { result: Boolean }    ✗ custom function
function isCrudMutation(field, entityName, typeMap): boolean {
  const payloadType = typeMap.get(getBaseTypeName(field.type));
  return payloadType.fields.some(
    f => f.name === lcFirst(entityName) && getBaseTypeName(f.type) === entityName
  );
}

Applied to all three CRUD checks (create/update/delete) and their ById/By* variants.

Reverts the earlier reverse-inflection workaround in table-command-generator.ts — the delete select logic is restored to the original pkFields.map(f => f.name: true) since PK constraint names now always come from real CRUD mutations where they match entity field names.

Generated principal.ts: no longer has handleDelete or handleGet (no CRUD delete/update). Commands: list, find-first, create.

Link to Devin session: https://app.devin.ai/sessions/713a7eeac5ee47abae2dc5a13a23e067
Requested by: @pyramation

…aint names

The codegen for CLI delete handlers was using PK constraint field names
(e.g. principalId) in the select clause, but these names come from
PostGraphile's inflected mutation input names and may differ from the
entity's actual field names (e.g. id) in the Select type.

Use buildSelectObject() for delete (same as create/update) to ensure
select uses entity field names that match the generated Select types.
@pyramation pyramation self-assigned this Jul 5, 2026
@devin-ai-integration

Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

…g all fields

Map PK constraint names back to entity field names via reverse inflection
(e.g. principalId → id) so delete select stays minimal while using correct
field names that exist on the generated *Select type.
matchMutationOperations now checks the payload type before claiming a
mutation as CRUD.  PostGraphile CRUD payloads always contain a field
named lcFirst(entityName) whose type is the entity (e.g. DeleteUserPayload
has `user: User`).  Custom SQL-function mutations that happen to follow
the same naming convention (e.g. `deletePrincipal`) return something
else — typically `result: Boolean` — and are no longer mistaken for CRUD.

This fixes Principal, whose delete/create are custom SQL functions
(`delete_principal()`, `create_principal()`) that PostGraphile exposes
as `deletePrincipal` / `createPrincipal`.  The codegen was treating
these as standard CRUD mutations, which caused a TS error because the
inferred PK constraint name (`principalId`, from the function arg) did
not match the entity field name (`id`) in PrincipalSelect.

Reverts the earlier reverse-inflection workaround in
table-command-generator.ts — the root cause is now fixed upstream in
infer-tables.ts.
@devin-ai-integration devin-ai-integration Bot changed the title fix: use entity field names in CLI delete select instead of PK constraint names fix: distinguish custom SQL function mutations from CRUD in codegen Jul 5, 2026
@pyramation pyramation merged commit 39477ca into main Jul 5, 2026
37 checks passed
@pyramation pyramation deleted the fix/cli-delete-select-pk-mismatch branch July 5, 2026 03:59
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.

1 participant