diff --git a/src/Types&Enums/role.enum.ts b/src/Types&Enums/role.enum.ts index beb0889..928890e 100644 --- a/src/Types&Enums/role.enum.ts +++ b/src/Types&Enums/role.enum.ts @@ -1,6 +1,7 @@ export enum RoleEnum { EXPERT = "expert", DAMAGE_EXPERT = "damage_expert", + FIELD_EXPERT = "field_expert", COMPANY = "company", ADMIN = "admin", USER = "user", diff --git a/src/auth/auth-controllers/actor/actor.auth.controller.ts b/src/auth/auth-controllers/actor/actor.auth.controller.ts index e099ba0..8905211 100644 --- a/src/auth/auth-controllers/actor/actor.auth.controller.ts +++ b/src/auth/auth-controllers/actor/actor.auth.controller.ts @@ -22,6 +22,7 @@ import { } from "src/auth/dto/actor/forget-password.actor.dto"; import { LoginActorDto } from "src/auth/dto/actor/login.actor.dto"; import { ActorEditUserProfileDto } from "src/auth/dto/actor/profile.actor.dto"; +import { CreateFieldExpertDto } from "src/auth/dto/actor/create-field-expert.actor.dto"; import { GenuineRegisterDto, InsurerRegisterDto, @@ -55,6 +56,14 @@ export class ActorAuthController { return await this.actorAuthService.insurerRegister(body); } + /** Mock: create a field expert for testing. Make private later. */ + @Post("create-field-expert") + @ApiBody({ type: CreateFieldExpertDto }) + @ApiAcceptedResponse() + async createFieldExpert(@Body() body: CreateFieldExpertDto) { + return await this.actorAuthService.createFieldExpertMock(body); + } + @UseGuards(LocalActorAuthGuard) @Post("login") @Roles() diff --git a/src/auth/auth-services/actor.auth.service.ts b/src/auth/auth-services/actor.auth.service.ts index 2cba56f..10c5d70 100644 --- a/src/auth/auth-services/actor.auth.service.ts +++ b/src/auth/auth-services/actor.auth.service.ts @@ -24,6 +24,7 @@ import { UserType } from "src/Types&Enums/userType.enum"; import { InsurerExpertDbService } from "src/users/entities/db-service/insurer-expert.db.service"; import { DamageExpertDbService } from "src/users/entities/db-service/damage-expert.db.service"; import { ExpertDbService } from "src/users/entities/db-service/expert.db.service"; +import { FieldExpertDbService } from "src/users/entities/db-service/field-expert.db.service"; import { HashService } from "src/utils/hash/hash.service"; import { MailService } from "src/utils/mail/mail.service"; import { OtpService } from "src/utils/otp/otp.service"; @@ -44,6 +45,7 @@ export class ActorAuthService { private readonly hashService: HashService, private readonly expertDbService: ExpertDbService, private readonly damageExpertDbService: DamageExpertDbService, + private readonly fieldExpertDbService: FieldExpertDbService, private readonly insurerExpertDbService: InsurerExpertDbService, private readonly mailService: MailService, private readonly clientDbService: ClientDbService, @@ -69,6 +71,14 @@ export class ActorAuthService { else res = await this.damageExpertDbService.findOne({ email: username }); break; + case RoleEnum.FIELD_EXPERT: + if (username == null && userId) + res = await this.fieldExpertDbService.findOne({ + _id: new Types.ObjectId(userId), + }); + else + res = await this.fieldExpertDbService.findOne({ email: username }); + break; case RoleEnum.COMPANY: res = await this.insurerExpertDbService.findOne({ email: username }); break; @@ -259,6 +269,11 @@ export class ActorAuthService { dbServiceToUpdate = this.insurerExpertDbService as any; } + if (!actor) { + actor = await this.fieldExpertDbService.findOne(filter); + dbServiceToUpdate = this.fieldExpertDbService as any; + } + if (!actor) { throw new NotFoundException("actor not found"); } @@ -278,18 +293,29 @@ export class ActorAuthService { } async forgetPasswordVerify(email, otp, newPassword) { - const userExist = await this.expertDbService.findOne({ email }); + let userExist: any = await this.expertDbService.findOne({ email }); + let dbServiceToUpdate: any = this.expertDbService; + if (!userExist) { + userExist = await this.damageExpertDbService.findOne({ email }); + dbServiceToUpdate = this.damageExpertDbService; + } + if (!userExist) { + userExist = await this.insurerExpertDbService.findOne({ email }); + dbServiceToUpdate = this.insurerExpertDbService; + } + if (!userExist) { + userExist = await this.fieldExpertDbService.findOne({ email }); + dbServiceToUpdate = this.fieldExpertDbService; + } if (!userExist) throw new NotFoundException("user not found"); const decodeOtp = await this.hashService.compare(otp, userExist.otp); if (!decodeOtp) throw new UnauthorizedException("otp invalid"); - if (decodeOtp) { - const hashNewPassword = await this.hashService.hash(newPassword); - await this.expertDbService.findOneAndUpdate( - { email }, - { password: hashNewPassword }, - ); - return new ForgetPasswordVerifyCodeDtoRs(userExist, "update password"); - } + const hashNewPassword = await this.hashService.hash(newPassword); + await dbServiceToUpdate.findOneAndUpdate( + { email }, + { password: hashNewPassword }, + ); + return new ForgetPasswordVerifyCodeDtoRs(userExist, "update password"); } async getProfiles(currentUser) { @@ -347,7 +373,14 @@ export class ActorAuthService { "city", "state", "address", - ] + ], + field_expert: [ + "firstName", + "lastName", + "email", + "phone", + "mobile", + ], }; const allowedFields = allowedFieldsByRole[role]; @@ -407,6 +440,13 @@ export class ActorAuthService { ); break; + case "field_expert": + await this.fieldExpertDbService.updateOne( + { _id: new Types.ObjectId(userId) }, + { $set: sanitized }, + ); + break; + default: throw new ForbiddenException("Unsupported role for update"); } @@ -417,4 +457,43 @@ export class ActorAuthService { throw new InternalServerErrorException("Failed to update profile"); } } + + /** Mock endpoint: create a field expert for testing. Make private later. */ + async createFieldExpertMock(body: { + email: string; + password: string; + firstName: string; + lastName: string; + mobile: string; + phone?: string; + }) { + const hashPassword = await this.hashService.hash(body.password); + const payload = { + email: body.email.toLowerCase().trim(), + password: hashPassword, + firstName: body.firstName, + lastName: body.lastName, + mobile: body.mobile, + phone: body.phone, + role: RoleEnum.FIELD_EXPERT, + }; + try { + const created = await this.fieldExpertDbService.create(payload); + return { + id: created._id, + email: created.email, + firstName: created.firstName, + lastName: created.lastName, + mobile: created.mobile, + role: created.role, + }; + } catch (er) { + if (er.code === 11000) { + throw new BadRequestException( + "A field expert with this email already exists.", + ); + } + throw er; + } + } } diff --git a/src/auth/dto/actor/create-field-expert.actor.dto.ts b/src/auth/dto/actor/create-field-expert.actor.dto.ts new file mode 100644 index 0000000..6d5f4f1 --- /dev/null +++ b/src/auth/dto/actor/create-field-expert.actor.dto.ts @@ -0,0 +1,30 @@ +import { ApiProperty } from "@nestjs/swagger"; +import { IsEmail, IsOptional, IsString, MinLength } from "class-validator"; + +export class CreateFieldExpertDto { + @ApiProperty({ example: "field.expert@example.com" }) + @IsEmail() + email: string; + + @ApiProperty({ example: "securePassword123", minLength: 6 }) + @IsString() + @MinLength(6) + password: string; + + @ApiProperty({ example: "علی" }) + @IsString() + firstName: string; + + @ApiProperty({ example: "محمدی" }) + @IsString() + lastName: string; + + @ApiProperty({ example: "09121234567" }) + @IsString() + mobile: string; + + @ApiProperty({ example: "02188776655", required: false }) + @IsOptional() + @IsString() + phone?: string; +} diff --git a/src/auth/guards/actor-local.guard.ts b/src/auth/guards/actor-local.guard.ts index 9996360..63a9926 100644 --- a/src/auth/guards/actor-local.guard.ts +++ b/src/auth/guards/actor-local.guard.ts @@ -39,9 +39,12 @@ export class LocalActorAuthGuard extends AuthGuard("actor") { }); if ( - ![RoleEnum.EXPERT, RoleEnum.DAMAGE_EXPERT, RoleEnum.COMPANY].includes( - payload.role, - ) + ![ + RoleEnum.EXPERT, + RoleEnum.DAMAGE_EXPERT, + RoleEnum.COMPANY, + RoleEnum.FIELD_EXPERT, + ].includes(payload.role) ) { throw new UnauthorizedException("User role is not authorized"); } diff --git a/src/claim-request-management/claim-request-management.module.ts b/src/claim-request-management/claim-request-management.module.ts index 51a76e9..21c916c 100644 --- a/src/claim-request-management/claim-request-management.module.ts +++ b/src/claim-request-management/claim-request-management.module.ts @@ -79,6 +79,7 @@ import { JwtModule } from "@nestjs/jwt"; ], controllers: [ClaimRequestManagementController], exports: [ + ClaimRequestManagementService, ClaimRequestManagementDbService, DamageImageDbService, VideoCaptureDbService, diff --git a/src/claim-request-management/claim-request-management.service.ts b/src/claim-request-management/claim-request-management.service.ts index 50cfa0e..0bd2263 100644 --- a/src/claim-request-management/claim-request-management.service.ts +++ b/src/claim-request-management/claim-request-management.service.ts @@ -118,7 +118,12 @@ export class ClaimRequestManagementService { // If actor is an expert, verify they're accessing an IN_PERSON claim file // and return the claim file's userId - if (actor.role === RoleEnum.EXPERT || actor.role === RoleEnum.DAMAGE_EXPERT) { + const expertRoles = [ + RoleEnum.EXPERT, + RoleEnum.DAMAGE_EXPERT, + RoleEnum.FIELD_EXPERT, + ]; + if (expertRoles.includes(actor.role)) { const claim = await this.claimDbService.findOne(claimRequestId); if (!claim) { throw new NotFoundException("Claim file not found"); @@ -184,11 +189,16 @@ export class ClaimRequestManagementService { // For IN_PERSON expert-initiated files, expert creates the claim // For LINK method or regular files, user creates their own claim + const expertRoles = [ + RoleEnum.EXPERT, + RoleEnum.DAMAGE_EXPERT, + RoleEnum.FIELD_EXPERT, + ]; if ( blameRequest.expertInitiated && blameRequest.creationMethod === "IN_PERSON" && actor && - (actor.role === "EXPERT" || actor.role === "DAMAGE_EXPERT") + expertRoles.includes(actor.role) ) { // Expert is creating claim for IN_PERSON file // Verify expert is the initiating expert @@ -343,6 +353,69 @@ export class ClaimRequestManagementService { } } + /** + * Field expert completes claim-needed data for expert-initiated IN_PERSON files. + * Only the initiating expert can call this. Accepts car part damage and/or sheba, nationalCodeOfInsurer, otherParts. + */ + async expertCompleteClaimData( + claimRequestId: string, + expert: any, + dto: { + carPartDamage?: CarDamagePartDto; + sheba?: string; + nationalCodeOfInsurer?: string; + otherParts?: any[]; + }, + ): Promise<{ success: boolean; claimRequestId: string }> { + const claim = await this.claimDbService.findOne(claimRequestId); + if (!claim) { + throw new NotFoundException("Claim file not found"); + } + + const blameFile = claim.blameFile as any; + if (!blameFile?.expertInitiated || blameFile?.creationMethod !== "IN_PERSON") { + throw new BadRequestException( + "This endpoint is only for expert-initiated IN_PERSON claim files.", + ); + } + if (String(blameFile.initiatedBy) !== expert.sub) { + throw new ForbiddenException( + "Only the initiating field expert can complete claim data for this file.", + ); + } + + if (dto.carPartDamage) { + if (claim.carPartDamage && (claim.carPartDamage as any[]).length > 0) { + throw new BadRequestException("Car part damage is already set."); + } + const trueItems = this.findTrueItems(dto.carPartDamage); + const claimDoc = (await this.claimDbService.findOne( + claimRequestId, + )) as any; + if (claimDoc) { + await this.setCarPartDamageAndImage(claimDoc, trueItems); + } + await this.claimDbService.findAndUpdate(claimRequestId, { + currentStep: ClaimStepsEnum.SelectDamagePart, + nextStep: ClaimStepsEnum.SelectOtherParts, + $push: { steps: ClaimStepsEnum.SelectDamagePart }, + }); + } + + const updates: Record = {}; + if (dto.sheba != null) updates.sheba = dto.sheba; + if (dto.nationalCodeOfInsurer != null) + updates.nationalCodeOfInsurer = dto.nationalCodeOfInsurer; + if (dto.otherParts != null) updates.otherParts = dto.otherParts; + if (Object.keys(updates).length > 0) { + await this.claimDbService.findAndUpdate(claimRequestId, { + $set: updates, + }); + } + + return { success: true, claimRequestId }; + } + async selectCarOtherPartDamage( requestId: string, body: any, // Use your DTO for better type safety @@ -1186,10 +1259,12 @@ export class ClaimRequestManagementService { } // For experts, return IN_PERSON claim files they initiated - if ( - currentUser.role === RoleEnum.EXPERT || - currentUser.role === RoleEnum.DAMAGE_EXPERT - ) { + const expertRoles = [ + RoleEnum.EXPERT, + RoleEnum.DAMAGE_EXPERT, + RoleEnum.FIELD_EXPERT, + ]; + if (expertRoles.includes(currentUser.role)) { const allClaims = await this.claimDbService.findAllByAnyFilter({}); const expertClaims = allClaims.filter((claim) => { const blameFile = claim.blameFile; diff --git a/src/request-management/dto/expert-complete-claim-data.dto.ts b/src/request-management/dto/expert-complete-claim-data.dto.ts new file mode 100644 index 0000000..0b4c903 --- /dev/null +++ b/src/request-management/dto/expert-complete-claim-data.dto.ts @@ -0,0 +1,32 @@ +import { ApiPropertyOptional } from "@nestjs/swagger"; +import { CarDamagePartDto } from "src/claim-request-management/dto/car-part.dto"; + +/** + * DTO for field expert to submit claim-needed data in one go (IN_PERSON flow). + * All fields optional so expert can submit in one or two steps (e.g. car parts first, then sheba/other). + */ +export class ExpertCompleteClaimDataDto { + @ApiPropertyOptional({ + description: "Car part damage selection (same as selectCarPartDamage). Required for first claim data step.", + type: CarDamagePartDto, + }) + carPartDamage?: CarDamagePartDto; + + @ApiPropertyOptional({ + description: "Sheba number", + example: "IR123456789012345678901234", + }) + sheba?: string; + + @ApiPropertyOptional({ + description: "National code of insurer", + example: "1234567890", + }) + nationalCodeOfInsurer?: string; + + @ApiPropertyOptional({ + description: "Other parts / extra damage items", + example: [{ "حسگر درها": true }], + }) + otherParts?: any[]; +} diff --git a/src/request-management/expert-initiated.controller.ts b/src/request-management/expert-initiated.controller.ts index 3845975..f99ce73 100644 --- a/src/request-management/expert-initiated.controller.ts +++ b/src/request-management/expert-initiated.controller.ts @@ -34,17 +34,83 @@ import { CreateExpertInitiatedFileDto } from "./dto/expert-initiated.dto"; import { ExpertCompleteThirdPartyFormDto } from "./dto/expert-complete-third-party-form.dto"; import { ExpertCompleteCarBodyFormDto } from "./dto/expert-complete-car-body-form.dto"; import { ExpertAccidentFieldsDto } from "./dto/expert-accident-fields.dto"; +import { ExpertCompleteClaimDataDto } from "./dto/expert-complete-claim-data.dto"; +import { ClaimRequestManagementService } from "src/claim-request-management/claim-request-management.service"; @ApiTags("expert-initiated-blame") @Controller("expert-initiated-blame") @ApiBearerAuth() @UseGuards(LocalActorAuthGuard, RolesGuard) -@Roles(RoleEnum.EXPERT, RoleEnum.DAMAGE_EXPERT) +@Roles(RoleEnum.FIELD_EXPERT) export class ExpertInitiatedController { constructor( private readonly requestManagementService: RequestManagementService, + private readonly claimRequestManagementService: ClaimRequestManagementService, ) {} + @Get("my-files") + @ApiOperation({ + summary: "List my expert-initiated files", + description: + "Returns all blame files created by the current field expert (their panel).", + }) + @ApiResponse({ status: 200, description: "List of expert-initiated files" }) + async getMyFiles(@CurrentUser() expert: any) { + return await this.requestManagementService.getMyExpertInitiatedFiles( + expert, + ); + } + + @Post("complete-blame-data/:requestId") + @ApiOperation({ + summary: "Submit all blame-needed data", + description: + "Single endpoint to complete blame form: send THIRD_PARTY or CAR_BODY form data according to file type. " + + "Video and voice can be uploaded separately.", + }) + @ApiParam({ name: "requestId", description: "ID of the expert-initiated file" }) + @ApiBody({ + description: + "Send ExpertCompleteThirdPartyFormDto for THIRD_PARTY files or ExpertCompleteCarBodyFormDto for CAR_BODY files (according to file type).", + }) + @ApiResponse({ status: 200, description: "Blame form completed successfully" }) + async completeBlameData( + @CurrentUser() expert: any, + @Param("requestId") requestId: string, + @Body() formData: any, + ) { + return await this.requestManagementService.completeBlameData( + expert, + requestId, + formData, + ); + } + + @Post("complete-claim-data/:claimRequestId") + @ApiOperation({ + summary: "Submit claim-needed data", + description: + "Field expert fills claim data for expert-initiated IN_PERSON files (car part damage, sheba, national code, other parts). " + + "Only the initiating expert can call this.", + }) + @ApiParam({ + name: "claimRequestId", + description: "ID of the claim file (created from the expert-initiated blame file)", + }) + @ApiBody({ type: ExpertCompleteClaimDataDto }) + @ApiResponse({ status: 200, description: "Claim data updated successfully" }) + async completeClaimData( + @CurrentUser() expert: any, + @Param("claimRequestId") claimRequestId: string, + @Body() dto: ExpertCompleteClaimDataDto, + ) { + return await this.claimRequestManagementService.expertCompleteClaimData( + claimRequestId, + expert, + dto, + ); + } + @Post("create") @ApiOperation({ summary: "Create expert-initiated blame file", diff --git a/src/request-management/request-management.service.ts b/src/request-management/request-management.service.ts index 640dbcd..de94e50 100644 --- a/src/request-management/request-management.service.ts +++ b/src/request-management/request-management.service.ts @@ -2005,8 +2005,13 @@ export class RequestManagementService { request: RequestManagementModel, user: any, ): Promise { - // If user is not an expert, no verification needed (normal flow) - if (user.role !== RoleEnum.EXPERT && user.role !== RoleEnum.DAMAGE_EXPERT) { + // If user is not an expert type, no verification needed (normal flow) + const expertRoles = [ + RoleEnum.EXPERT, + RoleEnum.DAMAGE_EXPERT, + RoleEnum.FIELD_EXPERT, + ]; + if (!expertRoles.includes(user.role)) { return; } @@ -2155,6 +2160,60 @@ export class RequestManagementService { }; } + /** + * List all expert-initiated blame files for the current field expert (their panel). + * Only files where initiatedBy === current user are returned. + */ + async getMyExpertInitiatedFiles(expert: any): Promise { + const expertId = new Types.ObjectId(expert.sub); + const files = await this.requestManagementDbService.findAll({ + expertInitiated: true, + initiatedBy: expertId, + }); + return (files || []).map((f) => ({ + _id: f._id, + requestNumber: f.requestNumber, + type: f.type, + creationMethod: f.creationMethod, + blameStatus: f.blameStatus, + currentStep: f.currentStep, + nextStep: f.nextStep, + createdAt: f.createdAt, + steps: f.steps, + })); + } + + /** + * Single endpoint handler: complete all blame-needed data. + * Routes to THIRD_PARTY or CAR_BODY completion based on request type. + */ + async completeBlameData( + expert: any, + requestId: string, + formData: any, + ): Promise { + const request = await this.requestManagementDbService.findOne(requestId); + if (!request) { + throw new NotFoundException("Request not found"); + } + if (!request.expertInitiated) { + throw new BadRequestException( + "This endpoint is only for expert-initiated files", + ); + } + await this.verifyExpertAccess(request, expert); + + if (request.type === "THIRD_PARTY") { + return this.expertCompleteThirdPartyForm(expert, requestId, formData); + } + if (request.type === "CAR_BODY") { + return this.expertCompleteCarBodyForm(expert, requestId, formData); + } + throw new BadRequestException( + "Unknown file type. Must be THIRD_PARTY or CAR_BODY.", + ); + } + /** * Expert completes all information for IN_PERSON THIRD_PARTY file at once * This replaces the step-by-step flow for experts filling files on-site diff --git a/src/users/entities/db-service/field-expert.db.service.ts b/src/users/entities/db-service/field-expert.db.service.ts new file mode 100644 index 0000000..d5992f3 --- /dev/null +++ b/src/users/entities/db-service/field-expert.db.service.ts @@ -0,0 +1,49 @@ +import { Injectable } from "@nestjs/common"; +import { InjectModel } from "@nestjs/mongoose"; +import { FilterQuery, Model, Types } from "mongoose"; +import { FieldExpertModel } from "../schema/field-expert.schema"; + +@Injectable() +export class FieldExpertDbService { + constructor( + @InjectModel(FieldExpertModel.name) + private readonly fieldExpertModel: Model, + ) {} + + async create( + user: Partial & { password: string }, + ): Promise { + return await this.fieldExpertModel.create(user); + } + + async findOne( + filter: FilterQuery, + ): Promise { + return await this.fieldExpertModel.findOne(filter); + } + + async findById(userId: string): Promise { + return await this.fieldExpertModel.findOne({ + _id: new Types.ObjectId(userId), + }); + } + + async findOneAndUpdate( + filter: FilterQuery, + update: FilterQuery, + ) { + return await this.fieldExpertModel.findOneAndUpdate(filter, update, { + new: true, + }); + } + + async findAll( + filter: FilterQuery, + ): Promise<(FieldExpertModel & { _id: Types.ObjectId })[]> { + return await this.fieldExpertModel.find(filter).lean(); + } + + async updateOne(filter: FilterQuery, update: any) { + return this.fieldExpertModel.updateOne(filter, update); + } +} diff --git a/src/users/entities/schema/field-expert.schema.ts b/src/users/entities/schema/field-expert.schema.ts new file mode 100644 index 0000000..dd5838d --- /dev/null +++ b/src/users/entities/schema/field-expert.schema.ts @@ -0,0 +1,78 @@ +import { Prop, Schema, SchemaFactory } from "@nestjs/mongoose"; +import { Types } from "mongoose"; +import { RoleEnum } from "src/Types&Enums/role.enum"; + +@Schema({ _id: false }) +export class RequestStats { + @Prop({ default: 0 }) + totalHandled: number; + + @Prop({ default: 0 }) + totalChecked: number; +} + +const RequestStatsSchema = SchemaFactory.createForClass(RequestStats); + +@Schema({ + collection: "field-expert", + versionKey: false, + timestamps: true, +}) +export class FieldExpertModel { + _id?: Types.ObjectId; + + @Prop({ required: true }) + firstName: string; + + @Prop({ required: true }) + lastName: string; + + @Prop({ type: "string", unique: true }) + email: string; + + @Prop({ type: "string" }) + username: string; + + @Prop({ required: true }) + password: string; + + @Prop({ required: true }) + mobile: string; + + @Prop({ required: false }) + phone?: string; + + @Prop({ default: RoleEnum.FIELD_EXPERT }) + role: RoleEnum; + + @Prop({ type: "string", default: "" }) + otp: string; + + @Prop({ type: RequestStatsSchema, default: () => ({}) }) + requestStats: RequestStats; + + @Prop({ + type: [{ type: String }], + default: [], + validate: { + validator: (arr: any[]) => arr.every((val) => typeof val === "string"), + message: "All countedRequests must be strings", + }, + }) + countedRequests?: string[]; + + createdAt: Date; +} + +export const FieldExpertDbSchema = + SchemaFactory.createForClass(FieldExpertModel); + +FieldExpertDbSchema.pre("save", function (next) { + if (!this.username) { + this.username = this.email; + } + if (!this.requestStats) { + this.requestStats = { totalChecked: 0, totalHandled: 0 }; + } + next(); +}); diff --git a/src/users/users.module.ts b/src/users/users.module.ts index 85a2e8f..c9fa042 100644 --- a/src/users/users.module.ts +++ b/src/users/users.module.ts @@ -5,6 +5,7 @@ import { ExpertModel } from "src/users/entities/schema/expert.schema"; import { HashModule } from "src/utils/hash/hash.module"; import { OtpModule } from "src/utils/otp/otp.module"; import { ExpertDbService } from "./entities/db-service/expert.db.service"; +import { FieldExpertDbService } from "./entities/db-service/field-expert.db.service"; import { InsurerExpertDbService } from "./entities/db-service/insurer-expert.db.service"; import { UserDbService } from "./entities/db-service/user.db.service"; import { @@ -12,6 +13,10 @@ import { DamageExpertModel, } from "./entities/schema/damage-expert.schema"; import { ExpertDbSchema } from "./entities/schema/expert.schema"; +import { + FieldExpertDbSchema, + FieldExpertModel, +} from "./entities/schema/field-expert.schema"; import { InsurerExpertDbSchema, InsurerExpertModel, @@ -24,6 +29,7 @@ import { UserModel, UserDbSchema } from "./entities/schema/user.schema"; { name: UserModel.name, schema: UserDbSchema }, { name: DamageExpertModel.name, schema: DamageExpertDbSchema }, { name: ExpertModel.name, schema: ExpertDbSchema }, + { name: FieldExpertModel.name, schema: FieldExpertDbSchema }, { name: InsurerExpertModel.name, schema: InsurerExpertDbSchema }, ]), OtpModule, @@ -34,12 +40,14 @@ import { UserModel, UserDbSchema } from "./entities/schema/user.schema"; UserDbService, ExpertDbService, DamageExpertDbService, + FieldExpertDbService, InsurerExpertDbService, ], exports: [ UserDbService, ExpertDbService, DamageExpertDbService, + FieldExpertDbService, InsurerExpertDbService, ], })