Files
grow-api/src/salons/salons.service.ts
T
2026-06-28 20:32:52 +03:30

102 lines
2.9 KiB
TypeScript

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<Salon>,
private readonly usersService: UsersService,
private readonly salonPolicy: SalonPolicy,
) {}
async create(createSalonDto: CreateSalonDto, user: AuthUser): Promise<Salon> {
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<Salon[]> {
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<Salon> {
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<Salon> {
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<void> {
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<void> {
const owner = await this.usersService.findOne(ownerId);
if (owner.role !== UserRole.SALON) {
throw new BadRequestException('Owner must have salon-owner role');
}
}
}