#### Direct Execution __typename & null backfill
##### __typename filling
The direct execution path now correctly derives __typename at every
level of the GraphQL response:
Connection types — CompanyConnection, CompanyEdge, Company, PageInfo
GroupBy types — TaskGroupByConnection (was incorrectly producing
TaskConnection)
Composite fields — Links, FullName, Currency, etc. handled by a
dedicated formatter (was inheriting the parent object's typename)
Previously, __typename was derived from the object's universal
identifier (a UUID), producing broken values like
20202020B3744779A56180086Cb2E17FConnection.
##### Null backfill
Selected fields missing from the resolver result are backfilled with
null, matching the standard Yoga schema behavior.
##### Integration test
A new test runs the same findMany query (with __typename at all
structural levels) through both paths — standard Yoga schema and direct
execution — and asserts identical output via toStrictEqual.
On top of [previous closed
PR](https://github.com/twentyhq/twenty/pull/18713) from @FelixMalfait :
- add a schema-creation-skipping optimization
- extract a handler-per-operation pattern,
- add runtime input validation guards,
- integrate with the standard workspace cache
- add gql-style error handling
To do/optimize/check :
- gql parsing and null backfilling
## Intro
This PR introduces a **direct GraphQL execution path** that bypasses
per-workspace GraphQL schema generation for workspace data queries (CRUD
on user-defined objects like companies, people, tasks, etc.).
## Why
In the current architecture, every workspace gets its own
dynamically-generated GraphQL schema reflecting its custom objects and
fields. This costs **~20MB of RAM per workspace per pod** and takes time
to build. For a multi-tenant SaaS with thousands of workspaces, this is
a significant infrastructure cost and a latency bottleneck (especially
on cold starts or cache misses).
The insight is that most workspace queries (`findMany`, `createOne`,
`updateOne`, etc.) don't actually *need* the full schema — they can be
routed directly to the existing Common API query runners by parsing the
GraphQL AST and matching resolver names against object metadata. The
schema is only truly needed for introspection, subscriptions, or queries
that mix core and workspace resolvers.
## How It Works
1. A Yoga `onRequest` plugin intercepts incoming GraphQL requests
2. It parses the query AST and checks if all top-level fields map to
generated workspace resolvers (e.g. `findManyCompanies`,
`createOnePerson`)
3. If yes, it executes them directly against the query runners, skipping
schema generation entirely
4. If the query contains introspection, subscriptions, or core-only
resolvers, it falls through to the normal path
5. Even for mixed queries it can't fully handle, it sets
`skipWorkspaceSchemaCreation` to avoid building the schema when
unnecessary
The whole thing is gated behind the
`IS_DIRECT_GRAPHQL_EXECUTION_ENABLED` feature flag for safe incremental
rollout.
**Net effect**: dramatically lower memory footprint and faster response
times for the vast majority of workspace API calls.
---------
Co-authored-by: Félix Malfait <felix@twenty.com>