chore: improve monitoring for Race condition between cache invalidation of flat

**Monitoring improvement:** Added structured logging to `WorkspaceSchemaFactory` that records key diagnostic context on every schema build:
- Whether typeDefs were served from cache or freshly generated
- The `metadataVersion` used for the cache key
- The number of objects in `flatObjectMetadataMaps`

This log line fires on every `POST /graphql` request and provides the exact data needed to diagnose future cache desync issues. When a "defined in resolvers, but not in schema" error occurs, the preceding log entry will show `typeDefs=cached` with a metadata version that doesn't match the object count — immediately revealing the stale cache condition.

Added `Logger` from `@nestjs/common` (consistent with the pattern used in `WorkspaceResolverFactory` and other services in the codebase).
This commit is contained in:
Sonarly Claude Code
2026-03-06 22:57:04 +00:00
parent 46aad8813b
commit 35e6b13329
@@ -1,4 +1,4 @@
import { Injectable } from '@nestjs/common';
import { Injectable, Logger } from '@nestjs/common';
import { makeExecutableSchema } from '@graphql-tools/schema';
import { GraphQLSchema, printSchema } from 'graphql';
@@ -27,6 +27,8 @@ import { TWENTY_STANDARD_APPLICATION } from 'src/engine/workspace-manager/twenty
@Injectable()
export class WorkspaceSchemaFactory {
private readonly logger = new Logger(WorkspaceSchemaFactory.name);
constructor(
private readonly dataSourceService: DataSourceService,
private readonly scalarsExplorerService: ScalarsExplorerService,
@@ -146,7 +148,9 @@ export class WorkspaceSchemaFactory {
applicationId,
);
if (!typeDefs || !usedScalarNames) {
const typeDefsFromCache = isDefined(typeDefs) && isDefined(usedScalarNames);
if (!typeDefsFromCache) {
const autoGeneratedSchema =
await this.workspaceGraphQLSchemaGenerator.generateSchema({
flatObjectMetadataMaps,
@@ -172,6 +176,16 @@ export class WorkspaceSchemaFactory {
);
}
const objectCount = Object.keys(
flatObjectMetadataMaps.byUniversalIdentifier,
).length;
this.logger.log(
`Building schema for workspace ${workspace.id} ` +
`(metadataVersion=${metadataVersion}, objects=${objectCount}, ` +
`typeDefs=${typeDefsFromCache ? 'cached' : 'generated'})`,
);
const autoGeneratedResolvers = await this.workspaceResolverFactory.create(
flatObjectMetadataMaps,
flatFieldMetadataMaps,