import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { EntityManager, IsNull, Repository } from 'typeorm'; import { NotificationEntity } from '../entities/notification.entity'; import type { NotificationStatusFilter } from '../dto/notification.dto'; @Injectable() export class NotificationsRepository { constructor( @InjectRepository(NotificationEntity) private readonly repo: Repository, ) {} listForUser( userId: string, status: NotificationStatusFilter, page: number, pageSize: number, ): Promise<[NotificationEntity[], number]> { const qb = this.repo .createQueryBuilder('notification') .where('notification.userId = :userId', { userId }) .andWhere('notification.deletedAt IS NULL'); if (status === 'read') { qb.andWhere('notification.readAt IS NOT NULL'); } if (status === 'unread') { qb.andWhere('notification.readAt IS NULL'); } return qb .orderBy('notification.createdAt', 'DESC') .skip((page - 1) * pageSize) .take(pageSize) .getManyAndCount(); } countUnreadForUser(userId: string): Promise { return this.repo.count({ where: { userId, readAt: IsNull(), deletedAt: IsNull() }, }); } findActiveForUser( id: string, userId: string, ): Promise { return this.repo.findOne({ where: { id, userId, deletedAt: IsNull() } }); } save( notification: NotificationEntity, manager?: EntityManager, ): Promise { return (manager?.getRepository(NotificationEntity) ?? this.repo).save( notification, ); } saveMany( notifications: NotificationEntity[], manager?: EntityManager, ): Promise { return (manager?.getRepository(NotificationEntity) ?? this.repo).save( notifications, ); } async markAllAsRead(userId: string, readAt = new Date()): Promise { const result = await this.repo.update( { userId, readAt: IsNull(), deletedAt: IsNull() }, { readAt }, ); return result.affected ?? 0; } async softDelete(notification: NotificationEntity): Promise { await this.repo.softRemove(notification); } }