gcx/backend/services/auth-service/src/infrastructure/persistence/email-verification.reposito...

66 lines
1.8 KiB
TypeScript

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, MoreThan, IsNull } from 'typeorm';
import { EmailVerification, EmailVerificationType } from '../../domain/entities/email-verification.entity';
import { IEmailVerificationRepository } from '../../domain/repositories/email-verification.repository.interface';
@Injectable()
export class EmailVerificationRepository implements IEmailVerificationRepository {
constructor(
@InjectRepository(EmailVerification)
private readonly repo: Repository<EmailVerification>,
) {}
async create(data: {
email: string;
code: string;
type: EmailVerificationType;
expiresAt: Date;
}): Promise<EmailVerification> {
const entity = this.repo.create(data);
return this.repo.save(entity);
}
async findLatestValid(
email: string,
type: EmailVerificationType,
): Promise<EmailVerification | null> {
return this.repo.findOne({
where: {
email,
type,
expiresAt: MoreThan(new Date()),
verifiedAt: IsNull(),
},
order: { createdAt: 'DESC' },
});
}
async save(verification: EmailVerification): Promise<EmailVerification> {
return this.repo.save(verification);
}
async getDailySendCount(email: string): Promise<number> {
const today = new Date();
today.setHours(0, 0, 0, 0);
return this.repo.count({
where: {
email,
createdAt: MoreThan(today),
},
});
}
async deleteExpired(): Promise<number> {
const result = await this.repo
.createQueryBuilder()
.delete()
.where('expires_at < :now', { now: new Date() })
.andWhere('verified_at IS NOT NULL OR expires_at < :cutoff', {
cutoff: new Date(Date.now() - 24 * 60 * 60 * 1000),
})
.execute();
return result.affected || 0;
}
}