Files
twenty/packages
Sonarly Claude Code 5adfc5f7b5 Slow metadata query: SELECT DISTINCT on wide fieldMetadata rows takes 2+ seconds
https://sonarly.com/issue/3801?type=bug

The POST /metadata GraphQL endpoint takes ~4.1 seconds due to a nestjs-query-generated SELECT DISTINCT query on the fieldMetadata table that takes 2+ seconds, caused by expensive DISTINCT deduplication across wide rows with multiple jsonb columns.

Fix: The fix replaces the slow `fields(paging: { first: 1000 }) { edges { node { ... } } }` CursorConnection query with `fields: fieldsList { ... }` using a GraphQL field alias in the REST metadata query builder.

**What changed:**

```typescript file=packages/twenty-server/src/engine/api/rest/metadata/query-builder/utils/fetch-metadata-fields.utils.ts lines=70-76
      const fieldsPart = selector?.fields
        ? `
        fields: fieldsList {
          ${fieldsSelection}
        }
      `
        : '';
```

**Why this works:**

1. **Eliminates the slow `SELECT DISTINCT`**: The `fields(paging: { first: 1000 })` CursorConnection was routed through nestjs-query's auto-generated resolver which unconditionally adds `SELECT DISTINCT` across all columns of `fieldMetadata` — including 4 large jsonb columns — taking ~2045ms. Switching to `fieldsList` uses the existing `@ResolveField` on `ObjectMetadataResolver` (lines 189–213) that loads fields via a DataLoader backed by a multi-level cache (local memory → Redis → database).

2. **Field alias preserves the response key**: Using `fields: fieldsList` as a GraphQL field alias means the response still contains the key `fields` (not `fieldsList`), so no consumer-facing breaking change occurs. The `cleanGraphQLResponse` utility handles the new shape correctly: a plain array is not an object (`isObject` returns false for arrays), so it is assigned directly — producing the same `fields: [{...}]` output as before.

3. **Single-file, 5-line change**: Entirely within the REST metadata query builder utility; no framework code, shared utilities, or other callers are modified.
2026-03-04 20:31:18 +00:00
..
2026-03-04 17:32:14 +01:00