Fix workspace cache flush versioned metadata (#23121)

## Problem

`WorkspaceCacheStorageService.flushVersionedMetadata` never deleted
several of the keys it was supposed to flush:

- When called without a `metadataVersion` (the dev seeder path), it
built keys ending in `:*` and passed them to `cacheStorageService.del`.
`del` is an exact-key delete with no glob support, so this branch
deleted nothing at all.
- `setGraphQLTypeDefs` and `setGraphQLUsedScalarNames` can write
applicationId-suffixed keys
(`{key}:{workspaceId}:{metadataVersion}:{applicationId}`), which the
flush loop never matched. On workspace deletion these SDL and scalar
entries survived in Redis until the 1-week TTL expired.
- The `MetadataVersion` key is stored without a version suffix
(`metadata:workspace-metadata-version:{workspaceId}`), but the flush
loop appended `:{metadataVersion}` to every key, so it never matched
either.

## Fix

`flushVersionedMetadata` now targets the key shapes that are actually
written:

- The `MetadataVersion` key is deleted by its exact, unversioned shape.
- With a known `metadataVersion`, each versioned key gets an exact `del`
on `{key}:{workspaceId}:{metadataVersion}` plus a `flushByPattern` on
`{key}:{workspaceId}:{metadataVersion}:*` to catch
applicationId-suffixed entries. The pattern requires the trailing colon
so flushing version 1 cannot match version 12.
- Without a `metadataVersion`, each versioned key is flushed with
`flushByPattern` on `{key}:{workspaceId}:*`.

`flushByPattern` is Redis-only, which is safe here: the cache module
factory hardcodes the Redis store, and `flushGraphQLOperation` in the
same service already relies on it.

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/23121?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
This commit is contained in:
Weiko
2026-07-22 01:28:19 +02:00
committed by GitHub
parent c503d4c4aa
commit 984944e9bc
@@ -173,18 +173,28 @@ export class WorkspaceCacheStorageService {
workspaceId: string,
metadataVersion?: number,
): Promise<void> {
const metadataVersionSuffix = isDefined(metadataVersion)
? `${metadataVersion}`
: '*';
const { MetadataVersion, ...versionedCacheKeys } =
METADATA_VERSIONED_WORKSPACE_CACHE_KEY;
await Promise.all(
Object.values(METADATA_VERSIONED_WORKSPACE_CACHE_KEY).map(
async (key) =>
await this.cacheStorageService.del(
`${key}:${workspaceId}:${metadataVersionSuffix}`,
),
await Promise.all([
this.cacheStorageService.del(`${MetadataVersion}:${workspaceId}`),
...Object.values(versionedCacheKeys).flatMap((key) =>
isDefined(metadataVersion)
? [
this.cacheStorageService.del(
`${key}:${workspaceId}:${metadataVersion}`,
),
this.cacheStorageService.flushByPattern(
`${key}:${workspaceId}:${metadataVersion}:*`,
),
]
: [
this.cacheStorageService.flushByPattern(
`${key}:${workspaceId}:*`,
),
],
),
);
]);
}
async flush(workspaceId: string, metadataVersion?: number): Promise<void> {