1
0
forked from Yara724/api

Fixed smsApiKey index error and err handling in ESG

This commit is contained in:
SepehrYahyaee
2026-06-21 12:18:08 +03:30
parent 570fa865de
commit d0e7694374
6 changed files with 56 additions and 28 deletions

View File

@@ -114,6 +114,7 @@ export class ClientService {
) {}
async addClient(client: ClientDto): Promise<ClientDtoRs> {
try {
const smsApiKey = client.property?.smsApiKey?.trim();
const newClient = await this.clientDbService.create({
clientCode: client.clientCode,
@@ -129,9 +130,7 @@ export class ClientService {
: (client.clientName?.english ?? null),
},
property: {
smsApiKey: client.property?.smsApiKey ?? null,
},
...(smsApiKey ? { property: { smsApiKey } } : {}),
useExpertMode: client.useExpertMode ?? null,
});

View File

@@ -23,8 +23,9 @@ class ClientName {
}
class Property {
@ApiPropertyOptional({})
@IsOptional()
@IsString()
smsApiKey: string;
smsApiKey?: string;
}
export class ClientDto {

View File

@@ -1,15 +1,49 @@
import { Injectable } from "@nestjs/common";
import { Injectable, Logger, OnModuleInit } from "@nestjs/common";
import { InjectModel } from "@nestjs/mongoose";
import { FilterQuery, Model, UpdateQuery } from "mongoose";
import { ClientModel, ClientDocument } from "../schema/client.schema";
@Injectable()
export class ClientDbService {
export class ClientDbService implements OnModuleInit {
private readonly logger = new Logger(ClientDbService.name);
constructor(
@InjectModel(ClientModel.name)
private readonly clientModel: Model<ClientModel>,
) {}
async onModuleInit(): Promise<void> {
await this.dropLegacyPropertyUniqueIndex();
}
/**
* `property` was once declared `unique: true` in the schema. Production keeps
* `autoIndex: false`, so the stale unique index remained and rejected a second
* client with a missing/null SMS key (E11000 duplicate key).
*/
private async dropLegacyPropertyUniqueIndex(): Promise<void> {
try {
const indexes = await this.clientModel.collection.indexes();
for (const index of indexes) {
if (!index.unique || !index.name || index.name === "_id_") continue;
const keys = Object.keys(index.key ?? {});
const isLegacyPropertyIndex =
keys.length === 1 &&
(keys[0] === "property" || keys[0] === "property.smsApiKey");
if (!isLegacyPropertyIndex) continue;
await this.clientModel.collection.dropIndex(index.name);
this.logger.warn(
`Dropped legacy unique index on clients.${keys[0]}: ${index.name}`,
);
}
} catch (err) {
this.logger.error("Failed to drop legacy client property index", err);
}
}
async create(client: ClientModel): Promise<ClientModel> {
return await this.clientModel.create(client);
}

View File

@@ -96,9 +96,9 @@ export class ClientModel {
english: string;
};
@Prop({ required: false, unique: false, type: Object })
property: {
smsApiKey: string;
@Prop({ required: false, type: Object })
property?: {
smsApiKey?: string;
};
@Prop({ required: true, unique: false })

View File

@@ -4061,9 +4061,6 @@ export class RequestManagementService {
persian: data.clientName,
english: null,
},
property: {
smsApiKey: null,
},
useExpertMode: "genuine",
});
} catch (err) {

View File

@@ -20,6 +20,9 @@ import { firstValueFrom } from "rxjs";
@Injectable()
export class SandHubService {
private static readonly ESG_INQUIRY_UNAVAILABLE_MESSAGE =
"استعلام در دسترس نیست";
private readonly logger = new Logger(SandHubService.name);
private loginToken: string | null = null;
private tokenExpiry: Date | null = null;
@@ -528,17 +531,13 @@ export class SandHubService {
if (!raw) return raw;
if (raw?.success === false) {
this.logger.warn(
"ESG policyByPlate inquiry returned success=false",
raw,
);
return {
Error: {
Message:
raw?.error?.message ||
raw?.message ||
"ESG policyByPlate inquiry returned an error",
Code: raw?.error?.code || raw?.error?.providerCode || "ESG_INQUIRY_ERROR",
ProviderMessage: raw?.error?.providerMessage,
ProviderCode: raw?.error?.providerCode,
TrackingCode: raw?.trackingCode,
Conflict: raw?.error?.conflict,
Message: SandHubService.ESG_INQUIRY_UNAVAILABLE_MESSAGE,
},
};
}
@@ -622,10 +621,9 @@ export class SandHubService {
private mapEsgPersonInquiryToOldFormat(raw: any): Record<string, unknown> {
if (raw?.success === false) {
throw new NotFoundException(
raw?.error?.message ||
raw?.message ||
"Personal inquiry failed: Record not found for the given national code and birth date.",
this.logger.warn("ESG person inquiry returned success=false", raw);
throw new BadRequestException(
SandHubService.ESG_INQUIRY_UNAVAILABLE_MESSAGE,
);
}
@@ -648,10 +646,9 @@ export class SandHubService {
private mapEsgShebaInquiryToOldFormat(raw: any): Record<string, unknown> {
if (raw?.success === false) {
this.logger.warn("ESG sheba inquiry returned success=false", raw);
throw new BadRequestException(
raw?.error?.message ||
raw?.message ||
"Sheba ID validation failed. The provided Sheba ID does not match the national ID.",
SandHubService.ESG_INQUIRY_UNAVAILABLE_MESSAGE,
);
}