Skip to content

fix(presigned-url): codec table name matching + ownerId type resolution#1073

Merged
pyramation merged 2 commits intomainfrom
fix/resolve-storage-config-codec-name
May 8, 2026
Merged

fix(presigned-url): codec table name matching + ownerId type resolution#1073
pyramation merged 2 commits intomainfrom
fix/resolve-storage-config-codec-name

Conversation

@pyramation
Copy link
Copy Markdown
Contributor

@pyramation pyramation commented May 8, 2026

Summary

Two fixes to the presigned-url plugin's mutation entry points (added in PR #1071 / #1072):

1. Use raw SQL table name for codec-to-storage-module lookup

resolveStorageConfigFromCodec was comparing pgCodec.name against metaschema table names (bucketsTableName / filesTableName). In PostGraphile v5, pgCodec.name is the inflected codec name (set via inflection.classCodecName(), e.g. appBuckets), while metaschema stores the raw SQL table name (e.g. app_buckets). The raw name is available at pgCodec.extensions.pg.name (set from pgClass.relname in PgCodecsPlugin).

This mismatch caused STORAGE_MODULE_NOT_FOUND errors whenever requestUploadUrl or requestBulkUploadUrls was called through the mutation entry points.

The fix reads from extensions.pg.name with a fallback to pgCodec.name for backward compatibility.

2. Resolve ownerId argument type from codec attribute

The ownerId mutation argument was hardcoded as GraphQLString. For codecs where owner_id is a UUID column, Grafast's type matching (referential equality via ===) rejects $ownerId: UUID! variables because GraphQLString !== UUID scalar.

The fix uses build.getGraphQLTypeByPgCodec(codec.attributes.owner_id.codec, 'input') to resolve the correct GraphQL scalar type from the codec's attribute definition, with a fallback to GraphQLString if the lookup returns null.

Related: This unblocks constructive-db PR #1054 which rewrites the minio-multi-scope integration tests to use the per-bucket mutation API.

Review & Testing Checklist for Human

  • Verify getGraphQLTypeByPgCodec returns the expected UUID scalar — the call uses (build as any) to bypass TypeScript; confirm at runtime that ownerIdType resolves to the UUID scalar (not null) for entity-scoped bucket codecs
  • Check codec.attributes.owner_id.codec access is safe — it's guarded by hasOwnerId = !!codec.attributes.owner_id, but verify that the .codec sub-property is always present on attribute definitions
  • Confirm end-to-end by publishing as a patch version and running constructive-db minio-multi-scope integration tests with $ownerId: UUID! (not String!) — this plugin has no local tests for either fix
  • Grep for other pgCodec.name usages in plugin.ts and storage-module-cache.ts to check for similar raw-vs-inflected mismatches

Notes

  • The type signature on resolveStorageConfigFromCodec was updated to include name?: string in the pg extension type so TypeScript knows about the field.
  • The ownerIdType fallback (|| GraphQLString) preserves the old behavior if getGraphQLTypeByPgCodec returns null for any reason.
  • Both fixes are backward-compatible: the extensions.pg.name fallback uses pgCodec.name, and the ownerIdType fallback uses GraphQLString.

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

resolveStorageConfigFromCodec was using pgCodec.name (inflected codec
name, e.g. 'appBuckets') instead of pgCodec.extensions.pg.name (raw
SQL table name, e.g. 'app_buckets'). The metaschema stores raw SQL
table names, so the match always failed → STORAGE_MODULE_NOT_FOUND.
@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 and CI monitoring

Use build.getGraphQLTypeByPgCodec() to resolve the ownerId argument
type from the codec's owner_id attribute (e.g. UUID scalar) instead
of hardcoding GraphQLString. Grafast uses referential equality for
type matching, so $ownerId: UUID! failed against String!.
@devin-ai-integration devin-ai-integration Bot changed the title fix(presigned-url): use extensions.pg.name for codec table name matching fix(presigned-url): codec table name matching + ownerId type resolution May 8, 2026
@pyramation pyramation merged commit 379d8af into main May 8, 2026
53 checks passed
@pyramation pyramation deleted the fix/resolve-storage-config-codec-name branch May 8, 2026 05:47
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