import { Injectable } from '@nestjs/common'; import { InjectModel } from '@nestjs/mongoose'; import { UserRegistry } from '@task-stream/api/identity/application'; import { User, UserFactory } from '@task-stream/api/identity/domain'; import { Model } from 'mongoose'; import { UserDocument } from './user.schema'; @Injectable() export class MongoUserRegistry extends UserRegistry { constructor( @InjectModel(UserDocument.name) private readonly users: Model, private readonly factory: UserFactory, ) { super(); } async upsert(user: User): Promise { await this.users.updateOne( { id: user.id }, { $set: { name: user.name, email: user.email, isActive: user.isActive } }, { upsert: true }, ); } async findById(id: string): Promise { const doc = await this.users.findOne({ id }).lean(); return doc ? this.toUser(doc) : null; } async findByIds(ids: string[]): Promise { if (ids.length === 0) return []; const docs = await this.users.find({ id: { $in: ids } }).lean(); return docs.map((d) => this.toUser(d)); } async search(term: string, limit: number): Promise { const pattern = new RegExp( term.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'i', ); const docs = await this.users .find(term ? { $or: [{ name: pattern }, { email: pattern }] } : {}) .sort({ name: 1 }) .limit(limit) .lean(); return docs.map((d) => this.toUser(d)); } private toUser(doc: UserDocument): User { return this.factory.restore({ id: doc.id, name: doc.name, email: doc.email, isActive: doc.isActive, }); } }