add business owner assignment

This commit is contained in:
2026-05-11 15:30:04 +03:30
parent d8f71efdd5
commit 8056503078
4 changed files with 60 additions and 2 deletions
@@ -17,6 +17,7 @@ import { Roles } from '../auth/decorators/roles.decorator';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { RolesGuard } from '../auth/guards/roles.guard';
import { BusinessesService } from './businesses.service';
import { AssignBusinessOwnerDto } from './dto/assign-business-owner.dto';
import { CreateBusinessDto } from './dto/create-business.dto';
import { UpdateBusinessDto } from './dto/update-business.dto';
@@ -50,6 +51,16 @@ export class BusinessesController {
return this.service.create(payload);
}
@Post(':id/assign-owner')
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles(UserRole.ADMIN)
assignOwner(
@Param('id') id: string,
@Body() payload: AssignBusinessOwnerDto,
): Promise<BusinessEntity> {
return this.service.assignOwner(id, payload);
}
@Patch(':id')
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles(UserRole.ADMIN, UserRole.BUSINESS_OWNER)
+2 -1
View File
@@ -2,13 +2,14 @@ import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { BusinessCategoryEntity } from '../../entities/business-category.entity';
import { BusinessEntity } from '../../entities/business.entity';
import { UserEntity } from '../../entities/user.entity';
import { AuthModule } from '../auth/auth.module';
import { BusinessesController } from './businesses.controller';
import { BusinessesService } from './businesses.service';
@Module({
imports: [
TypeOrmModule.forFeature([BusinessEntity, BusinessCategoryEntity]),
TypeOrmModule.forFeature([BusinessEntity, BusinessCategoryEntity, UserEntity]),
AuthModule,
],
controllers: [BusinessesController],
+43 -1
View File
@@ -1,4 +1,5 @@
import {
BadRequestException,
ConflictException,
ForbiddenException,
Injectable,
@@ -8,8 +9,9 @@ import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { BusinessCategoryEntity } from '../../entities/business-category.entity';
import { BusinessEntity } from '../../entities/business.entity';
import { UserRole } from '../../entities/user.entity';
import { UserEntity, UserRole } from '../../entities/user.entity';
import { AuthUser } from '../auth/auth.types';
import { AssignBusinessOwnerDto } from './dto/assign-business-owner.dto';
import { CreateBusinessDto } from './dto/create-business.dto';
import { UpdateBusinessDto } from './dto/update-business.dto';
@@ -25,6 +27,8 @@ export class BusinessesService {
private readonly repo: Repository<BusinessEntity>,
@InjectRepository(BusinessCategoryEntity)
private readonly categoryRepo: Repository<BusinessCategoryEntity>,
@InjectRepository(UserEntity)
private readonly userRepo: Repository<UserEntity>,
) {}
async findAll(filters: FindAllFilters): Promise<BusinessEntity[]> {
@@ -113,6 +117,36 @@ export class BusinessesService {
}
}
async assignOwner(
id: string,
dto: AssignBusinessOwnerDto,
): Promise<BusinessEntity> {
const business = await this.findOne(id);
const mobile = this.normalizeMobile(dto.mobile);
let user = await this.userRepo.findOne({ where: { mobile } });
if (!user) {
user = this.userRepo.create({
mobile,
fullName: dto.fullName ?? null,
role: UserRole.BUSINESS_OWNER,
isActive: true,
});
} else {
if (user.role !== UserRole.ADMIN) {
user.role = UserRole.BUSINESS_OWNER;
}
if (dto.fullName !== undefined) {
user.fullName = dto.fullName;
}
user.isActive = true;
}
const savedUser = await this.userRepo.save(user);
business.ownerId = savedUser.id;
return this.repo.save(business);
}
private async ensureCategoryExists(categoryId: string): Promise<void> {
const category = await this.categoryRepo.findOne({ where: { id: categoryId } });
if (!category) {
@@ -120,6 +154,14 @@ export class BusinessesService {
}
}
private normalizeMobile(mobile: string): string {
const normalized = String(mobile ?? '').trim();
if (!/^(\+?\d{10,15}|09\d{9})$/.test(normalized)) {
throw new BadRequestException('Invalid mobile number');
}
return normalized;
}
private assertCanUpdateBusiness(
business: BusinessEntity,
payload: UpdateBusinessDto,
@@ -0,0 +1,4 @@
export class AssignBusinessOwnerDto {
mobile!: string;
fullName?: string | null;
}