Fix links

This commit is contained in:
SepehrYahyaee
2026-06-13 17:24:25 +03:30
parent 3e5e9852ad
commit 6426233350
9 changed files with 78 additions and 20 deletions

View File

@@ -15,7 +15,7 @@ import { isAxiosError } from "axios";
import { unlink } from "node:fs/promises";
import { existsSync } from "node:fs";
import { AiService } from "src/ai/ai.service";
import { buildFileLink } from "src/helpers/urlCreator";
import { buildFileLink, resolveStoredFileUrl } from "src/helpers/urlCreator";
import { RequestManagementDbService } from "src/request-management/entities/db-service/request-management.db.service";
import { ReqBlameStatus } from "src/Types&Enums/blame-request-management/status.enum";
import { ReqClaimStatus } from "src/Types&Enums/claim-request-management/status.enum";
@@ -6644,7 +6644,7 @@ export class ClaimRequestManagementService {
) as { url?: string; path?: string } | undefined;
carAngles[k] = {
captured: !!cap,
url: cap?.url || (cap?.path ? buildFileLink(cap.path) : undefined),
url: resolveStoredFileUrl(cap),
};
}

View File

@@ -22,7 +22,9 @@ export class EnvironmentVariables {
message: "NODE_ENV should be development or production",
})
NODE_ENV: Environment;
// --------------------------------------------------------- //
@IsNumber(
{
allowNaN: false,
@@ -36,7 +38,9 @@ export class EnvironmentVariables {
@Min(0, { message: "PORT must be between 0 and 65535" })
@Max(65535, { message: "PORT must be between 0 and 65535" })
PORT: number;
// --------------------------------------------------------- //
@IsString({ message: "MONGO_URI must be string" })
@IsUrl(
{
@@ -48,23 +52,32 @@ export class EnvironmentVariables {
},
)
MONGO_URI: string;
// --------------------------------------------------------- //
@IsBooleanString({ message: "MONGO_TLS must be boolean" })
MONGO_TLS: string;
// --------------------------------------------------------- //
@IsBooleanString({ message: "MONGO_TLS_ALLOW_INVALID_CERTS must be boolean" })
MONGO_TLS_ALLOW_INVALID_CERTS: string;
// --------------------------------------------------------- //
@IsString({ message: "JWT_SECRET must be string" })
@MinLength(32, {
message: "JWT_SECRET must be at least 32 characters",
})
JWT_SECRET: string;
// --------------------------------------------------------- //
@Matches(/^\d+(ms|s|m|h|d|w|y)$/, {
message: "JWT_EXPIRY must be in the correct format",
})
JWT_EXPIRY: StringValue;
// --------------------------------------------------------- //
// @IsString({ message: "HASH_PEPPER must be string" })
// @MinLength(32, {

View File

@@ -1,5 +1,6 @@
// claim-damaged-part.enricher.ts
import { resolveStoredFileUrl } from "src/helpers/urlCreator";
import {
DamagedPartCaptureStatus,
EnrichedDamagedPart,
@@ -14,6 +15,9 @@ export function buildEnrichedDamagedParts(params: {
hasDamagedPartCapture: (data: any, key: string, parts: any[]) => boolean;
catalogLikeKeyFromPart: (part: any) => string;
buildFileLink: (path: string) => string;
resolveStoredFileUrl?: (
stored?: { url?: string; path?: string } | null,
) => string | undefined;
}): EnrichedDamagedPart[] {
const {
selectedParts,
@@ -24,6 +28,7 @@ export function buildEnrichedDamagedParts(params: {
hasDamagedPartCapture,
catalogLikeKeyFromPart,
buildFileLink,
resolveStoredFileUrl: resolveUrl = resolveStoredFileUrl,
} = params;
const priceDropLines: any[] = evaluationBlock?.priceDrop?.partLines ?? [];
@@ -109,17 +114,13 @@ export function buildEnrichedDamagedParts(params: {
: false);
const capUrl =
cap?.url ||
(cap?.path ? buildFileLink(cap.path) : undefined) ||
resolveUrl(cap) ||
(sp.id == null && Array.isArray(damagedPartsData)
? (() => {
const match = (damagedPartsData as any[]).find(
(d) => d.name === sp.name && d.side === sp.side && d.path,
);
return (
match?.url ||
(match?.path ? buildFileLink(match.path) : undefined)
);
return resolveUrl(match);
})()
: undefined);

View File

@@ -20,7 +20,7 @@ import { ClaimSignDbService } from "src/claim-request-management/entites/db-serv
import { DamageImageDbService } from "src/claim-request-management/entites/db-service/damage-image.db.service";
import { VideoCaptureDbService } from "src/claim-request-management/entites/db-service/video-capture.db.service";
import { ClientDbService } from "src/client/entities/db-service/client.db.service";
import { buildFileLink } from "src/helpers/urlCreator";
import { buildFileLink, resolveStoredFileUrl } from "src/helpers/urlCreator";
import { toJalaliDateAndTime } from "src/helpers/date-jalali";
import { BlameDocumentDbService } from "src/request-management/entities/db-service/blame-document.db.service";
import { BlameVideoDbService } from "src/request-management/entities/db-service/blame-video.db.service";
@@ -3941,7 +3941,7 @@ export class ExpertClaimService {
) as { url?: string; path?: string } | undefined;
carAngles[k] = {
captured: !!cap,
url: cap?.url || (cap?.path ? buildFileLink(cap.path) : undefined),
url: resolveStoredFileUrl(cap),
};
}
@@ -3965,6 +3965,7 @@ export class ExpertClaimService {
hasDamagedPartCapture,
catalogLikeKeyFromPart,
buildFileLink,
resolveStoredFileUrl,
});
// Vehicle payload — fall back to blame inquiry if claim vehicle is sparse

View File

@@ -33,7 +33,7 @@ import { BlameVideoDbService } from "src/request-management/entities/db-service/
import { BlameVoiceDbService } from "src/request-management/entities/db-service/blame.voice.db.service";
import { VideoCaptureDbService } from "src/claim-request-management/entites/db-service/video-capture.db.service";
import { ClientDbService } from "src/client/entities/db-service/client.db.service";
import { buildFileLink } from "src/helpers/urlCreator";
import { buildFileLink, resolveStoredFileUrl } from "src/helpers/urlCreator";
import { toJalaliDateAndTime } from "src/helpers/date-jalali";
import { enrichBlamePartiesForAgreementView } from "src/helpers/blame-party-agreement-decision";
import { BlameRequestType } from "src/Types&Enums/blame-request-management/blameRequestType.enum";
@@ -422,7 +422,7 @@ export class ExpertInsurerService {
ck,
selectedNormExpert,
) as { url?: string; path?: string; fileName?: string } | undefined;
const url = cap?.url || (cap?.path ? buildFileLink(cap.path) : undefined);
const url = resolveStoredFileUrl(cap);
const link = url;
return {
index,
@@ -633,7 +633,7 @@ export class ExpertInsurerService {
) as { url?: string; path?: string } | undefined;
carAngles[k] = {
captured: !!cap,
url: cap?.url || (cap?.path ? buildFileLink(cap.path) : undefined),
url: resolveStoredFileUrl(cap),
};
}

View File

@@ -9,6 +9,7 @@ import {
} from "./outer-damage-parts";
import { ClaimVehicleTypeV2 } from "src/static/outer-car-parts-catalog";
import { canonicalizeResendDocumentKey } from "./claim-resend-document-keys";
import { resolveStoredFileUrl } from "./urlCreator";
export type ExpertResendCarPartV2 = {
id?: number | null;
@@ -161,8 +162,7 @@ export function mapExpertResendCarPartsForClient(
const capturedFromStore =
typeof stored.captured === "boolean" ? stored.captured : undefined;
const url =
cap?.url ||
(cap?.path && options.buildUrl ? options.buildUrl(cap.path) : undefined);
resolveStoredFileUrl(cap);
return {
id: sp.id,

View File

@@ -1,9 +1,38 @@
type StoredFileCapture = {
url?: string;
path?: string;
};
/**
* Build a public file URL from a relative storage path (e.g. `files/...`).
* Uses the current `URL` env so deployments with custom routing stay correct.
*/
export function buildFileLink(path: string): string {
const baseUrl = process.env.URL;
if(process.env.NODE_ENV === 'local'){
return baseUrl + "/" + path;
}else{
return baseUrl + "/api/" + path;
const normalized = String(path ?? "").trim();
if (!normalized) return normalized;
if (/^https?:\/\//i.test(normalized)) {
return normalized;
}
const baseUrl = (process.env.URL ?? "").replace(/\/+$/, "");
const relativePath = normalized.replace(/^\/+/, "");
if (process.env.NODE_ENV === "local") {
return `${baseUrl}/${relativePath}`;
}
return `${baseUrl}/api/${relativePath}`;
}
/**
* Resolve a file URL from persisted capture metadata.
* Prefer rebuilding from `path` so stale baked-in URLs (e.g. user-portal prefix)
* do not leak into expert/other API responses.
*/
export function resolveStoredFileUrl(
stored?: StoredFileCapture | null,
): string | undefined {
const path = stored?.path?.trim();
if (path) {
return buildFileLink(path);
}
return stored?.url;
}