Skip to content

fix(presigned-url): return PgSelectSingleStep from mutation entry points#1072

Merged
pyramation merged 1 commit intomainfrom
fix/presigned-url-mutation-step-type
May 8, 2026
Merged

fix(presigned-url): return PgSelectSingleStep from mutation entry points#1072
pyramation merged 1 commit intomainfrom
fix/presigned-url-mutation-step-type

Conversation

@pyramation
Copy link
Copy Markdown
Contributor

Summary

The per-bucket mutation entry points added in #1071 returned a generic Grafast object() step, which PostGraphile v5 rejects at runtime because sub-fields like requestUploadUrl call $parent.get('column_name') — a method only available on PgSelectSingleStep (and similar Pg step types).

Before: The plan function manually fetched bucket config via lambda + withPgClient, then wrapped individual columns in access() calls and returned object(columnEntries). This produced an ObjectStep that PostGraphile couldn't use for sub-field resolution.

After: The plan function looks up the PgResource for the bucket codec at schema build time, then calls bucketResource.find(spec).single() in the plan. This returns a proper PgSelectSingleStep, which PostGraphile can use to resolve sub-fields via .get().

Review & Testing Checklist for Human

  • RLS / auth context: The old code explicitly passed pgSettings via withPgClient. Verify that resource.find() goes through PostGraphile's normal auth pipeline (selectAuth) so that RLS policies are respected on the bucket lookup.
  • Resource lookup filter: The filter !r.isUnique && !r.isVirtual && !r.parameters is intended to find the primary table resource for each codec. Confirm this won't accidentally match a view or function resource if one exists for a bucket codec.
  • End-to-end validation: This plugin has no unit tests for the mutation entry points. The real proof is the minio-multi-scope.integration.test.ts in constructive-db (PR #1054). After publishing, run those integration tests to confirm the full mutation { appBucket(key: "public") { requestUploadUrl(...) { ... } } } flow works.

Notes

  • The capturedCodec variable was removed since it's no longer needed (the resource lookup replaces the manual column iteration).
  • Entity-scoped buckets pass owner_id in the find spec using the SQL column name, while the GraphQL arg is ownerId — this is correct since resource.find() expects codec attribute names.

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

The mutation entry points were returning a generic Grafast object() step,
which PostGraphile v5 rejects because sub-fields (requestUploadUrl, etc.)
expect a PgSelectSingleStep to resolve column values via $parent.get().

Replace the manual lambda + object() approach with resource.find(spec).single()
which returns a proper PgSelectSingleStep.
@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

@pyramation pyramation merged commit a4fafea into main May 8, 2026
53 checks passed
@pyramation pyramation deleted the fix/presigned-url-mutation-step-type branch May 8, 2026 04:18
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