import { Injectable } from '@nestjs/common'; import { InjectModel } from '@nestjs/mongoose'; import { NotificationsRepository } from '@task-stream/api/tracker/application'; import { NotificationReadModel, NotificationSettingsReadModel, } from '@task-stream/api/tracker/domain'; import { Model } from 'mongoose'; import { fromDoc, NotificationDoc, NotificationSettingsDoc, ReadModels, } from './read-model.schemas'; @Injectable() export class MongoNotificationsRepository extends NotificationsRepository { constructor( @InjectModel(ReadModels.Notification) private readonly notifications: Model, @InjectModel(ReadModels.NotificationSettings) private readonly settingsDocs: Model, ) { super(); } async insert({ id, ...rest }: NotificationReadModel): Promise { const result = await this.notifications.updateOne( { id }, { $setOnInsert: rest }, { upsert: true }, ); return result.upsertedCount > 0; } async findForUser( userId: string, options: { unreadOnly: boolean; limit: number }, ): Promise { const docs = await this.notifications .find({ userId, ...(options.unreadOnly ? { readAt: null } : {}) }) .sort({ createdAt: -1 }) .limit(options.limit) .lean(); return docs.map((doc) => fromDoc(doc) as NotificationReadModel); } countUnread(userId: string): Promise { return this.notifications.countDocuments({ userId, readAt: null }); } async markRead(userId: string, ids: string[] | null): Promise { await this.notifications.updateMany( { userId, readAt: null, ...(ids ? { id: { $in: ids } } : {}) }, { $set: { readAt: new Date().toISOString() } }, ); } async settings(userId: string): Promise { const doc = await this.settingsDocs .findOne({ id: userId }) .lean(); return { userId, email: doc?.email ?? false }; } async saveSettings(settings: NotificationSettingsReadModel): Promise { await this.settingsDocs.updateOne( { id: settings.userId }, { $set: { email: settings.email } }, { upsert: true }, ); } }