Skip to content

Conversation

@coratgerl
Copy link
Contributor

@coratgerl coratgerl commented Nov 29, 2025

Pull Request

Issue

Fixes: #7702

  • Add tests
  • Add changes to documentation (guides, repository pages, code comments)
  • Add security check
  • Add new Parse Error codes to Parse JS SDK

Summary by CodeRabbit

  • New Features

    • Added a GraphQL query to retrieve cloud configuration parameters and a GraphQL mutation to update them, including the ability to mark parameters as master-key only.
    • Permission enforcement: updates require master-key when marked so; queries reflect master-key restrictions.
  • Tests

    • Added end-to-end tests for config retrieval, updates, master-key permission checks, and handling of missing parameters.

✏️ Tip: You can customize this high-level summary in your review settings.

@parse-github-assistant
Copy link

parse-github-assistant bot commented Nov 29, 2025

🚀 Thanks for opening this pull request!

@coderabbitai
Copy link

coderabbitai bot commented Nov 29, 2025

📝 Walkthrough

Walkthrough

Adds GraphQL support for Parse Config: introduces a new cloudConfig query and updateCloudConfig mutation, implements loaders and schema wiring, integrates them into default GraphQL loaders, and adds end-to-end tests covering fetch, update, and master-key permission behavior.

Changes

Cohort / File(s) Summary
Schema updates
src/GraphQL/ParseGraphQLSchema.js
Added reserved names cloudConfig (query) and updateCloudConfig (mutation); introduced and reset cloudConfigType on schema for caching the ConfigValue GraphQL type.
Config Query Loader
src/GraphQL/loaders/configQueries.js
New loader exporting load and cloudConfig. Adds cloudConfig(paramName: String!) query, enforces master-key access, reads _GlobalConfig (objectId 1), and returns { value, isMasterKeyOnly } (or { null, null } when missing). Defines/caches ConfigValue GraphQL type on schema.
Config Mutation Loader
src/GraphQL/loaders/configMutations.js
New loader exporting load and updateCloudConfig. Adds updateCloudConfig(paramName: String!, value: String!, isMasterKeyOnly: Boolean = false) mutation, enforces master-key access, delegates updates to GlobalConfigRouter, and returns updated { cloudConfig }.
Default loader integration
src/GraphQL/loaders/defaultGraphQLQueries.js, src/GraphQL/loaders/defaultGraphQLMutations.js
Imported and invoked configQueries.load(parseGraphQLSchema) and configMutations.load(parseGraphQLSchema) to register new query/mutation during default schema loading.
Tests
spec/ParseGraphQLServer.spec.js
Added tests that save initial config via Parse.Config.save, query cloudConfig (including non-existent -> null), perform updateCloudConfig mutations with isMasterKeyOnly true/false, and assert master-key permission enforcement.
Manifest
package.json
Listed in manifest (no public API signature changes).

Sequence Diagram(s)

