gongxiangp2/lib/certificate-report.ts
chenpei 7326e273e1 fix: harden media upload and release safety
Protect upload cleanup and atomic completion paths, add durable media worker leases and brand asset validation, and introduce verified migration/bootstrap/deployment gates.
2026-08-12 18:04:08 +08:00

78 lines
2.3 KiB
TypeScript

export const CERTIFICATE_REPORT_MATERIAL_TYPE = '证书-检测报告'
export const CERTIFICATE_REPORT_ASSET_TYPE = {
PDF: 'report-pdf',
IMAGE: 'report-image',
} as const
export const CERTIFICATE_REPORT_UPLOAD_LIMITS = {
maxFiles: 20,
maxImageBytes: 100 * 1024 * 1024,
maxPdfBytes: 512 * 1024 * 1024,
maxTotalBytes: 1024 * 1024 * 1024,
} as const
const CERTIFICATE_REPORT_IMAGE_EXTENSIONS = new Set(['.jpg', '.jpeg', '.png', '.webp'])
export type CertificateReportAssetType =
(typeof CERTIFICATE_REPORT_ASSET_TYPE)[keyof typeof CERTIFICATE_REPORT_ASSET_TYPE]
export type CertificateReportFileKind = 'pdf' | 'image'
export function isCertificateReportMaterialType(materialType: string | null | undefined): boolean {
return String(materialType || '').trim() === CERTIFICATE_REPORT_MATERIAL_TYPE
}
export function normalizeReportTitle(value: string | null | undefined): string | null {
const normalized = typeof value === 'string' ? value.trim() : ''
return normalized || null
}
export function getCertificateReportDisplayTitle(input: {
productModel?: string | null
reportTitle?: string | null
}): string {
const productModel = String(input.productModel || '').trim()
if (productModel) {
return productModel
}
const reportTitle = String(input.reportTitle || '').trim()
if (reportTitle) {
return reportTitle
}
return '未命名报告'
}
export function getCertificateReportFileKindByAssetType(assetType: string | null | undefined): CertificateReportFileKind | null {
if (assetType === CERTIFICATE_REPORT_ASSET_TYPE.PDF) {
return 'pdf'
}
if (assetType === CERTIFICATE_REPORT_ASSET_TYPE.IMAGE) {
return 'image'
}
return null
}
export function detectFileKindFromName(fileName: string | null | undefined): CertificateReportFileKind {
const lowerName = String(fileName || '').trim().toLowerCase()
if (lowerName.endsWith('.pdf')) {
return 'pdf'
}
return 'image'
}
export function isSupportedCertificateReportFileName(fileName: string | null | undefined): boolean {
const normalized = String(fileName || '').trim().toLowerCase()
if (normalized.endsWith('.pdf')) {
return true
}
const extensionIndex = normalized.lastIndexOf('.')
const extension = extensionIndex >= 0 ? normalized.slice(extensionIndex) : ''
return CERTIFICATE_REPORT_IMAGE_EXTENSIONS.has(extension)
}