import { Injectable, NotFoundException } from '@nestjs/common'; import { TenantPrismaService } from '../prisma/tenant-prisma.service'; import * as bcrypt from 'bcrypt'; @Injectable() export class UsersService { constructor(private readonly tenantDb: TenantPrismaService) {} async findAll(query: { search?: string; tenantId?: string; page?: number; limit?: number }) { const { search, tenantId, page = 1, limit = 20 } = query; const skip = (page - 1) * limit; const where: any = { deletedAt: null }; if (search) { where.OR = [ { firstName: { contains: search, mode: 'insensitive' } }, { lastName: { contains: search, mode: 'insensitive' } }, { email: { contains: search, mode: 'insensitive' } }, ]; } if (tenantId) where.tenantId = tenantId; const [items, total] = await Promise.all([ this.tenantDb.user.findMany({ where, orderBy: { createdAt: 'desc' }, skip, take: limit, select: { id: true, email: true, firstName: true, lastName: true, isActive: true, createdAt: true, tenant: { select: { id: true, name: true, slug: true } }, roles: { select: { role: true } }, tenantRoles: { include: { tenantRole: { select: { name: true, slug: true } } } }, }, }), this.tenantDb.user.count({ where }), ]); return { items, total, page, limit, totalPages: Math.ceil(total / limit) }; } async findOne(id: string) { const user = await this.tenantDb.user.findUnique({ where: { id, deletedAt: null }, select: { id: true, email: true, firstName: true, lastName: true, isActive: true, createdAt: true, updatedAt: true, tenant: { select: { id: true, name: true, slug: true } }, roles: { select: { role: true } }, tenantRoles: { include: { tenantRole: { select: { name: true, slug: true } } } }, }, }); if (!user) throw new NotFoundException('User not found'); return user; } async update(id: string, dto: { isActive?: boolean; firstName?: string; lastName?: string }) { const user = await this.tenantDb.user.findUnique({ where: { id, deletedAt: null } }); if (!user) throw new NotFoundException('User not found'); return this.tenantDb.user.update({ where: { id }, data: { ...(dto.isActive !== undefined && { isActive: dto.isActive }), ...(dto.firstName && { firstName: dto.firstName }), ...(dto.lastName && { lastName: dto.lastName }), }, }); } async resetPassword(id: string, newPassword: string) { const user = await this.tenantDb.user.findUnique({ where: { id, deletedAt: null } }); if (!user) throw new NotFoundException('User not found'); const hashed = await bcrypt.hash(newPassword, 12); return this.tenantDb.user.update({ where: { id }, data: { password: hashed }, }); } }