sequenceDiagram
    autonumber
    actor Client
    participant GraphQLServer as GraphQL Server
    participant Schema as ParseGraphQLSchema
    participant Loader as configQueries / configMutations
    participant Router as GlobalConfigRouter
    participant DB as _GlobalConfig (DB)

    Client->>GraphQLServer: GraphQL query/mutation (cloudConfig / updateCloudConfig)
    GraphQLServer->>Schema: resolve field
    Schema->>Loader: cloudConfig(paramName) / updateCloudConfig(...)
    Loader->>Schema: verify masterKey present (if required)
    alt masterKey check passes
        Loader->>Router: read/update param (objectId: "1")
        Router->>DB: read/write _GlobalConfig document
        DB-->>Router: return doc / ack
        Router-->>Loader: return value + isMasterKeyOnly
        Loader-->>Schema: payload { cloudConfig }
        Schema-->>GraphQLServer: response
        GraphQLServer-->>Client: GraphQL response (value, isMasterKeyOnly)
    else masterKey missing
        Loader-->>Schema: throw permission error
        Schema-->>GraphQLServer: error
        GraphQLServer-->>Client: GraphQL error (requires master key)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–25 minutes

  • Check master-key enforcement and error handling in configQueries.js and configMutations.js.
  • Verify GraphQL type definitions, nullability, and caching behavior of cloudConfigType in ParseGraphQLSchema.js.
  • Ensure integration ordering in defaultGraphQLQueries.js / defaultGraphQLMutations.js does not conflict with existing reserved names.
  • Review tests in spec/ParseGraphQLServer.spec.js for correctness and edge-case coverage.

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description check ✅ Passed The PR description follows the template structure with a linked issue (#7702), completed checklist for 'Add tests', and standard contribution/license links.
Linked Issues check ✅ Passed The PR implements the requested feature from issue #7702 by adding GraphQL types, queries, and mutations for Parse Config operations with appropriate master key enforcement.
Out of Scope Changes check ✅ Passed All changes are scoped to implementing GraphQL support for Parse Config, including loaders, schema integration, and comprehensive test coverage. No unrelated changes detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed The title accurately describes the main additions: a GraphQL query cloudConfig and mutation updateCloudConfig for Parse Config management, matching the core changes in the PR.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@parseplatformorg
Copy link
Contributor

parseplatformorg commented Nov 29, 2025

Snyk checks have passed. No issues have been found so far.

Status Scanner Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@codecov
Copy link

codecov bot commented Nov 29, 2025

Codecov Report

❌ Patch coverage is 94.73684% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.56%. Comparing base (6d67013) to head (5f2f6ba).
⚠️ Report is 2 commits behind head on alpha.

Files with missing lines Patch % Lines
src/GraphQL/loaders/configQueries.js 88.88% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##            alpha    #9947      +/-   ##
==========================================
- Coverage   92.57%   92.56%   -0.02%     
==========================================
  Files         189      191       +2     
  Lines       15488    15544      +56     
  Branches      177      177              
==========================================
+ Hits        14338    14388      +50     
- Misses       1138     1144       +6     
  Partials       12       12              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (4)
spec/ParseGraphQLServer.spec.js (4)

7085-7090: Clarify Parse.Config.save usage with 3rd { useMasterKey: true } argument

In both config test setups you call Parse.Config.save with three arguments, passing { useMasterKey: true } as a third options object. The Parse JS SDK API currently documents Parse.Config.save(attrs, masterKeyOnlyFlags) with only two parameters, with master-key use typically handled via SDK initialization or Config.get({ useMasterKey: true }) rather than a third options argument. (parseplatform.org)

Because extra arguments are silently ignored in JS, this is unlikely to break anything, but it can be misleading for future readers and might not behave as intended across SDK versions.

I’d suggest either:

  • Dropping the third argument and relying on the test SDK being initialized with a master key, or
  • Adding a short comment noting that the 3‑arg form is intentional and supported by the SDK version used here.

Also applies to: 7262-7266


7083-7142: Broaden coverage of configValue query, especially around master‑key‑only flags

These tests validate the happy path and non‑existent parameter handling, but they currently only hit:

  • publicParam with a master key, and
  • a non‑existent parameter with a master key.

Given the semantics of isMasterKeyOnly, it would be useful (and security‑relevant) to add tests that:

  • Read publicParam without a master key and assert it’s returned as expected.
  • Read privateParam with a master key and assert value and isMasterKeyOnly are correct.
  • Read privateParam without a master key and assert the behavior you intend (e.g. configValue is null or a permission error).

That will lock in the intended access‑control behavior for config reads via GraphQL.


7144-7359: Tighten updateConfigValue mutation tests (clientMutationId and access behavior)

The mutation tests exercise creation, updating, and master‑key enforcement, but there are a couple of easy wins to strengthen them:

  • Each test passes a clientMutationId, yet none assert that updateConfigValue echoes it back. Adding expect(mutationResult.data.updateConfigValue.clientMutationId).toBe('<id>') would verify the Relay‑style contract.
  • For the isMasterKeyOnly: true case, you only read the value again with a master key. It would be helpful to also query configValue for that param without a master key and assert the expected behavior (e.g. hidden vs. error), mirroring the intended security semantics.

These changes would make the new GraphQL surface more robustly specified without altering the implementation.


7083-7359: Suggested Angular-style PR title for changelog

To align with the repository’s changelog conventions, a more descriptive PR title could be:

feat(graphql): expose Parse Config via GraphQL queries and mutations

This captures both the scope (graphql) and the key behavior change.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a906a11 and e92b88f.

📒 Files selected for processing (6)
  • spec/ParseGraphQLServer.spec.js (1 hunks)
  • src/GraphQL/ParseGraphQLSchema.js (3 hunks)
  • src/GraphQL/loaders/configMutations.js (1 hunks)
  • src/GraphQL/loaders/configQueries.js (1 hunks)
  • src/GraphQL/loaders/defaultGraphQLMutations.js (1 hunks)
  • src/GraphQL/loaders/defaultGraphQLQueries.js (2 hunks)
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: mtrezza
Repo: parse-community/parse-server PR: 0
File: :0-0
Timestamp: 2025-11-17T15:02:48.786Z
Learning: For Parse Server PRs, always suggest an Angular commit convention PR title that would make a meaningful changelog entry for developers. Update the PR title suggestion on every commit. The format should be: type(scope): description. Common types include feat, fix, perf, refactor, docs, test, chore. The scope should identify the subsystem (e.g., graphql, rest, push, security). The description should be action-oriented and clearly convey the change's impact to developers.
Learnt from: mtrezza
Repo: parse-community/parse-server PR: 0
File: :0-0
Timestamp: 2025-11-08T13:46:04.940Z
Learning: When reviewing Parse Server PRs that add new features, always check whether the feature is documented in the README.md file, though for new Parse Server options this is optional rather than required.
Learnt from: mtrezza
Repo: parse-community/parse-server PR: 9858
File: src/GraphQL/ParseGraphQLServer.js:176-178
Timestamp: 2025-09-21T15:43:32.265Z
Learning: The GraphQL playground feature in ParseGraphQLServer.js (applyPlayground method) is intended for development environments only, which is why it includes the master key in client-side headers.
📚 Learning: 2025-04-30T19:31:35.344Z
Learnt from: RahulLanjewar93
Repo: parse-community/parse-server PR: 9744
File: spec/ParseLiveQuery.spec.js:0-0
Timestamp: 2025-04-30T19:31:35.344Z
Learning: In the Parse Server codebase, the functions in QueryTools.js are typically tested through end-to-end behavior tests rather than direct unit tests, even though the functions are exported from the module.

Applied to files:

  • spec/ParseGraphQLServer.spec.js
📚 Learning: 2025-11-08T13:46:04.940Z
Learnt from: mtrezza
Repo: parse-community/parse-server PR: 0
File: :0-0
Timestamp: 2025-11-08T13:46:04.940Z
Learning: For new Parse Server options, verify that the option is documented in src/Options/index.js and that npm run definitions has been executed to reflect changes in src/Options/docs.js and src/Options/Definitions.js. README.md documentation is a bonus but not required for new options.

Applied to files:

  • spec/ParseGraphQLServer.spec.js
📚 Learning: 2025-11-17T15:02:48.786Z
Learnt from: mtrezza
Repo: parse-community/parse-server PR: 0
File: :0-0
Timestamp: 2025-11-17T15:02:48.786Z
Learning: For Parse Server PRs, always suggest an Angular commit convention PR title that would make a meaningful changelog entry for developers. Update the PR title suggestion on every commit. The format should be: type(scope): description. Common types include feat, fix, perf, refactor, docs, test, chore. The scope should identify the subsystem (e.g., graphql, rest, push, security). The description should be action-oriented and clearly convey the change's impact to developers.

Applied to files:

  • spec/ParseGraphQLServer.spec.js
📚 Learning: 2025-09-21T15:43:32.265Z
Learnt from: mtrezza
Repo: parse-community/parse-server PR: 9858
File: src/GraphQL/ParseGraphQLServer.js:176-178
Timestamp: 2025-09-21T15:43:32.265Z
Learning: The GraphQL playground feature in ParseGraphQLServer.js (applyPlayground method) is intended for development environments only, which is why it includes the master key in client-side headers.

Applied to files:

  • spec/ParseGraphQLServer.spec.js
📚 Learning: 2025-05-09T09:59:06.289Z
Learnt from: mtrezza
Repo: parse-community/parse-server PR: 9445
File: spec/ParseLiveQuery.spec.js:1340-1375
Timestamp: 2025-05-09T09:59:06.289Z
Learning: New tests in the parse-server repository should use async/await with promise-based patterns rather than callback patterns with `done()`. The preferred pattern is to create a Promise that resolves when an expected event occurs, then await that Promise.

Applied to files:

  • spec/ParseGraphQLServer.spec.js
📚 Learning: 2025-05-04T20:41:05.147Z
Learnt from: mtrezza
Repo: parse-community/parse-server PR: 9445
File: spec/ParseLiveQuery.spec.js:1312-1338
Timestamp: 2025-05-04T20:41:05.147Z
Learning: New tests in the parse-server repository should use async/await with promise-based patterns rather than callback patterns with `done()`.

Applied to files:

  • spec/ParseGraphQLServer.spec.js
🧬 Code graph analysis (4)
src/GraphQL/loaders/configMutations.js (3)
src/Routers/GlobalConfigRouter.js (1)
  • GlobalConfigRouter (16-100)
src/GraphQL/loaders/configQueries.js (2)
  • context (6-6)
  • load (32-59)
src/GraphQL/loaders/defaultGraphQLMutations.js (1)
  • load (7-13)
src/GraphQL/loaders/defaultGraphQLQueries.js (3)
src/GraphQL/loaders/parseClassMutations.js (1)
  • parseGraphQLSchema (53-57)
src/GraphQL/transformers/mutation.js (1)
  • parseGraphQLSchema (11-15)
src/GraphQL/loaders/parseClassQueries.js (1)
  • parseGraphQLSchema (55-59)
src/GraphQL/loaders/defaultGraphQLMutations.js (2)
src/GraphQL/loaders/configMutations.js (1)
  • load (32-73)
src/GraphQL/loaders/configQueries.js (1)
  • load (32-59)
src/GraphQL/loaders/configQueries.js (3)
src/GraphQL/loaders/configMutations.js (2)
  • context (10-10)
  • load (32-73)
src/GraphQL/loaders/defaultGraphQLMutations.js (1)
  • load (7-13)
src/GraphQL/loaders/defaultGraphQLQueries.js (1)
  • load (6-21)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (16)
  • GitHub Check: Node 18
  • GitHub Check: MongoDB 6, ReplicaSet
  • GitHub Check: MongoDB 8, ReplicaSet
  • GitHub Check: Redis Cache
  • GitHub Check: Node 22
  • GitHub Check: PostgreSQL 17, PostGIS 3.5
  • GitHub Check: MongoDB 7, ReplicaSet
  • GitHub Check: PostgreSQL 16, PostGIS 3.5
  • GitHub Check: PostgreSQL 15, PostGIS 3.4
  • GitHub Check: Node 20
  • GitHub Check: PostgreSQL 18, PostGIS 3.6
  • GitHub Check: PostgreSQL 15, PostGIS 3.3
  • GitHub Check: PostgreSQL 15, PostGIS 3.5
  • GitHub Check: Docker Build
  • GitHub Check: Code Analysis (javascript)
  • GitHub Check: Benchmarks
🔇 Additional comments (13)
src/GraphQL/loaders/defaultGraphQLMutations.js (1)

5-12: Config mutations wiring and load order look correct

Importing configMutations and calling configMutations.load(parseGraphQLSchema) aligns with the existing loader pattern, and with defaultGraphQLQueries.load being invoked before defaultGraphQLMutations.load, configValueType should already be initialized when mutations are registered. It would be good to keep tests that implicitly cover this ordering so regressions are caught if the loader sequence ever changes.

src/GraphQL/loaders/defaultGraphQLQueries.js (1)

4-20: Config queries are integrated consistently with existing default loaders

Adding configQueries and invoking configQueries.load(parseGraphQLSchema) after the existing default queries cleanly wires the new configValue query into the auto schema without affecting the health or user/schema queries. This matches the established loader pattern and ensures configValueType is created before config mutations are registered.

src/GraphQL/ParseGraphQLSchema.js (2)

116-125: Resetting configValueType alongside other cached schema state is appropriate

Initializing this.configValueType = null together with parseClassTypes, viewerType, and other cached fields ensures that each schema rebuild gets a fresh ConfigValue type created by configQueries.load, avoiding stale references across reloads. This matches the existing initialization pattern and looks correct.


52-63: Based on my investigation, I was unable to directly access the codebase or locate the specific PR details due to repository cloning failures. However, through web searches, I was able to verify the surrounding context:

  1. Reserved GraphQL names pattern is confirmed: Parse Server does use reserved names (e.g., health) to prevent collisions with auto-generated queries/mutations, and the addGraphQLQuery/addGraphQLMutation pattern is real and documented.

  2. New feature indicators: configValue, updateConfigValue, and configValueType do not appear in current Parse Server public documentation, which strongly suggests they are new features being added in this PR.

  3. Pattern validation: The review comment's reasoning about reserving names to prevent collisions and resetting cached types during schema rebuilds aligns with standard GraphQL schema management practices.

The review comment's technical analysis appears sound, though I cannot verify specific line numbers or implementation details without file access. The concern about potential ecosystem impact on extensions that might have previously tried to use these names is valid and worth documenting.

Reserving configValue / updateConfigValue prevents collisions with the new built‑in config operations

Adding configValue to RESERVED_GRAPHQL_QUERY_NAMES and updateConfigValue to RESERVED_GRAPHQL_MUTATION_NAMES correctly protects the new built‑in operations from accidental collisions via addGraphQLQuery / addGraphQLMutation. This is a behavior change: any extensions that previously tried to register fields with these names will now be rejected unless they explicitly bypass the reservations. For an alpha feature, this is acceptable, but document the breaking change in release notes and GraphQL documentation.

src/GraphQL/loaders/configQueries.js (3)

1-3: Imports look appropriate for the module's needs.

Standard GraphQL types, Parse SDK for error codes, and the sanitized error utility are correctly imported.


5-13: Master key enforcement is correctly implemented.

The function properly checks auth.isMaster before allowing access to GlobalConfig, consistent with the REST API's behavior in GlobalConfigRouter.


32-43: ConfigValue type registration with caching is well-implemented.

The guard if (!parseGraphQLSchema.configValueType) prevents duplicate type registration, and the type is properly cached on the schema for reuse by the mutation.

src/GraphQL/loaders/configMutations.js (6)

1-7: Module structure and router instantiation look appropriate.

Imports are correct. The module-level GlobalConfigRouter singleton is acceptable for reusing the existing config update logic.


9-30: Master key enforcement and delegation to GlobalConfigRouter are well-implemented.

The function correctly:

  • Validates master key access before proceeding
  • Reuses GlobalConfigRouter.updateGlobalConfig for consistency with REST API behavior
  • Structures the request object to match the router's expected format

32-55: Mutation definition follows graphql-relay conventions correctly.

Input fields with proper types and descriptions, and output fields referencing the shared configValueType from the schema are well-structured.


70-72: Mutation type registration is correctly handled.

Both input and output types are registered before the mutation itself, ensuring proper schema construction.


57-66: Missing await causes errors to escape the catch block.

Same issue as in configQueries.js: updateConfigValue is async, so without await, rejected promises bypass the try/catch and won't be handled by parseGraphQLSchema.handleError.

     mutateAndGetPayload: async (args, context) => {
       try {
         const { paramName, value, isMasterKeyOnly } = args;
-        const result = await updateConfigValue(context, paramName, value, isMasterKeyOnly);
+        const result = await updateConfigValue(context, paramName, value, isMasterKeyOnly);
         return {
           configValue: result,
         };
       } catch (e) {
         parseGraphQLSchema.handleError(e);
       }
     },

Wait, I see await is actually present on line 60. Let me re-check... The issue is that mutateAndGetPayload returns undefined if an error is caught (line 65 calls handleError but doesn't return or re-throw). This could cause downstream issues.

Actually, looking more carefully - the await IS present on line 60. My mistake. Let me revise:


64-66: Let me search the web for information about the handleError implementation in the parse-server repository:
<function_calls>
web_search
parse-server parseGraphQLSchema handleError implementation

</function_calls>

coderabbitai[bot]
coderabbitai bot previously approved these changes Nov 29, 2025
@coratgerl
Copy link
Contributor Author

@mtrezza @Moumouls This one is ready for review :)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (5)
spec/ParseGraphQLServer.spec.js (3)

7083-7142: Consider adding tests for master-key-only and unauthorized config queries

The happy-path coverage for cloudConfig (existing param and non-existent param) looks good. For completeness and to guard security semantics, I suggest adding:

  • A test that queries a master-key-only param (e.g. privateParam seeded in beforeEach) and asserts the expected value / isMasterKeyOnly behavior when called with the master key.
  • A negative test that calls cloudConfig without the master key and asserts the expected error shape (e.g. OPERATION_FORBIDDEN / “Permission denied”) or redaction behavior, whichever the implementation guarantees.

That would align these config tests with the other master-key permission checks in this spec.


7145-7359: Strengthen the permission assertion in the master-key-required mutation test

The mutation tests cover the main flows well. In it("should require master key to update config", ...), you currently only assert that the error message contains “Permission denied”. For consistency with the rest of this spec (e.g. class schema mutation tests), consider also asserting the GraphQL error code:

-        } catch (error) {
-          expect(error.graphQLErrors).toBeDefined();
-          expect(error.graphQLErrors[0].message).toContain('Permission denied');
-        }
+        } catch (error) {
+          expect(error.graphQLErrors).toBeDefined();
+          expect(error.graphQLErrors[0].extensions.code).toBe(Parse.Error.OPERATION_FORBIDDEN);
+          expect(error.graphQLErrors[0].message).toContain('Permission denied');
+        }

