Skip to content

feat: write-path cache invalidation with per-org namespacing#899

Open
martinshub-tech wants to merge 1 commit into
Disciplr-Org:mainfrom
martinshub-tech:feature/cache-invalidation-hooks
Open

feat: write-path cache invalidation with per-org namespacing#899
martinshub-tech wants to merge 1 commit into
Disciplr-Org:mainfrom
martinshub-tech:feature/cache-invalidation-hooks

Conversation

@martinshub-tech

Copy link
Copy Markdown
Contributor

this pr closes #837

Description

This PR introduces a robust cache‑aside invalidation mechanism for vault and analytics data, ensuring that cached entries are correctly evicted the moment underlying data changes. It also adds per‑organization namespacing to prevent cross‑tenant cache contamination.

Changes Made
Cache Library (src/lib/cache.ts)

Added optional orgId parameter to getOrSet, invalidate, and invalidatePrefix.
Implemented namespaced key format: org:${orgId}:${key}.
Switched to non‑blocking eviction using SCAN + UNLINK (Redis) for both single key and prefix invalidation.
Vault Store (src/services/vaultStore.ts)

Updated DB queries to include organization_id.
Implemented cache‑aside getVaultById with org‑scoped keys.
Added invalidation calls after every write path (create, update, cancel) to evict:
Specific vault cache (vault:${id}) and org‑lookup (vault:${id}:org).
All vault list caches for the organization (vaults: prefix).
Analytics caches (analytics: prefix) and global overall analytics.
Analytics Service (src/services/analytics.service.ts)

Added optional orgId to getOverallAnalytics and updateAnalyticsSummary.
Triggered appropriate invalidation on analytics refresh.
Validation & Types

Updated Zod schemas (src/services/vaultValidation.ts) and TypeScript interfaces (src/types/vaults.ts) to support optional orgId / organizationId.
Documentation

Added docs/cache.md detailing namespace conventions, helper functions, and invalidation triggers.
Tests

Created src/tests/cache.invalidation.test.ts covering:
Idempotent invalidate on missing keys.
Per‑organization isolation.
Prefix invalidation within a namespace.
Large‑scale prefix scans (thousands of keys) for performance and correctness.
All tests pass (npm test).

@drips-wave

drips-wave Bot commented Jun 27, 2026

Copy link
Copy Markdown

@martinshub-tech Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

Comment thread src/lib/cache.ts
}
} catch (error) {
console.warn(`Redis get failed for key ${key}:`, error);
console.warn(`Redis get failed for key ${cacheKey}:`, error);
Comment thread src/lib/cache.ts
await redisClient.set(cacheKey, JSON.stringify(entry), 'EX', ttlSeconds);
} catch (error) {
console.warn(`Redis set failed for key ${key}:`, error);
console.warn(`Redis set failed for key ${cacheKey}:`, error);
Comment thread src/lib/cache.ts
await redisClient.unlink(cacheKey);
} catch (error) {
console.warn(`Redis del failed for key ${key}:`, error);
console.warn(`Redis unlink failed for key ${cacheKey}:`, error);
@GBOYEE

GBOYEE commented Jun 28, 2026

Copy link
Copy Markdown

@GBOYEE has applied to work on this issue as part of the Stellar Wave Program's 6th wave.

Implement following existing patterns and conventions. Add tests, ensure CI passes, and document any new API surface.

ℹ️ Repo Maintainers: To accept this application, review their application or assign @GBOYEE to this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add targeted cache-invalidation hooks on vault and analytics writes in src/lib/cache.ts

3 participants