chore: add danak services and admin login
This commit is contained in:
@@ -9,6 +9,7 @@ import { rateLimitConfig } from "./configs/rateLimit.config";
|
||||
import { databaseConfigs } from "./configs/typeorm.config";
|
||||
import { HTTPLogger } from "./core/middlewares/logger.middleware";
|
||||
import { AuthModule } from "./modules/auth/auth.module";
|
||||
import { DanakServicesModule } from "./modules/danak-services/danak-services.module";
|
||||
import { TicketsModule } from "./modules/tickets/tickets.module";
|
||||
import { UsersModule } from "./modules/users/users.module";
|
||||
|
||||
@@ -21,6 +22,7 @@ import { UsersModule } from "./modules/users/users.module";
|
||||
UsersModule,
|
||||
TicketsModule,
|
||||
AuthModule,
|
||||
DanakServicesModule,
|
||||
],
|
||||
controllers: [],
|
||||
providers: [],
|
||||
|
||||
@@ -49,6 +49,7 @@ export const enum AuthMessage {
|
||||
NATIONAL_NOT_EMPTY = "کد ملی نمیتواند خالی باشد",
|
||||
OTP_ALREADY_SENT = "کد یکبار مصرف قبلا ارسال شده است",
|
||||
TOO_MANY_REQUESTS = "تعداد درخواست های شما بیش از حد مجاز است",
|
||||
NOT_ADMIN = "شما دسترسی به بخش ادمین ندارید",
|
||||
}
|
||||
|
||||
export const enum UserMessage {
|
||||
@@ -66,4 +67,16 @@ export const enum CommonMessage {
|
||||
THIS_FILED_IS_REQUIRED = "این فیلد الزامی است",
|
||||
VALID_FOR_CHOOSE = "معتبر برای انتخاب",
|
||||
UPDATE_SUCCESS = "با موفقیت به روز رسانی شد",
|
||||
CREATED = "با موفقیت ایجاد شد",
|
||||
}
|
||||
|
||||
export const enum CategoryMessage {
|
||||
TITLE_REQUIRED = "نام دسته بندی مورد نیاز است",
|
||||
TITLE_STRING = "نام دسته بندی باید یک رشته باشد",
|
||||
TITLE_LENGTH = "نام دسته بندی باید بین ۳ تا ۵۰ کاراکتر باشد",
|
||||
ICON_REQUIRED = "آیکون دسته بندی مورد نیاز است",
|
||||
ICON_SHOULD_BE_URL = "آیکون باید یک آدرس یو آر ال باشد",
|
||||
PARENT_ID_REQUIRED = "شناسه والد دسته بندی مورد نیاز است",
|
||||
PARENT_ID_SHOULD_BE_UUID = "شناسه والد باید یک یو یو آی دی باشد",
|
||||
TITLE_EXIST = "دسته بندی با این نام قبلا ثبت شده است",
|
||||
}
|
||||
|
||||
@@ -57,6 +57,22 @@ export class AuthController {
|
||||
return this.authService.loginWithPassword(loginPasswordDto);
|
||||
}
|
||||
|
||||
//***************************** */
|
||||
@ApiOperation({ summary: "login with password ==> admin" })
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@Post("login/password/admin")
|
||||
adminLoginWithPassword(@Body() loginPasswordDto: LoginPasswordDTO) {
|
||||
return this.authService.adminLoginWithPassword(loginPasswordDto);
|
||||
}
|
||||
|
||||
@ApiOperation({ summary: "verify otp for login" })
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@Post("otp/verify/admin")
|
||||
adminVerifyOtp(@Body() verifyOtpDto: VerifyOtpDto) {
|
||||
return this.authService.adminVerifyLoginOtp(verifyOtpDto);
|
||||
}
|
||||
//***************************** */
|
||||
|
||||
// @Post("forgot-password")
|
||||
// async forgotPassword(@Body() forgotPasswordDto: ForgotPasswordDto) {
|
||||
// return this.authService.forgotPassword(forgotPasswordDto);
|
||||
|
||||
@@ -2,6 +2,7 @@ import { BadRequestException, Injectable, Logger } from "@nestjs/common";
|
||||
|
||||
import { TokensService } from "./tokens.service";
|
||||
import { AuthMessage, UserMessage } from "../../../common/enums/message.enum";
|
||||
import { RoleEnum } from "../../users/enums/role.enum";
|
||||
import { UsersService } from "../../users/providers/users.service";
|
||||
import { OTPService } from "../../utils/providers/otp.service";
|
||||
import { PasswordService } from "../../utils/providers/password.service";
|
||||
@@ -64,11 +65,7 @@ export class AuthService {
|
||||
async loginWithPassword(loginDto: LoginPasswordDTO) {
|
||||
const { email, password } = loginDto;
|
||||
|
||||
const user = await this.usersService.findOneWithEmail(email);
|
||||
if (!user) throw new BadRequestException(AuthMessage.INVALID_PASSWORD);
|
||||
|
||||
const passCompare = await this.passwordService.comparePassword(password, user.password);
|
||||
if (!passCompare) throw new BadRequestException(AuthMessage.INVALID_PASSWORD);
|
||||
const user = await this.checkUserLoginCredentialWithEmail(email, password);
|
||||
|
||||
const tokens = this.tokensService.generateAccessAndRefreshToken({ sub: user.id, role: user.role.name });
|
||||
|
||||
@@ -79,6 +76,21 @@ export class AuthService {
|
||||
}
|
||||
//****************** */
|
||||
|
||||
async adminLoginWithPassword(loginDto: LoginPasswordDTO) {
|
||||
const { email, password } = loginDto;
|
||||
|
||||
const user = await this.checkUserLoginCredentialWithEmail(email, password);
|
||||
|
||||
if (user.role.name !== RoleEnum.ADMIN) throw new BadRequestException(AuthMessage.NOT_ADMIN);
|
||||
const tokens = this.tokensService.generateAccessAndRefreshToken({ sub: user.id, role: user.role.name });
|
||||
|
||||
return {
|
||||
message: AuthMessage.PASSWORD_LOGIN_SUCCESS,
|
||||
...tokens,
|
||||
};
|
||||
}
|
||||
|
||||
//****************** */
|
||||
async checkUserExist(checkUserExistDto: CheckUserExistDto) {
|
||||
const user = await this.usersService.findOneWithEmail(checkUserExistDto.email);
|
||||
if (!user) throw new BadRequestException(UserMessage.USER_NOT_FOUND);
|
||||
@@ -86,7 +98,6 @@ export class AuthService {
|
||||
}
|
||||
|
||||
//****************** */
|
||||
|
||||
async requestLoginOtp(requestOtpDto: RequestOtpDto) {
|
||||
const { phone } = requestOtpDto;
|
||||
const user = await this.usersService.findOneWithPhone(phone);
|
||||
@@ -114,13 +125,22 @@ export class AuthService {
|
||||
async verifyLoginOtp(verifyOtpDto: VerifyOtpDto) {
|
||||
const { code, phone } = verifyOtpDto;
|
||||
|
||||
const isValid = await this.otpService.verifyOtp(phone, code, "LOGIN");
|
||||
if (!isValid) throw new BadRequestException(AuthMessage.INVALID_OTP);
|
||||
const user = await this.checkUserLoginCredentialWithPhone(phone, code);
|
||||
|
||||
await this.otpService.delOtpFormCache(phone, "LOGIN");
|
||||
const tokens = this.tokensService.generateAccessAndRefreshToken({ sub: user.id, role: user.role.name });
|
||||
return {
|
||||
message: AuthMessage.LOGIN_SUCCESS,
|
||||
...tokens,
|
||||
};
|
||||
}
|
||||
|
||||
const user = await this.usersService.findOneWithPhone(phone);
|
||||
if (!user) throw new BadRequestException(UserMessage.USER_NOT_FOUND);
|
||||
//****************** */
|
||||
async adminVerifyLoginOtp(verifyOtpDto: VerifyOtpDto) {
|
||||
const { code, phone } = verifyOtpDto;
|
||||
|
||||
const user = await this.checkUserLoginCredentialWithPhone(phone, code);
|
||||
|
||||
if (user.role.name !== RoleEnum.ADMIN) throw new BadRequestException(AuthMessage.NOT_ADMIN);
|
||||
|
||||
const tokens = this.tokensService.generateAccessAndRefreshToken({ sub: user.id, role: user.role.name });
|
||||
return {
|
||||
@@ -129,4 +149,29 @@ export class AuthService {
|
||||
};
|
||||
}
|
||||
//****************** */
|
||||
//****************** */
|
||||
|
||||
private async checkUserLoginCredentialWithEmail(email: string, password: string) {
|
||||
const user = await this.usersService.findOneWithEmail(email);
|
||||
if (!user) throw new BadRequestException(AuthMessage.INVALID_PASSWORD);
|
||||
|
||||
const passCompare = await this.passwordService.comparePassword(password, user.password);
|
||||
if (!passCompare) throw new BadRequestException(AuthMessage.INVALID_PASSWORD);
|
||||
|
||||
return user;
|
||||
}
|
||||
//****************** */
|
||||
//****************** */
|
||||
|
||||
private async checkUserLoginCredentialWithPhone(phone: string, otpCode: string) {
|
||||
const isValid = await this.otpService.verifyOtp(phone, otpCode, "LOGIN");
|
||||
if (!isValid) throw new BadRequestException(AuthMessage.INVALID_OTP);
|
||||
|
||||
await this.otpService.delOtpFormCache(phone, "LOGIN");
|
||||
|
||||
const user = await this.usersService.findOneWithPhone(phone);
|
||||
if (!user) throw new BadRequestException(UserMessage.USER_NOT_FOUND);
|
||||
|
||||
return user;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger";
|
||||
import { IsNotEmpty, IsOptional, IsString, IsUUID, IsUrl, Length } from "class-validator";
|
||||
|
||||
import { CategoryMessage } from "../../../common/enums/message.enum";
|
||||
|
||||
export class CreateCategoryDto {
|
||||
@IsNotEmpty({ message: CategoryMessage.TITLE_REQUIRED })
|
||||
@IsString({ message: CategoryMessage.TITLE_STRING })
|
||||
@Length(3, 50, { message: CategoryMessage.TITLE_LENGTH })
|
||||
@ApiProperty({ description: "Category title", example: "business" })
|
||||
title: string;
|
||||
|
||||
@IsNotEmpty({ message: CategoryMessage.ICON_REQUIRED })
|
||||
@IsUrl({ protocols: ["http", "https"], require_protocol: true }, { message: CategoryMessage.ICON_SHOULD_BE_URL })
|
||||
@ApiProperty({ description: "Category icon", example: "https://example.com/icon.png" })
|
||||
icon: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsNotEmpty({ message: CategoryMessage.PARENT_ID_REQUIRED })
|
||||
@IsUUID("4", { message: CategoryMessage.PARENT_ID_SHOULD_BE_UUID })
|
||||
@ApiPropertyOptional({ description: "Parent category id", example: "8b1e8b1e-8b1e-8b1e-8b1e-8b1e8b1e8b1e" })
|
||||
parentId?: string;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Body, Controller, Post } from "@nestjs/common";
|
||||
import { ApiOperation, ApiTags } from "@nestjs/swagger";
|
||||
|
||||
import { CreateCategoryDto } from "./DTO/create-category.dto";
|
||||
import { DanakServicesService } from "./providers/danak-services.service";
|
||||
import { AuthGuards } from "../../common/decorators/auth-guard.decorator";
|
||||
|
||||
@Controller("services")
|
||||
@ApiTags("Danak-Services")
|
||||
export class DanakServicesController {
|
||||
constructor(private readonly danakServicesService: DanakServicesService) {}
|
||||
@AuthGuards()
|
||||
@ApiOperation({ summary: "Create a new service category" })
|
||||
@Post("category")
|
||||
createCategory(@Body() createDto: CreateCategoryDto) {
|
||||
return this.danakServicesService.createCategory(createDto);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import { Module } from "@nestjs/common";
|
||||
import { TypeOrmModule } from "@nestjs/typeorm";
|
||||
|
||||
import { DanakServicesController } from "./danak-services.controller";
|
||||
import { DanakServiceCategory } from "./entities/danak-service-category.entity";
|
||||
import { DanakServiceImage } from "./entities/danak-service-image.entity";
|
||||
import { DanakService } from "./entities/danak-service.entity";
|
||||
import { DanakServicesService } from "./providers/danak-services.service";
|
||||
import { DanakServicesCategoryRepository } from "./repositories/danak-services-category.repository";
|
||||
import { DanakServicesImageRepository } from "./repositories/danak-services-image.repository";
|
||||
import { DanakServicesRepository } from "./repositories/danak-services.repository";
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([DanakService, DanakServiceImage, DanakServiceCategory])],
|
||||
providers: [DanakServicesService, DanakServicesRepository, DanakServicesCategoryRepository, DanakServicesImageRepository],
|
||||
controllers: [DanakServicesController],
|
||||
exports: [DanakServicesService, TypeOrmModule],
|
||||
})
|
||||
export class DanakServicesModule {}
|
||||
@@ -0,0 +1,26 @@
|
||||
import { Column, Entity, JoinColumn, ManyToOne, OneToMany } from "typeorm";
|
||||
|
||||
import { DanakService } from "./danak-service.entity";
|
||||
import { BaseEntity } from "../../../common/entities/base.entity";
|
||||
|
||||
@Entity()
|
||||
export class DanakServiceCategory extends BaseEntity {
|
||||
@Column({ type: "varchar", length: 100, nullable: false, unique: true })
|
||||
title: string;
|
||||
|
||||
@Column({ type: "varchar", length: 150, nullable: false })
|
||||
icon: string;
|
||||
|
||||
@ManyToOne(() => DanakServiceCategory, (category) => category.children)
|
||||
@JoinColumn({ name: "parentId" })
|
||||
parent: DanakServiceCategory;
|
||||
|
||||
@OneToMany(() => DanakServiceCategory, (category) => category.parent)
|
||||
children: DanakServiceCategory[];
|
||||
|
||||
@Column({ nullable: true })
|
||||
parentId: string;
|
||||
|
||||
@OneToMany(() => DanakService, (danakService) => danakService.category)
|
||||
danakService: DanakService[];
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { Column, Entity, ManyToOne } from "typeorm";
|
||||
|
||||
import { DanakService } from "./danak-service.entity";
|
||||
import { BaseEntity } from "../../../common/entities/base.entity";
|
||||
|
||||
@Entity()
|
||||
export class DanakServiceImage extends BaseEntity {
|
||||
@Column({ type: "varchar", length: 255, nullable: false })
|
||||
imageUrl: string;
|
||||
|
||||
@ManyToOne(() => DanakService, (danakService) => danakService.images, { nullable: false, onDelete: "CASCADE" })
|
||||
danakService: DanakService;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
import { Column, Entity, ManyToOne, OneToMany } from "typeorm";
|
||||
|
||||
import { DanakServiceCategory } from "./danak-service-category.entity";
|
||||
import { DanakServiceImage } from "./danak-service-image.entity";
|
||||
import { BaseEntity } from "../../../common/entities/base.entity";
|
||||
import { ServiceStatus } from "../enums/service-status.enum";
|
||||
import { ServicesLanguage } from "../enums/services-language.enum";
|
||||
|
||||
@Entity()
|
||||
export class DanakService extends BaseEntity {
|
||||
@Column({ type: "varchar", length: 255, nullable: false })
|
||||
name: string;
|
||||
|
||||
@Column({ type: "text", nullable: false })
|
||||
description: string;
|
||||
|
||||
@Column({ type: "varchar", length: 255, nullable: false })
|
||||
author: string;
|
||||
|
||||
@Column({ type: "timestamp", nullable: false, default: () => "CURRENT_TIMESTAMP" })
|
||||
createDate: Date;
|
||||
|
||||
@Column({ type: "int", nullable: false, default: 0 })
|
||||
userCount: number;
|
||||
|
||||
@Column({ type: "enum", enum: ServicesLanguage, nullable: false })
|
||||
serviceLanguage: ServicesLanguage;
|
||||
|
||||
@Column({ type: "varchar", length: 150, nullable: false })
|
||||
softwareLanguage: string;
|
||||
|
||||
@Column({ type: "text", nullable: false })
|
||||
metaDescription: string;
|
||||
|
||||
@Column({ type: "enum", enum: ServiceStatus, nullable: false, default: ServiceStatus.IN_ACTIVE })
|
||||
status: ServiceStatus;
|
||||
|
||||
@Column({ type: "varchar", length: 255, nullable: false })
|
||||
link: string;
|
||||
|
||||
@Column({ type: "varchar", length: 255, nullable: false })
|
||||
icon: string;
|
||||
|
||||
@OneToMany(() => DanakServiceImage, (danakServiceImage) => danakServiceImage.danakService, { eager: true })
|
||||
images: DanakServiceImage[];
|
||||
|
||||
@ManyToOne(() => DanakServiceCategory, (danakServiceCategory) => danakServiceCategory.danakService, {
|
||||
nullable: false,
|
||||
onDelete: "RESTRICT",
|
||||
})
|
||||
category: DanakServiceCategory;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export enum ServiceStatus {
|
||||
ACTIVE = "ACTIVE",
|
||||
IN_ACTIVE = "IN_ACTIVE",
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export enum ServicesLanguage {
|
||||
ENGLISH = "en",
|
||||
GERMAN = "de",
|
||||
PERSIAN = "fa",
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import { BadRequestException, Injectable, Logger } from "@nestjs/common";
|
||||
|
||||
import { CategoryMessage, CommonMessage } from "../../../common/enums/message.enum";
|
||||
import { CreateCategoryDto } from "../DTO/create-category.dto";
|
||||
import { DanakServicesCategoryRepository } from "../repositories/danak-services-category.repository";
|
||||
|
||||
@Injectable()
|
||||
export class DanakServicesService {
|
||||
private readonly logger = new Logger(DanakServicesService.name);
|
||||
constructor(private readonly danakServicesCategoryRepository: DanakServicesCategoryRepository) {}
|
||||
/********** */
|
||||
async createCategory(createDto: CreateCategoryDto) {
|
||||
this.logger.log(`Creating a new category with title: ${createDto.title}`);
|
||||
const existCategory = await this.danakServicesCategoryRepository.findOneBy({ title: createDto.title });
|
||||
if (existCategory) throw new BadRequestException(CategoryMessage.TITLE_EXIST);
|
||||
const category = this.danakServicesCategoryRepository.create(createDto);
|
||||
await this.danakServicesCategoryRepository.save(category);
|
||||
return {
|
||||
message: CommonMessage.CREATED,
|
||||
category,
|
||||
};
|
||||
}
|
||||
/********** */
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { Injectable } from "@nestjs/common";
|
||||
import { InjectRepository } from "@nestjs/typeorm";
|
||||
import { Repository } from "typeorm";
|
||||
|
||||
import { DanakServiceCategory } from "../entities/danak-service-category.entity";
|
||||
|
||||
@Injectable()
|
||||
export class DanakServicesCategoryRepository extends Repository<DanakServiceCategory> {
|
||||
constructor(@InjectRepository(DanakServiceCategory) danakServicesCategoryRepository: Repository<DanakServiceCategory>) {
|
||||
super(danakServicesCategoryRepository.target, danakServicesCategoryRepository.manager, danakServicesCategoryRepository.queryRunner);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { Injectable } from "@nestjs/common";
|
||||
import { InjectRepository } from "@nestjs/typeorm";
|
||||
import { Repository } from "typeorm";
|
||||
|
||||
import { DanakServiceImage } from "../entities/danak-service-image.entity";
|
||||
|
||||
@Injectable()
|
||||
export class DanakServicesImageRepository extends Repository<DanakServiceImage> {
|
||||
constructor(@InjectRepository(DanakServiceImage) danakServicesImageRepository: Repository<DanakServiceImage>) {
|
||||
super(danakServicesImageRepository.target, danakServicesImageRepository.manager, danakServicesImageRepository.queryRunner);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { Injectable } from "@nestjs/common";
|
||||
import { InjectRepository } from "@nestjs/typeorm";
|
||||
import { Repository } from "typeorm";
|
||||
|
||||
import { DanakService } from "../entities/danak-service.entity";
|
||||
|
||||
@Injectable()
|
||||
export class DanakServicesRepository extends Repository<DanakService> {
|
||||
constructor(@InjectRepository(DanakService) danakServicesRepository: Repository<DanakService>) {
|
||||
super(danakServicesRepository.target, danakServicesRepository.manager, danakServicesRepository.queryRunner);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { Column, Entity, JoinColumn, ManyToOne } from "typeorm";
|
||||
import { BaseEntity } from "../../../common/entities/base.entity";
|
||||
import { Ticket } from "./ticket.entity";
|
||||
import { User } from "../../users/entities/user.entity";
|
||||
|
||||
@Entity()
|
||||
export class TicketMessage extends BaseEntity {
|
||||
@Column({ type: "text", nullable: false })
|
||||
content: string;
|
||||
|
||||
@Column({ type: "varchar", length: 150, nullable: true, default: null })
|
||||
attachmentUrl: string;
|
||||
|
||||
@JoinColumn()
|
||||
@ManyToOne(() => Ticket, (ticket) => ticket.messages, { onDelete: "CASCADE", nullable: false })
|
||||
ticket: Ticket;
|
||||
|
||||
@ManyToOne(() => User, (user) => user.ticketMessage, { onDelete: "SET NULL", nullable: true })
|
||||
@JoinColumn()
|
||||
author: User;
|
||||
}
|
||||
@@ -1,13 +1,17 @@
|
||||
import { Column, Entity, JoinColumn, ManyToOne } from "typeorm";
|
||||
import { Column, Entity, JoinColumn, ManyToOne, OneToMany } from "typeorm";
|
||||
|
||||
import { TicketCategory } from "./ticket-category.entity";
|
||||
import { BaseEntity } from "../../../common/entities/base.entity";
|
||||
import { User } from "../../users/entities/user.entity";
|
||||
import { TicketPriority } from "../enums/ticket-priority.enum";
|
||||
import { TicketStatus } from "../enums/ticket-status.enum";
|
||||
import { TicketMessage } from "./ticket-message.entity";
|
||||
|
||||
@Entity()
|
||||
export class Ticket extends BaseEntity {
|
||||
@Column({ type: "int", generated: "identity", insert: false })
|
||||
numericId: number;
|
||||
|
||||
@Column({ type: "varchar", length: 150, nullable: false })
|
||||
title: string;
|
||||
|
||||
@@ -33,4 +37,7 @@ export class Ticket extends BaseEntity {
|
||||
@JoinColumn()
|
||||
@ManyToOne(() => TicketCategory, (category) => category.tickets, { onDelete: "RESTRICT", nullable: false })
|
||||
category: TicketCategory;
|
||||
|
||||
@OneToMany(() => TicketMessage, (message) => message.ticket)
|
||||
messages: TicketMessage[];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import { InjectRepository } from "@nestjs/typeorm";
|
||||
import { Repository } from "typeorm";
|
||||
import { TicketCategory } from "../entities/ticket-category.entity";
|
||||
import { Injectable } from "@nestjs/common";
|
||||
|
||||
@Injectable()
|
||||
export class TicketCategoryRepository extends Repository<TicketCategory> {
|
||||
constructor(@InjectRepository(TicketCategory) ticketCategoryRepository: Repository<TicketCategory>) {
|
||||
super(ticketCategoryRepository.target, ticketCategoryRepository.manager, ticketCategoryRepository.queryRunner);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { InjectRepository } from "@nestjs/typeorm";
|
||||
import { Repository } from "typeorm";
|
||||
import { TicketMessage } from "../entities/ticket-message.entity";
|
||||
import { Injectable } from "@nestjs/common";
|
||||
|
||||
@Injectable()
|
||||
export class TicketMessagesRepository extends Repository<TicketMessage> {
|
||||
constructor(@InjectRepository(TicketMessage) ticketMessagesRepository: Repository<TicketMessage>) {
|
||||
super(ticketMessagesRepository.target, ticketMessagesRepository.manager, ticketMessagesRepository.queryRunner);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { Repository } from "typeorm";
|
||||
import { Ticket } from "../entities/ticket.entity";
|
||||
import { Injectable } from "@nestjs/common";
|
||||
import { InjectRepository } from "@nestjs/typeorm";
|
||||
|
||||
@Injectable()
|
||||
export class TicketsRepository extends Repository<Ticket> {
|
||||
constructor(@InjectRepository(Ticket) ticketsRepository: Repository<Ticket>) {
|
||||
super(ticketsRepository.target, ticketsRepository.manager, ticketsRepository.queryRunner);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,10 @@
|
||||
import { Controller } from "@nestjs/common";
|
||||
import { ApiTags } from "@nestjs/swagger";
|
||||
|
||||
// import { TicketsService } from "./providers/tickets.service";
|
||||
|
||||
@Controller("tickets")
|
||||
@ApiTags("users")
|
||||
export class TicketsController {}
|
||||
@ApiTags("Tickets")
|
||||
export class TicketsController {
|
||||
// constructor(private readonly ticketsService: TicketsService) {}
|
||||
}
|
||||
|
||||
@@ -4,11 +4,16 @@ import { TypeOrmModule } from "@nestjs/typeorm";
|
||||
import { TicketCategory } from "./entities/ticket-category.entity";
|
||||
import { Ticket } from "./entities/ticket.entity";
|
||||
import { TicketsController } from "./tickets.controller";
|
||||
import { TicketsService } from "./tickets.service";
|
||||
import { TicketsService } from "./providers/tickets.service";
|
||||
import { TicketMessage } from "./entities/ticket-message.entity";
|
||||
import { TicketsRepository } from "./repositories/tickets.repository";
|
||||
import { TicketCategoryRepository } from "./repositories/tickets-category.repository";
|
||||
import { TicketMessagesRepository } from "./repositories/tickets-message.repository";
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([Ticket, TicketCategory])],
|
||||
providers: [TicketsService],
|
||||
imports: [TypeOrmModule.forFeature([Ticket, TicketCategory, TicketMessage])],
|
||||
providers: [TicketsService, TicketsRepository, TicketCategoryRepository, TicketMessagesRepository],
|
||||
controllers: [TicketsController],
|
||||
exports: [TypeOrmModule, TicketsService, TicketsRepository, TicketCategoryRepository, TicketMessagesRepository],
|
||||
})
|
||||
export class TicketsModule {}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { Column, Entity, JoinColumn, ManyToOne, OneToMany } from "typeorm";
|
||||
import { Column, Entity, ManyToOne, OneToMany } from "typeorm";
|
||||
|
||||
import { Role } from "./role.entity";
|
||||
import { BaseEntity } from "../../../common/entities/base.entity";
|
||||
import { TicketMessage } from "../../tickets/entities/ticket-message.entity";
|
||||
import { Ticket } from "../../tickets/entities/ticket.entity";
|
||||
|
||||
@Entity()
|
||||
@@ -30,10 +31,12 @@ export class User extends BaseEntity {
|
||||
@Column({ type: "varchar", length: 100, unique: true, nullable: false })
|
||||
nationalCode: string;
|
||||
|
||||
@JoinColumn()
|
||||
@ManyToOne(() => Role, { eager: true, onDelete: "RESTRICT", nullable: false })
|
||||
role: Role;
|
||||
|
||||
@OneToMany(() => Ticket, (ticket) => ticket.user)
|
||||
tickets: Ticket[];
|
||||
|
||||
@OneToMany(() => TicketMessage, (ticketMessage) => ticketMessage.author)
|
||||
ticketMessage: TicketMessage[];
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ import slugify from "slugify";
|
||||
import { Not } from "typeorm";
|
||||
|
||||
import { RoleRepository } from "./roles.repository";
|
||||
import { UserRepository } from "./users.repository";
|
||||
import { roles } from "../../../../database/seeders/role.seeder";
|
||||
import { UserRepository } from "../repositories/users.repository";
|
||||
// import { roles } from "../../../../database/seeders/role.seeder";
|
||||
import { CommonMessage, UserMessage } from "../../../common/enums/message.enum";
|
||||
import { CompleteRegistrationDto } from "../../auth/DTO/complete-register.dto";
|
||||
import { CheckValidityDTO } from "../DTO/check-validity.dto";
|
||||
@@ -38,6 +38,7 @@ export class UsersService {
|
||||
/************************************************************ */
|
||||
|
||||
async getMe(userId: string) {
|
||||
this.logger.debug("sss");
|
||||
const user = await this.userRepository.findOne({ where: { id: userId }, select: this.userSelect });
|
||||
if (!user) throw new BadRequestException(UserMessage.USER_NOT_FOUND);
|
||||
return { user };
|
||||
@@ -105,11 +106,11 @@ export class UsersService {
|
||||
}
|
||||
|
||||
///****************************************************** */
|
||||
async roleSeeder() {
|
||||
const countRole = await this.roleRepository.count();
|
||||
if (countRole > 0) return;
|
||||
const createdRoles = await this.roleRepository.insert(roles);
|
||||
this.logger.log({ createdRoles });
|
||||
return createdRoles;
|
||||
}
|
||||
// async roleSeeder() {
|
||||
// const countRole = await this.roleRepository.count();
|
||||
// if (countRole > 0) return;
|
||||
// const createdRoles = await this.roleRepository.insert(roles);
|
||||
// this.logger.log({ createdRoles });
|
||||
// return createdRoles;
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ import { TypeOrmModule } from "@nestjs/typeorm";
|
||||
import { Role } from "./entities/role.entity";
|
||||
import { User } from "./entities/user.entity";
|
||||
import { RoleRepository } from "./providers/roles.repository";
|
||||
import { UserRepository } from "./providers/users.repository";
|
||||
import { UsersService } from "./providers/users.service";
|
||||
import { UserRepository } from "./repositories/users.repository";
|
||||
import { UsersController } from "./users.controller";
|
||||
|
||||
@Module({
|
||||
|
||||
Reference in New Issue
Block a user