This will make the test more resilient to wording changes while still verifying the permissions contract.


7083-7359: PR metadata: Angular-style title and docs follow-up for GraphQL config feature

Since this PR adds a new GraphQL surface for Parse Config, two non-code suggestions:

  • PR title: to align with the Angular convention used in this repo, a more specific title like
    feat(graphql-config): add GraphQL support for Parse Config
    would read well in the changelog and clearly signal the affected subsystem.
  • Docs: once the implementation settles, it would be good to document the new cloudConfig query and updateCloudConfig mutation in the GraphQL guide / README, including examples for public vs. master-key-only parameters.

Based on learnings, this helps downstream developers quickly understand and discover the new capability.

src/GraphQL/loaders/configMutations.js (2)

9-30: Consider deriving mutation output from persisted config instead of echoing inputs

updateCloudConfig currently returns { value, isMasterKeyOnly } based solely on the mutation arguments. If GlobalConfigRouter.updateGlobalConfig ever normalizes or transforms values (or merges with existing config state), the mutation response could drift from what cloudConfig would return for the same param.

To keep read / write behavior aligned and make tests more robust, consider re-reading the value after the router call (e.g., via the existing cloudConfig helper) and returning that instead:

 const updateCloudConfig = async (context, paramName, value, isMasterKeyOnly = false) => {
   const { config, auth } = context;

@@
   await globalConfigRouter.updateGlobalConfig({
@@
   });

-  return { value, isMasterKeyOnly };
+  // Option A: re-read via existing query helper for consistent behavior
+  // return cloudConfig(context, paramName);
+
+  // Option B: if you prefer to avoid the extra read, at least derive
+  // isMasterKeyOnly from the stored config in a follow-up change.
+  return { value, isMasterKeyOnly };
 };

