Skip to content

feat(presigned-url): add per-bucket mutation entry points on root Mutation type#1071

Merged
pyramation merged 1 commit into
mainfrom
feat/per-bucket-mutation-entry-points
May 8, 2026
Merged

feat(presigned-url): add per-bucket mutation entry points on root Mutation type#1071
pyramation merged 1 commit into
mainfrom
feat/per-bucket-mutation-entry-points

Conversation

@pyramation
Copy link
Copy Markdown
Contributor

Summary

Adds per-bucket mutation fields on the root GraphQL Mutation type so that upload operations (requestUploadUrl, requestBulkUploadUrls) can be accessed as proper mutations instead of queries. Previously, these were only reachable via query fields on bucket types.

For each @storageBuckets-tagged codec, the plugin now adds a mutation field named after the bucket type (e.g., appBucket, dataRoomBucket):

mutation {
  appBucket(key: "public") {
    requestUploadUrl(contentHash: "...", contentType: "...", size: 123) {
      uploadUrl fileId key deduplicated expiresAt
    }
  }
}

Entity-scoped buckets automatically include a required ownerId argument. The mutation resolves the bucket row via getBucketConfig and returns an ObjectStep with access() steps for each codec attribute, so existing sub-field plans (which call $parent.get('column')) continue to work.

Review & Testing Checklist for Human

  • ObjectStep ↔ PgSelectSingleStep compatibility: The mutation plan returns a Grafast object() step, NOT a PgSelectSingleStep. PostGraphile's generated attribute field plans call $parent.get('column') — verify that ObjectStep.get() behaves identically to PgSelectSingleStep.get() for sub-field resolution. This is the highest-risk area and has not been integration-tested.
  • Column coverage gap: getBucketConfig returns only 8 fields (id, key, type, is_public, owner_id, allowed_mime_types, max_file_size, allow_custom_keys), but the object() step is built from Object.keys(codec.attributes) which may include additional columns (e.g., created_at). Selecting those columns through the mutation entry point will return undefined. Verify this is acceptable or if SELECT * should be used instead.
  • Integration test: Run the minio-multi-scope integration test in constructive-db with a mutation { appBucket(...) { requestUploadUrl(...) { ... } } } query to confirm the full plan chain resolves correctly at runtime.

Notes

  • The @pgpmjs/logger type errors in the build output are pre-existing on main (verified by building before and after changes). The workspace-level pnpm build passes cleanly.
  • ownerId uses GraphQLString rather than the PostGraphile UUID scalar — works but is less type-precise.
  • Related: this unblocks updating the failing test in constructive-db PR #1054 to use the mutation API.

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

…ation type

Adds mutation fields for each @storageBuckets-tagged codec on the root
Mutation type (e.g., appBucket(key: "public"): AppBucket). This allows
upload operations (requestUploadUrl, requestBulkUploadUrls) to be accessed
as proper GraphQL mutations instead of queries.

Each mutation entry point resolves a bucket by key (and ownerId for
entity-scoped buckets) and returns the bucket type, so existing upload
fields on the bucket type work as sub-selections:

  mutation {
    appBucket(key: "public") {
      requestUploadUrl(contentHash: "...", contentType: "...", size: 123) {
        uploadUrl fileId key deduplicated expiresAt
      }
    }
  }
@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 9250af5 into main May 8, 2026
53 checks passed
@pyramation pyramation deleted the feat/per-bucket-mutation-entry-points branch May 8, 2026 01:45
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