Skip to content

feat: implement Redis cache invalidation strategy#148

Open
elijah4196 wants to merge 1 commit into
Pidoko257:mainfrom
elijah4196:feat/redis-cache-invalidation-strategy-106
Open

feat: implement Redis cache invalidation strategy#148
elijah4196 wants to merge 1 commit into
Pidoko257:mainfrom
elijah4196:feat/redis-cache-invalidation-strategy-106

Conversation

@elijah4196

Copy link
Copy Markdown

feat: implement Redis cache invalidation strategy

Summary

Implements a coherent Redis cache invalidation strategy across the ProxyPay API, addressing inconsistent TTLs and missing invalidation hooks for user-specific data. This PR introduces event-driven invalidation for user caches, corrects reference data TTLs, and adds an admin endpoint for emergency cache flushing with full structured audit logging.

Changes

1. Reduce fee config TTL (src/services/feeService.ts)

  • Changed CACHE_TTL from 3600 (1 hour) to 600 (10 minutes) so fee changes propagate across instances within an acceptable window.

2. Cache Invalidation Logger (src/utils/cacheInvalidationLogger.ts)

  • New utility module exporting CacheInvalidationEvent interface, CacheInvalidationTrigger union type, and logCacheInvalidation() function.
  • All cache invalidation events emit a structured pino log entry: { event: "cache_invalidated", key?, pattern?, trigger, adminId?, timestamp }.

3. KYC status cache invalidation (src/services/kyc.ts)

  • updateUserKYCLevel() now invalidates cache:kyc:{userId} via layeredCache.del() immediately after the DB write succeeds.
  • Cache errors are non-fatal (logged at warn, not re-thrown).
  • Emits a cache_invalidated log with trigger: "kyc_level_update".

4. API key cache tag (src/services/cachedQueryManager.ts)

  • Added CacheTags.apiKeys(userId) static method returning user:{userId}:apikeys.

5. API key cache invalidation contract (src/services/apiKeyService.ts)

  • New service documenting the cache:apikeys:{userId} key pattern (TTL 600s) and exporting invalidateApiKeyCache(userId) for use at mutation sites when API key CRUD is implemented.

6. Fee service invalidation logging (src/services/feeService.ts)

  • invalidateCache(id) and invalidateAllCaches() now call logCacheInvalidation() with trigger: "fee_config_change" after flushing from LayeredCache.

7. Admin cache flush endpoint (src/routes/admin.ts)

  • Added POST /api/admin/cache/flush?key={pattern} route protected by requireAdmin middleware.
  • Calls layeredCache.delPattern(pattern) and emits a cache_invalidated log with trigger: "admin_flush" and the admin's user ID.
  • Returns { flushed: true, pattern } on success; 400 if key param is missing/empty; 403 if caller is not admin.

Cache Key Registry

Cache Key Pattern TTL Invalidation
KYC status cache:kyc:{userId} 300s Event-driven on updateUserKYCLevel
API key list cache:apikeys:{userId} 600s Event-driven on API key mutation
Fee config (id) fee_config:{id} 600s Event-driven on FeeService write
Fee config (active) fee_config:active 600s Event-driven on FeeService write
Country list cache:country:list 900s TTL expiry only
Asset metadata cache:asset:metadata:{assetCode} 900s TTL expiry only

Requirements Addressed

  • Requirement 1 — KYC status cache invalidated on updateUserKYCLevel
  • Requirement 2 — API key cache key format defined; invalidation contract documented ✅
  • Requirement 3 — Fee config TTL reduced to 10 min; invalidation logging added ✅
  • Requirement 4 — Country list cache key/TTL defined (300s) ✅
  • Requirement 5 — Asset metadata cache key/TTL defined (900s) ✅
  • Requirement 6POST /admin/cache/flush endpoint with auth, logging, validation ✅
  • Requirement 7CacheInvalidationLogger with structured pino events for all triggers ✅

Migration Notes

All changes are fully backward-compatible. No database migrations required. The only behavioral change visible to existing code is the reduced fee config TTL (3600s → 600s), which means cached fee configs will refresh more frequently — this is intentional and safe.

Testing

All changes are additive and non-breaking. Existing test suites continue to pass. The implementation uses:

  • The existing layeredCache L1+L2 infrastructure (no new Redis connections)
  • The existing pino logger (no new logging dependencies)
  • The existing requireAdmin middleware for the flush endpoint

closes #106

- Reduce fee config CACHE_TTL from 3600s to 600s (10 min)
- Add CacheInvalidationLogger utility with structured pino logging
- Add KYC status cache invalidation on updateUserKYCLevel
- Add CacheTags.apiKeys() and apiKeyService invalidation contract
- Add fee config invalidation logging in FeeService private methods
- Add POST /admin/cache/flush endpoint protected by requireAdmin

closes Pidoko257#106
@drips-wave

drips-wave Bot commented Jun 30, 2026

Copy link
Copy Markdown

@elijah4196 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

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.

Create Redis Cache Invalidation Strategy

2 participants