first (part 3: src directory)
Deploy Iddaai Backend / build-and-deploy (push) Successful in 33s

This commit is contained in:
2026-04-16 15:12:27 +03:00
parent 2f0b85a0c7
commit 182f4aae16
125 changed files with 22552 additions and 0 deletions
+122
View File
@@ -0,0 +1,122 @@
import { Injectable, Logger } from '@nestjs/common';
import { Cron } from '@nestjs/schedule';
import { PrismaService } from '../database/prisma.service';
@Injectable()
export class LimitResetterTask {
private readonly logger = new Logger(LimitResetterTask.name);
constructor(private readonly prisma: PrismaService) {}
private shouldSkipInHistoricalMode(jobName: string): boolean {
if (process.env.FEEDER_MODE === 'historical') {
this.logger.debug(`Skipping ${jobName} in historical feeder mode`);
return true;
}
return false;
}
/**
* Reset usage limits daily at 03:00 (Europe/Istanbul)
*/
@Cron('0 3 * * *', { timeZone: 'Europe/Istanbul' })
async resetUsageLimits() {
if (this.shouldSkipInHistoricalMode('resetUsageLimits')) return;
this.logger.log('Starting daily usage limit reset job...');
try {
const today = new Date();
today.setHours(0, 0, 0, 0);
// Reset all limits that were last reset before today
const result = await this.prisma.usageLimit.updateMany({
where: {
lastResetDate: { lt: today },
},
data: {
analysisCount: 0,
couponCount: 0,
lastResetDate: today,
},
});
if (result.count > 0) {
this.logger.log(
`Usage limits for ${result.count} users have been reset`,
);
} else {
this.logger.log('No user limits needed resetting');
}
} catch (error: any) {
this.logger.error(`Limit reset job failed: ${error.message}`);
}
}
/**
* Clean up old predictions (older than 30 days)
*/
@Cron('0 4 * * *', { timeZone: 'Europe/Istanbul' })
async cleanupOldData() {
if (this.shouldSkipInHistoricalMode('cleanupOldData')) return;
this.logger.log('Starting data cleanup job...');
try {
const thirtyDaysAgo = new Date();
thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);
// Delete old AI prediction logs
const deletedLogs = await this.prisma.aiPredictionsLog.deleteMany({
where: {
createdAt: { lt: thirtyDaysAgo },
},
});
// Delete old live matches (finished more than 1 day ago)
// Historical data is already persisted in the 'matches' table
const oneDayAgo = new Date();
oneDayAgo.setDate(oneDayAgo.getDate() - 1);
const deletedLiveMatches = await this.prisma.liveMatch.deleteMany({
where: {
state: 'Finished',
updatedAt: { lt: oneDayAgo },
},
});
this.logger.log(
`Cleanup complete: ${deletedLogs.count} old logs, ${deletedLiveMatches.count} old live matches`,
);
} catch (error: any) {
this.logger.error(`Cleanup job failed: ${error.message}`);
}
}
/**
* Reset subscription status for expired users
*/
@Cron('0 0 * * *', { timeZone: 'Europe/Istanbul' })
async checkSubscriptions() {
if (this.shouldSkipInHistoricalMode('checkSubscriptions')) return;
this.logger.log('Checking expired subscriptions...');
try {
const now = new Date();
const result = await this.prisma.user.updateMany({
where: {
subscriptionStatus: 'active',
subscriptionExpiresAt: { lt: now },
},
data: {
subscriptionStatus: 'expired',
},
});
if (result.count > 0) {
this.logger.log(`${result.count} subscriptions marked as expired`);
}
} catch (error: any) {
this.logger.error(`Subscription check failed: ${error.message}`);
}
}
}