fix: concurrent stale race, Redis expire leak, missing invalidation, UI Suspense

- Fix integration data cache: set pending synchronously before creating
  fetch to prevent concurrent stale-revalidation from spawning duplicate
  upstream calls
- Redis cache handler: skip persisting entries with expire=0 (dynamic
  entries should not be stored in Redis)
- Add missing invalidation: user.changePassword, group.updateGroup,
  group.transferOwnership
- Move SearchEngineOptimization inside Suspense in root layout
- Add Suspense fallback loader to root layout
- Move searchParams resolution inside Suspense in login page
This commit is contained in:
Thomas Camlong committed 2026-08-07 20:53:36 +02:00
1 parent 38ac8f3075
commit fbb2eddd87
6 files changed
+30 -21

No files matched your search

@@ -113,12 +113,9 @@ export class RedisCacheHandler implements CacheHandler {
});
const ttlMs = entry.expire * 1000;
if (ttlMs <= 0) return; // Dynamic entries (expire: 0) should not be persisted
await this.redis.connect().catch(() => {});
if (ttlMs > 0) {
await this.redis.set(this.entryKey(cacheKey), serialized, "PX", ttlMs);
} else {
await this.redis.set(this.entryKey(cacheKey), serialized);
}
await this.redis.set(this.entryKey(cacheKey), serialized, "PX", ttlMs);
} catch {
// Fail open
} finally {