From 4433e0a9d0a3c4a8e85fcb2111f6b34a2481b7d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89mile=20R=C3=A9?= Date: Fri, 19 Jun 2026 14:57:28 +0200 Subject: [PATCH] Restore GraphQL schema merge for Relay query text MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit relay-compiler requires a single schema file: a directory is rejected and schemaExtensions marks fields as client-only, so it emitted text: null and the console posted query: null, getting a 400 on every operation. Restore the merge step (contrib/merge-graphql-schema.sh, the RELAY_SCHEMAS make rules, and the gitignore entry) and point each relay.config.json project back at the merged schema.graphql. The IDE graphql-config removal and npm-script cleanup are unrelated and stay. Signed-off-by: Émile Ré --- .gitignore | 1 + GNUmakefile | 18 +++++++++++++- contrib/claude/make.md | 2 +- contrib/merge-graphql-schema.sh | 44 +++++++++++++++++++++++++++++++++ relay.config.json | 9 +++---- 5 files changed, 66 insertions(+), 8 deletions(-) create mode 100755 contrib/merge-graphql-schema.sh diff --git a/.gitignore b/.gitignore index 5d48a7026..ba170da14 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ compose/keycloak/probo-realm.json # Generated files (codegen) __generated__/ pkg/server/api/*/v1/types/types.go +pkg/server/api/*/v1/schema.graphql cfg/dev_local.yaml cfg/dev.yaml .env diff --git a/GNUmakefile b/GNUmakefile index 384064f7a..4238b274b 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -282,14 +282,30 @@ $(PROBO_AGENT_BIN): @probo/emails: $(NPM) --workspace $@ run build +RELAY_SCHEMAS = \ + pkg/server/api/connect/v1/schema.graphql \ + pkg/server/api/console/v1/schema.graphql \ + pkg/server/api/trust/v1/schema.graphql + .PHONY: relay -relay: +relay: $(RELAY_SCHEMAS) $(NPM) run relay +MERGE_GRAPHQL = contrib/merge-graphql-schema.sh + CONNECT_GQL = $(wildcard pkg/server/api/connect/v1/graphql/*.graphql) CONSOLE_GQL = $(wildcard pkg/server/api/console/v1/graphql/*.graphql) TRUST_GQL = $(wildcard pkg/server/api/trust/v1/graphql/*.graphql) +pkg/server/api/connect/v1/schema.graphql: pkg/server/api/connect/v1/graphql $(CONNECT_GQL) + $(MERGE_GRAPHQL) $@ pkg/server/api/connect/v1/graphql + +pkg/server/api/console/v1/schema.graphql: pkg/server/api/console/v1/graphql $(CONSOLE_GQL) + $(MERGE_GRAPHQL) $@ pkg/server/api/console/v1/graphql + +pkg/server/api/trust/v1/schema.graphql: pkg/server/api/trust/v1/graphql $(TRUST_GQL) + $(MERGE_GRAPHQL) $@ pkg/server/api/trust/v1/graphql + .PHONY: @probo/console @probo/console: NODE_ENV=production @probo/console: relay diff --git a/contrib/claude/make.md b/contrib/claude/make.md index 7ed252bc2..0c9e556aa 100644 --- a/contrib/claude/make.md +++ b/contrib/claude/make.md @@ -41,7 +41,7 @@ Individual codegen is driven by `go generate`: - `go generate ./pkg/server/api/mcp/v1` — MCP (mcpgen) - `go generate ./pkg/llm` — LLM model registry from OpenRouter (`make genmodels`) -`make relay` runs `relay-compiler`, which reads the split `.graphql` schema files directly (via each project's `schema` + `schemaExtensions` in `relay.config.json`) and keeps generated artifacts in sync (stale ones are removed automatically). +`make relay` merges each service's split `.graphql` schema files into a single `schema.graphql` (via `contrib/merge-graphql-schema.sh`) and runs `relay-compiler`. The merge is required: relay-compiler's `schema` must be a single file, and `schemaExtensions` would mark the fields as client-only (emitting `text: null`), so the split files cannot be fed to Relay directly. ## Coverage diff --git a/contrib/merge-graphql-schema.sh b/contrib/merge-graphql-schema.sh new file mode 100755 index 000000000..7b82fb5c9 --- /dev/null +++ b/contrib/merge-graphql-schema.sh @@ -0,0 +1,44 @@ +#!/bin/sh +# Merge split GraphQL schema files into a single file for Relay. +# Strips "type Mutation" and "extend type Mutation { ... }" blocks, +# then appends a single "type Mutation { ... }" with all collected fields. +# +# Usage: merge-graphql-schema.sh + +set -eu + +output="$1" +graphql_dir="$2" +base="$graphql_dir/base.graphql" + +mutation_fields=$(mktemp) +schema_body=$(mktemp) +trap 'rm -f "$mutation_fields" "$schema_body"' EXIT + +process_file() { + awk -v mf="$mutation_fields" ' + /^type Mutation$/ { next } + /^(extend )?type Mutation \{/ { skip=1; depth=1; next } + skip { + if (/\{/) depth++ + if (/\}/) { depth--; if (depth==0) { skip=0; next } } + if (skip) { print >> mf; next } + } + { print } + ' "$1" +} + +{ + process_file "$base" + for f in "$graphql_dir"/*.graphql; do + [ "$f" = "$base" ] && continue + process_file "$f" + done +} > "$schema_body" + +{ + cat "$schema_body" + printf '\ntype Mutation {\n' + cat "$mutation_fields" + printf '}\n' +} > "$output" diff --git a/relay.config.json b/relay.config.json index b88f66675..96788f962 100644 --- a/relay.config.json +++ b/relay.config.json @@ -10,8 +10,7 @@ }, "projects": { "core": { - "schema": "pkg/server/api/console/v1/graphql/base.graphql", - "schemaExtensions": ["pkg/server/api/console/v1/graphql"], + "schema": "pkg/server/api/console/v1/schema.graphql", "language": "typescript", "noFutureProofEnums": true, "output": "apps/console/src/__generated__/core", @@ -26,8 +25,7 @@ } }, "iam": { - "schema": "pkg/server/api/connect/v1/graphql/base.graphql", - "schemaExtensions": ["pkg/server/api/connect/v1/graphql"], + "schema": "pkg/server/api/connect/v1/schema.graphql", "language": "typescript", "noFutureProofEnums": true, "output": "apps/console/src/__generated__/iam", @@ -42,8 +40,7 @@ } }, "trust": { - "schema": "pkg/server/api/trust/v1/graphql/base.graphql", - "schemaExtensions": ["pkg/server/api/trust/v1/graphql"], + "schema": "pkg/server/api/trust/v1/schema.graphql", "language": "typescript", "noFutureProofEnums": true, "customScalarTypes": {