Two Paths: Public Proxy vs Server-Side Ingest
Before writing any code, decide which path your operation belongs to:
| Public Proxy | Server-Side Ingest | |
|---|---|---|
| Caller | Frontend (browser) via executeGithubGraphql | Server only, called from lib/github/fetch-graphql.ts |
| Allowlist required | Yes — USER_GITHUB_GRAPHQL_OPERATIONS | No — bypasses the allowlist entirely |
| Query source | OPERATION_QUERY_FALLBACKS (client query text is ignored) | lib/github/queries/ files |
| Security | Only listed operations allowed; no introspection | Unrestricted; only runs on the server |
Use the public proxy for data the frontend needs directly. Use server-side ingest for leaderboard pipeline queries.
Adding a Public Proxy Operation
All changes are in lib/github/operations/registry.ts.
Step 1 — Add the operation name to the allowlist
export const USER_GITHUB_GRAPHQL_OPERATIONS = [
// ...existing operations...
'MyNewOperation', // <-- add here
] as const;The operationName sent by the client must exactly match this string. Any name not in this array returns 403.
Step 2 — Write the GraphQL query string
Write the query as a template literal or string constant. The client’s own query text is discarded — the server uses only what you define here.
const MY_NEW_OPERATION_QUERY = `
query MyNewOperation($org: String!) {
organization(login: $org) {
name
description
}
}
`;Step 3 — Add the query to OPERATION_QUERY_FALLBACKS
export const OPERATION_QUERY_FALLBACKS: Record<string, string> = {
// ...existing entries...
MyNewOperation: MY_NEW_OPERATION_QUERY,
};The key must exactly match the operation name in the allowlist.
Step 4 — Create the frontend query hook
Create hooks/queries/useMyNewOperationQuery.ts:
import { useQuery } from '@tanstack/react-query';
import { queryKeys } from '@/hooks/query-keys';
export function useMyNewOperationQuery(org: string) {
return useQuery({
queryKey: queryKeys.myNewOperation(org),
queryFn: async () => {
// call executeGithubGraphql with operationName: 'MyNewOperation'
},
});
}Step 5 — Add the query key
In hooks/query-keys.ts, add a key for the new operation:
myNewOperation: (org: string) => ['myNewOperation', org] as const,Adding a Server-Side Ingest Query
Server-side ingest queries do not go through the allowlist. They are called directly from lib/github/fetch-graphql.ts (or a new ingest function you write).
- Add the query string to
lib/github/queries/as a new file, e.g.lib/github/queries/my-ingest-query.ts. - Call it from
fetch-graphql.tsor from a new function you add to the ingest pipeline. - Wire it into
lib/leaderboard/ingest.tsviarunIngest()if it needs to run as part of the standard ingest phase.
Do not add server-side ingest queries to USER_GITHUB_GRAPHQL_OPERATIONS or OPERATION_QUERY_FALLBACKS — that allowlist is only for the public proxy.