Even if you defer the extra read for now, it’s worth considering for long‑term consistency between query and mutation behavior.


32-73: PR-level: commit title format and documentation for new GraphQL config API

Two higher-level suggestions for the PR overall (not specific to this file’s logic):

  1. Commit / PR title formatting

    To follow the Angular-style convention used in this repo and make the changelog clearer, consider adjusting the PR title to something like:

    • feat(graphql): add Parse Config query and mutation

    This highlights both the scope (graphql) and the functional change.

  2. Documentation for new GraphQL features

    Since this adds a public GraphQL query (cloudConfig) and mutation (updateCloudConfig), it would be helpful to:

    • Mention them in the GraphQL section of the README or relevant docs (including arguments, return type, and master-key behavior).
    • Optionally add a short example query / mutation to guide users.

    If you’d like, I can help sketch the README / guide snippet based on the current schema.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a6c2bf2 and d8d0d79.

📒 Files selected for processing (4)
  • spec/ParseGraphQLServer.spec.js (1 hunks)
  • src/GraphQL/ParseGraphQLSchema.js (3 hunks)
  • src/GraphQL/loaders/configMutations.js (1 hunks)
  • src/GraphQL/loaders/configQueries.js (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/GraphQL/ParseGraphQLSchema.js
🧰 Additional context used
🧠 Learnings (11)
📓 Common learnings
Learnt from: mtrezza
Repo: parse-community/parse-server PR: 0
File: :0-0
Timestamp: 2025-11-17T15:02:48.786Z
Learning: For Parse Server PRs, always suggest an Angular commit convention PR title that would make a meaningful changelog entry for developers. Update the PR title suggestion on every commit. The format should be: type(scope): description. Common types include feat, fix, perf, refactor, docs, test, chore. The scope should identify the subsystem (e.g., graphql, rest, push, security). The description should be action-oriented and clearly convey the change's impact to developers.
Learnt from: mtrezza
Repo: parse-community/parse-server PR: 0
File: :0-0
Timestamp: 2025-11-08T13:46:04.940Z
Learning: When reviewing Parse Server PRs that add new features, always check whether the feature is documented in the README.md file, though for new Parse Server options this is optional rather than required.
Learnt from: mtrezza
Repo: parse-community/parse-server PR: 9858
File: src/GraphQL/ParseGraphQLServer.js:176-178
Timestamp: 2025-09-21T15:43:32.265Z
Learning: The GraphQL playground feature in ParseGraphQLServer.js (applyPlayground method) is intended for development environments only, which is why it includes the master key in client-side headers.
📚 Learning: 2025-05-09T09:59:06.289Z
Learnt from: mtrezza
Repo: parse-community/parse-server PR: 9445
File: spec/ParseLiveQuery.spec.js:1340-1375
Timestamp: 2025-05-09T09:59:06.289Z
Learning: Tests in the parse-server repository should use promise-based approaches rather than callback patterns with `done()`. Use a pattern where a Promise is created that resolves when the event occurs, then await that promise.

Applied to files:

  • src/GraphQL/loaders/configQueries.js
  • spec/ParseGraphQLServer.spec.js
📚 Learning: 2025-05-09T09:59:06.289Z
Learnt from: mtrezza
Repo: parse-community/parse-server PR: 9445
File: spec/ParseLiveQuery.spec.js:1340-1375
Timestamp: 2025-05-09T09:59:06.289Z
Learning: New tests in the parse-server repository should use async/await with promise-based patterns rather than callback patterns with `done()`. The preferred pattern is to create a Promise that resolves when an expected event occurs, then await that Promise.

Applied to files:

  • src/GraphQL/loaders/configQueries.js
  • spec/ParseGraphQLServer.spec.js
📚 Learning: 2025-05-04T20:41:05.147Z
Learnt from: mtrezza
Repo: parse-community/parse-server PR: 9445
File: spec/ParseLiveQuery.spec.js:1312-1338
Timestamp: 2025-05-04T20:41:05.147Z
Learning: New tests in the parse-server repository should use async/await with promise-based patterns rather than callback patterns with `done()`.

Applied to files:

  • src/GraphQL/loaders/configQueries.js
  • spec/ParseGraphQLServer.spec.js
📚 Learning: 2025-10-16T19:27:05.311Z
Learnt from: Moumouls
Repo: parse-community/parse-server PR: 9883
File: spec/CloudCodeLogger.spec.js:410-412
Timestamp: 2025-10-16T19:27:05.311Z
Learning: In spec/CloudCodeLogger.spec.js, the test "should log cloud function triggers using the silent log level" (around lines 383-420) is known to be flaky and requires the extra `await new Promise(resolve => setTimeout(resolve, 100))` timeout after awaiting `afterSavePromise` for reliability, even though it may appear redundant.

Applied to files:

  • src/GraphQL/loaders/configQueries.js
📚 Learning: 2025-09-21T15:43:32.265Z
Learnt from: mtrezza
Repo: parse-community/parse-server PR: 9858
File: src/GraphQL/ParseGraphQLServer.js:176-178
Timestamp: 2025-09-21T15:43:32.265Z
Learning: The GraphQL playground feature in ParseGraphQLServer.js (applyPlayground method) is intended for development environments only, which is why it includes the master key in client-side headers.

Applied to files:

  • src/GraphQL/loaders/configQueries.js
  • src/GraphQL/loaders/configMutations.js
  • spec/ParseGraphQLServer.spec.js
📚 Learning: 2025-12-02T06:55:53.788Z
Learnt from: mtrezza
Repo: parse-community/parse-server PR: 0
File: :0-0
Timestamp: 2025-12-02T06:55:53.788Z
Learning: When reviewing Parse Server PRs that add or modify Parse Server options, always verify that changes are properly reflected in three files: src/Options/index.js (where changes originate), src/Options/Definitions.js, and src/Options/docs.js. The correct workflow is: make changes in index.js first, then run `npm run definitions` to automatically replicate the changes to Definitions.js and docs.js.

Applied to files:

  • spec/ParseGraphQLServer.spec.js
📚 Learning: 2025-04-30T19:31:35.344Z
Learnt from: RahulLanjewar93
Repo: parse-community/parse-server PR: 9744
File: spec/ParseLiveQuery.spec.js:0-0
Timestamp: 2025-04-30T19:31:35.344Z
Learning: In the Parse Server codebase, the functions in QueryTools.js are typically tested through end-to-end behavior tests rather than direct unit tests, even though the functions are exported from the module.

Applied to files:

  • spec/ParseGraphQLServer.spec.js
📚 Learning: 2025-11-08T13:46:04.940Z
Learnt from: mtrezza
Repo: parse-community/parse-server PR: 0
File: :0-0
Timestamp: 2025-11-08T13:46:04.940Z
Learning: For new Parse Server options, verify that the option is documented in src/Options/index.js and that npm run definitions has been executed to reflect changes in src/Options/docs.js and src/Options/Definitions.js. README.md documentation is a bonus but not required for new options.

Applied to files:

  • spec/ParseGraphQLServer.spec.js
📚 Learning: 2025-11-08T13:46:04.940Z
Learnt from: mtrezza
Repo: parse-community/parse-server PR: 0
File: :0-0
Timestamp: 2025-11-08T13:46:04.940Z
Learning: When reviewing Parse Server PRs that add new features, always check whether the feature is documented in the README.md file, though for new Parse Server options this is optional rather than required.

Applied to files:

  • spec/ParseGraphQLServer.spec.js
📚 Learning: 2025-11-17T15:02:48.786Z
Learnt from: mtrezza
Repo: parse-community/parse-server PR: 0
File: :0-0
Timestamp: 2025-11-17T15:02:48.786Z
Learning: For Parse Server PRs, always suggest an Angular commit convention PR title that would make a meaningful changelog entry for developers. Update the PR title suggestion on every commit. The format should be: type(scope): description. Common types include feat, fix, perf, refactor, docs, test, chore. The scope should identify the subsystem (e.g., graphql, rest, push, security). The description should be action-oriented and clearly convey the change's impact to developers.

Applied to files:

  • spec/ParseGraphQLServer.spec.js
🧬 Code graph analysis (1)
src/GraphQL/loaders/configQueries.js (3)
src/GraphQL/loaders/configMutations.js (2)
  • context (10-10)
  • load (32-73)
src/GraphQL/loaders/defaultGraphQLMutations.js (1)
  • load (7-13)
src/GraphQL/loaders/defaultGraphQLQueries.js (1)
  • load (6-21)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (15)
  • GitHub Check: Node 18
  • GitHub Check: PostgreSQL 17, PostGIS 3.5
  • GitHub Check: Node 22
  • GitHub Check: MongoDB 8, ReplicaSet
  • GitHub Check: Node 20
  • GitHub Check: MongoDB 7, ReplicaSet
  • GitHub Check: PostgreSQL 18, PostGIS 3.6
  • GitHub Check: Redis Cache
  • GitHub Check: MongoDB 6, ReplicaSet
  • GitHub Check: PostgreSQL 15, PostGIS 3.5
  • GitHub Check: PostgreSQL 16, PostGIS 3.5
  • GitHub Check: PostgreSQL 15, PostGIS 3.3
  • GitHub Check: PostgreSQL 15, PostGIS 3.4
  • GitHub Check: Docker Build
  • GitHub Check: Benchmarks
🔇 Additional comments (2)
src/GraphQL/loaders/configQueries.js (1)

5-59: cloudConfig resolver and type wiring look solid

Master-key enforcement, GlobalConfig lookup, null-safe handling for missing params, and the ConfigValue GraphQL type registration all look correct and consistent with the surrounding GraphQL loader patterns. No functional issues spotted here.

src/GraphQL/loaders/configMutations.js (1)

32-73: UpdateCloudConfig mutation wiring and access control look correct

The mutation definition, input / output field types, registration via addGraphQLType / addGraphQLMutation, and master-key enforcement in updateCloudConfig are all coherent and in line with existing GraphQL loaders. Error handling via parseGraphQLSchema.handleError around the awaited mutation payload is also correctly set up.

Copy link
Member

@mtrezza mtrezza left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

@mtrezza mtrezza changed the title feat: Add graphql to parse config feat: Add GraphQL query cloudConfig and mutation updateCloudConfig to retrieve and update Cloud Config Dec 3, 2025
@mtrezza mtrezza changed the title feat: Add GraphQL query cloudConfig and mutation updateCloudConfig to retrieve and update Cloud Config feat: Add GraphQL query cloudConfig to retrieve and mutation updateCloudConfig to update Cloud Config Dec 3, 2025
@mtrezza mtrezza merged commit 3ca85cd into parse-community:alpha Dec 3, 2025
24 of 28 checks passed
parseplatformorg pushed a commit that referenced this pull request Dec 3, 2025
# [8.6.0-alpha.1](8.5.0...8.6.0-alpha.1) (2025-12-03)

### Features

* Add GraphQL query `cloudConfig` to retrieve and mutation `updateCloudConfig` to update Cloud Config ([#9947](#9947)) ([3ca85cd](3ca85cd))
@parseplatformorg
Copy link
Contributor

🎉 This change has been released in version 8.6.0-alpha.1

@parseplatformorg parseplatformorg added the state:released-alpha Released as alpha version label Dec 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state:released-alpha Released as alpha version

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Parse Config GraphQL mutations and queries

3 participants