Step 4: Enforce read-only mode for GraphQL mutations
Summary
Block GraphQL mutations that target namespaces in maintenance state. Rack middleware alone is insufficient for GraphQL because the namespace is embedded in the request body (all GraphQL requests are POST to /api/graphql).
POC approach: This will be part of a single POC MR (does not need to merge to master). Maintenance mode will be toggled via Rails console.
Dependencies
- Depends on: Step 1 (#591688) — state machine transitions
- Parallel with: Step 2 (#591689 (closed)) and Step 3 (#591690 (closed))
Context
Parent issue: #590009 (closed)
GraphQL mutations are all POST requests to a single endpoint, so the namespace-scoped middleware (Step 2) cannot determine the target namespace from the URL path alone. Enforcement must happen at the GraphQL layer.
Tasks
-
Investigate enforcement approaches:
-
Option A: Custom
GraphQL::Analysis::AST::Analyzerthat inspects mutation arguments for namespace/group/project references and checks maintenance state -
Option B: Override in
Mutations::BaseMutationto check namespace state before executing - Option C: Add a shared concern to resolvers/mutations that checks the namespace of the resolved object
-
Option A: Custom
- Implement chosen approach
- Ensure GraphQL queries (reads) still work — only mutations should be blocked
-
Return a structured GraphQL error with appropriate message and extensions (e.g.,
{ "extensions": { "code": "NAMESPACE_MAINTENANCE" } }) - Add specs covering: mutation blocking, query passthrough, nested namespace resolution
Key Files
app/graphql/mutations/base_mutation.rbapp/controllers/graphql_controller.rbapp/graphql/types/mutation_type.rb
Effort Estimate
Medium (2-3 days)
Edited by Chen Zhang