import { BadRequestException, ForbiddenException, Injectable, NotFoundException, } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { SalonPolicy } from '../authorization/policies/salon.policy'; import { AuthUser } from '../auth/interfaces/auth-user.interface'; import { UserRole } from '../users/enums/user-role.enum'; import { UsersService } from '../users/users.service'; import { CreateSalonDto } from './dto/create-salon.dto'; import { UpdateSalonDto } from './dto/update-salon.dto'; import { Salon } from './entities/salon.entity'; @Injectable() export class SalonsService { constructor( @InjectRepository(Salon) private readonly salonsRepository: Repository, private readonly usersService: UsersService, private readonly salonPolicy: SalonPolicy, ) {} async create(createSalonDto: CreateSalonDto, user: AuthUser): Promise { const ownerId = this.resolveOwnerId(createSalonDto, user); await this.ensureOwnerIsSalonOwner(ownerId); const salon = this.salonsRepository.create({ ...createSalonDto, ownerId, }); return this.salonsRepository.save(salon); } findAll(user?: AuthUser): Promise { if (user?.role === UserRole.SALON) { return this.salonsRepository.find({ where: { ownerId: user.id }, relations: { owner: true }, }); } return this.salonsRepository.find({ relations: { owner: true } }); } async findOne(id: string): Promise { const salon = await this.salonsRepository.findOne({ where: { id }, relations: { owner: true }, }); if (!salon) { throw new NotFoundException(`Salon #${id} not found`); } return salon; } async update( id: string, updateSalonDto: UpdateSalonDto, user: AuthUser, ): Promise { const salon = await this.findOne(id); if (!this.salonPolicy.canUpdate(user, salon)) { throw new ForbiddenException(); } Object.assign(salon, updateSalonDto); return this.salonsRepository.save(salon); } async remove(id: string, user: AuthUser): Promise { const salon = await this.findOne(id); if (!this.salonPolicy.canDelete(user, salon)) { throw new ForbiddenException(); } await this.salonsRepository.remove(salon); } private resolveOwnerId( createSalonDto: CreateSalonDto, user: AuthUser, ): string { if (user.role === UserRole.SALON) { return user.id; } if (!createSalonDto.ownerId) { throw new BadRequestException('ownerId is required for admin'); } return createSalonDto.ownerId; } private async ensureOwnerIsSalonOwner(ownerId: string): Promise { const owner = await this.usersService.findOne(ownerId); if (owner.role !== UserRole.SALON) { throw new BadRequestException('Owner must have salon-owner role'); } } }