module customers

This commit is contained in:
2026-06-28 20:08:27 +03:30
parent 043e80a139
commit 7a5b3f0bea
9 changed files with 253 additions and 1 deletions
+2
View File
@@ -1,6 +1,7 @@
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
import { CustomersModule } from './customers/customers.module';
import { SalonsModule } from './salons/salons.module';
import { UsersModule } from './users/users.module';
@@ -19,6 +20,7 @@ import { UsersModule } from './users/users.module';
}),
UsersModule,
SalonsModule,
CustomersModule,
],
controllers: [],
providers: [],
+46
View File
@@ -0,0 +1,46 @@
import {
Body,
Controller,
Delete,
Get,
Param,
ParseUUIDPipe,
Patch,
Post,
} from '@nestjs/common';
import { CustomersService } from './customers.service';
import { CreateCustomerDto } from './dto/create-customer.dto';
import { UpdateCustomerDto } from './dto/update-customer.dto';
@Controller('customers')
export class CustomersController {
constructor(private readonly customersService: CustomersService) {}
@Post()
create(@Body() createCustomerDto: CreateCustomerDto) {
return this.customersService.create(createCustomerDto);
}
@Get()
findAll() {
return this.customersService.findAll();
}
@Get(':id')
findOne(@Param('id', ParseUUIDPipe) id: string) {
return this.customersService.findOne(id);
}
@Patch(':id')
update(
@Param('id', ParseUUIDPipe) id: string,
@Body() updateCustomerDto: UpdateCustomerDto,
) {
return this.customersService.update(id, updateCustomerDto);
}
@Delete(':id')
remove(@Param('id', ParseUUIDPipe) id: string) {
return this.customersService.remove(id);
}
}
+14
View File
@@ -0,0 +1,14 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UsersModule } from '../users/users.module';
import { CustomersController } from './customers.controller';
import { CustomersService } from './customers.service';
import { Customer } from './entities/customer.entity';
@Module({
imports: [TypeOrmModule.forFeature([Customer]), UsersModule],
controllers: [CustomersController],
providers: [CustomersService],
exports: [CustomersService],
})
export class CustomersModule {}
+86
View File
@@ -0,0 +1,86 @@
import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { UserRole } from '../users/enums/user-role.enum';
import { UsersService } from '../users/users.service';
import { CreateCustomerDto } from './dto/create-customer.dto';
import { UpdateCustomerDto } from './dto/update-customer.dto';
import { Customer } from './entities/customer.entity';
@Injectable()
export class CustomersService {
constructor(
@InjectRepository(Customer)
private readonly customersRepository: Repository<Customer>,
private readonly usersService: UsersService,
) {}
async create(createCustomerDto: CreateCustomerDto): Promise<Customer> {
const user = await this.usersService.create({
firstName: createCustomerDto.firstName,
lastName: createCustomerDto.lastName,
mobile: createCustomerDto.mobile,
role: UserRole.CUSTOMER,
});
const customer = this.customersRepository.create({
userId: user.id,
dateOfBirth: createCustomerDto.dateOfBirth,
address: createCustomerDto.address,
});
const saved = await this.customersRepository.save(customer);
return this.findOne(saved.id);
}
findAll(): Promise<Customer[]> {
return this.customersRepository.find({ relations: { user: true } });
}
async findOne(id: string): Promise<Customer> {
const customer = await this.customersRepository.findOne({
where: { id },
relations: { user: true },
});
if (!customer) {
throw new NotFoundException(`Customer #${id} not found`);
}
return customer;
}
async update(
id: string,
updateCustomerDto: UpdateCustomerDto,
): Promise<Customer> {
const customer = await this.findOne(id);
const { firstName, lastName, mobile, dateOfBirth, address } =
updateCustomerDto;
if (
firstName !== undefined ||
lastName !== undefined ||
mobile !== undefined
) {
await this.usersService.update(customer.userId, {
firstName,
lastName,
mobile,
});
}
if (dateOfBirth !== undefined) {
customer.dateOfBirth = dateOfBirth;
}
if (address !== undefined) {
customer.address = address;
}
await this.customersRepository.save(customer);
return this.findOne(customer.id);
}
async remove(id: string): Promise<void> {
const customer = await this.findOne(id);
await this.usersService.remove(customer.userId);
}
}
+30
View File
@@ -0,0 +1,30 @@
import {
IsDateString,
IsNotEmpty,
IsString,
Length,
Matches,
} from 'class-validator';
export class CreateCustomerDto {
@IsString()
@Length(1, 100)
@IsNotEmpty()
firstName: string;
@IsString()
@Length(1, 100)
@IsNotEmpty()
lastName: string;
@Matches(/^09\d{9}$/)
mobile: string;
@IsDateString()
dateOfBirth: string;
@IsString()
@Length(1, 500)
@IsNotEmpty()
address: string;
}
+32
View File
@@ -0,0 +1,32 @@
import {
IsDateString,
IsOptional,
IsString,
Length,
Matches,
} from 'class-validator';
export class UpdateCustomerDto {
@IsOptional()
@IsString()
@Length(1, 100)
firstName?: string;
@IsOptional()
@IsString()
@Length(1, 100)
lastName?: string;
@IsOptional()
@Matches(/^09\d{9}$/)
mobile?: string;
@IsOptional()
@IsDateString()
dateOfBirth?: string;
@IsOptional()
@IsString()
@Length(1, 500)
address?: string;
}
+35
View File
@@ -0,0 +1,35 @@
import {
Column,
CreateDateColumn,
Entity,
JoinColumn,
OneToOne,
PrimaryGeneratedColumn,
UpdateDateColumn,
} from 'typeorm';
import { User } from '../../users/entities/user.entity';
@Entity('customers')
export class Customer {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column({ unique: true })
userId: string;
@OneToOne(() => User, { onDelete: 'CASCADE' })
@JoinColumn({ name: 'userId' })
user: User;
@Column({ type: 'date' })
dateOfBirth: string;
@Column({ length: 500 })
address: string;
@CreateDateColumn()
createdAt: Date;
@UpdateDateColumn()
updatedAt: Date;
}
+5 -1
View File
@@ -1,4 +1,4 @@
import { IsOptional, IsString, Length } from 'class-validator';
import { IsOptional, IsString, Length, Matches } from 'class-validator';
export class UpdateUserDto {
@IsOptional()
@@ -10,4 +10,8 @@ export class UpdateUserDto {
@IsString()
@Length(1, 100)
lastName?: string;
@IsOptional()
@Matches(/^09\d{9}$/)
mobile?: string;
}
+3
View File
@@ -36,6 +36,9 @@ export class UsersService {
async update(id: string, updateUserDto: UpdateUserDto): Promise<User> {
const user = await this.findOne(id);
if (updateUserDto.mobile) {
await this.ensureMobileIsUnique(updateUserDto.mobile, id);
}
Object.assign(user, updateUserDto);
return this.usersRepository.save(user);
}