feat: add Redis caching to cospend API endpoints
All checks were successful
CI / update (push) Successful in 1m21s

Implement comprehensive caching for all cospend routes to improve performance:

Cache Implementation:
- Balance API: 30-minute TTL for user balances and global balances
- Debts API: 15-minute TTL for debt breakdown calculations
- Payments List: 10-minute TTL with pagination support
- Individual Payment: 30-minute TTL for payment details

Cache Invalidation:
- Created invalidateCospendCaches() helper function
- Invalidates user balances, debts, and payment lists on mutations
- Applied to payment create, update, and delete operations
- Applied to recurring payment execution (manual and cron)
This commit is contained in:
2026-01-13 19:45:09 +01:00
parent 041d415525
commit baa3f3e533
7 changed files with 163 additions and 29 deletions

View File

@@ -302,10 +302,44 @@ export async function invalidateRecipeCaches(): Promise<void> {
cache.delPattern('recipes:category:*'),
cache.delPattern('recipes:icon:*'),
]);
console.log('[Cache] Invalidated all recipe caches');
} catch (err) {
console.error('[Cache] Error invalidating recipe caches:', err);
}
}
/**
* Helper function to invalidate cospend caches for specific users and/or payments
* Call this after payment create/update/delete operations
* @param usernames - Array of usernames whose caches should be invalidated
* @param paymentId - Optional payment ID to invalidate specific payment cache
*/
export async function invalidateCospendCaches(usernames: string[], paymentId?: string): Promise<void> {
try {
const invalidations: Promise<any>[] = [];
// Invalidate balance and debts caches for all affected users
for (const username of usernames) {
invalidations.push(
cache.del(`cospend:balance:${username}`),
cache.del(`cospend:debts:${username}`)
);
}
// Invalidate global balance cache
invalidations.push(cache.del('cospend:balance:all'));
// Invalidate payment list caches (all pagination variants)
invalidations.push(cache.delPattern('cospend:payments:list:*'));
// If specific payment ID provided, invalidate its cache
if (paymentId) {
invalidations.push(cache.del(`cospend:payment:${paymentId}`));
}
await Promise.all(invalidations);
} catch (err) {
console.error('[Cache] Error invalidating cospend caches:', err);
}
}
export default cache;