Signup and admin-created accounts notify platform managers, and an ended plan sends one SMS instead of repeating for old expirations. Co-authored-by: Cursor <cursoragent@cursor.com>
44 lines
1.3 KiB
TypeScript
44 lines
1.3 KiB
TypeScript
import { Injectable, Logger } from '@nestjs/common';
|
|
import { Cron } from '@nestjs/schedule';
|
|
import { PrismaService } from '../prisma/prisma.service';
|
|
import { PlatformAdminAlertService } from './platform-admin-alert.service';
|
|
|
|
@Injectable()
|
|
export class BillingExpiryService {
|
|
private readonly logger = new Logger(BillingExpiryService.name);
|
|
|
|
constructor(
|
|
private readonly prisma: PrismaService,
|
|
private readonly alerts: PlatformAdminAlertService,
|
|
) {}
|
|
|
|
@Cron('15 * * * *', { timeZone: 'Asia/Tehran' })
|
|
async handleHourly(): Promise<void> {
|
|
await this.notifyEnded();
|
|
}
|
|
|
|
async notifyEnded(): Promise<number> {
|
|
const rows = await this.prisma.billingAccount.findMany({
|
|
where: {
|
|
expiryNotifiedAt: null,
|
|
planCode: { not: 'lifetime' },
|
|
status: { not: 'suspended' },
|
|
expiresAt: { lte: new Date() },
|
|
},
|
|
select: { id: true },
|
|
take: 100,
|
|
});
|
|
for (const row of rows) {
|
|
try {
|
|
await this.alerts.notifySubscriptionEnded(row.id);
|
|
} catch (error) {
|
|
this.logger.warn(
|
|
`expiry notify failed ${row.id}: ${error instanceof Error ? error.message : 'unknown'}`,
|
|
);
|
|
}
|
|
}
|
|
if (rows.length) this.logger.log(`subscription expiry checked: ${rows.length}`);
|
|
return rows.length;
|
|
}
|
|
}
|