CognxSafeTrack
refactor: resolve critical tech debt in CRM broadcasts and usage tracking
d983a7d
import Redis from 'ioredis';
import { logger } from '../logger';
import { getCachedOrganization } from './organization';
export class UsageService {
/**
* Checks if an organization has exceeded its daily message limit.
* Increments the count if within limits.
*/
static async checkAndIncrement(organizationId: string, redis: Redis, amount: number = 1): Promise<{ allowed: boolean; current: number; limit: number }> {
const org = await getCachedOrganization(organizationId);
if (!org) return { allowed: false, current: 0, limit: 0 };
const limit = org.dailyMessageLimit || 250;
const today = new Date().toISOString().split('T')[0];
const key = `usage:${organizationId}:${today}`;
// Atomic increment by amount
const current = await redis.incrby(key, amount);
if (current <= amount) {
// Set expiry for 24h on first use of the day
await redis.expire(key, 86400);
}
if (current > limit) {
logger.warn(`[USAGE] Org ${organizationId} reached limit: ${current}/${limit}`);
return { allowed: false, current, limit };
}
return { allowed: true, current, limit };
}
static async getCurrentUsage(organizationId: string, redis: Redis): Promise<number> {
const today = new Date().toISOString().split('T')[0];
const key = `usage:${organizationId}:${today}`;
const val = await redis.get(key);
return val ? parseInt(val) : 0;
}
}