From 02a88da4301ac0987e0f8b8085fcfcf1de722e69 Mon Sep 17 00:00:00 2001 From: AutonetSellCar Deploy Date: Wed, 18 Feb 2026 09:08:58 +0900 Subject: [PATCH] fix: Show skip/error reasons in car import results - Backend: Include car_name in skipped response - Frontend: Display skip details (car name + reason like "Already imported (ID: 123)") - Frontend: Display error details with error message - Add import process description during loading Co-Authored-By: Claude Opus 4.6 --- backend/app/api/carmodoo.py | 1 + frontend/src/app/admin/cars/page.tsx | 125 ++++++++++++++++++++------- 2 files changed, 94 insertions(+), 32 deletions(-) diff --git a/backend/app/api/carmodoo.py b/backend/app/api/carmodoo.py index 933bef6..04647b6 100644 --- a/backend/app/api/carmodoo.py +++ b/backend/app/api/carmodoo.py @@ -1423,6 +1423,7 @@ async def import_cars_from_carmodoo( skipped.append({ "car_no": car_data.car_no, "car_id": existing.id, + "car_name": car_data.car_name or existing.name or car_data.car_no, "reason": "already exists" }) continue diff --git a/frontend/src/app/admin/cars/page.tsx b/frontend/src/app/admin/cars/page.tsx index 06d1d35..05414e2 100644 --- a/frontend/src/app/admin/cars/page.tsx +++ b/frontend/src/app/admin/cars/page.tsx @@ -199,6 +199,16 @@ export default function CarsAdminPage() { attempts: number; error?: string; }>; + skipDetails?: Array<{ + car_no: string; + car_id: number; + car_name: string; + reason: string; + }>; + errorDetails?: Array<{ + car_no: string; + error: string; + }>; } | null>(null); const [pdfStatus, setPdfStatus] = useState>({}); const [regeneratingPdf, setRegeneratingPdf] = useState(null); @@ -738,6 +748,8 @@ export default function CarsAdminPage() { pdfSuccess: data.summary.pdf_success_count || 0, pdfFailed: data.summary.pdf_failed_count || 0, pdfDetails, + skipDetails: data.skipped || [], + errorDetails: data.errors || [], }); // Remove imported cars from selection and reload local cars @@ -2207,41 +2219,53 @@ export default function CarsAdminPage() { {/* Import Result */} {importResult && (
0 - ? 'bg-amber-50 border-amber-200' - : 'bg-green-50 border-green-200' + importResult.errors > 0 + ? 'bg-red-50 border-red-200' + : importResult.pdfFailed > 0 + ? 'bg-amber-50 border-amber-200' + : 'bg-green-50 border-green-200' }`}>
-
+

0 ? 'text-amber-800' : 'text-green-800' + importResult.errors > 0 ? 'text-red-800' : importResult.pdfFailed > 0 ? 'text-amber-800' : 'text-green-800' }`}> Import Complete

-
- Imported: {importResult.imported} - Skipped: {importResult.skipped} - {importResult.errors > 0 && ( - Errors: {importResult.errors} - )} -
-
- - - - - PDF Success: {importResult.pdfSuccess} +
+ + Imported: {importResult.imported} - {importResult.pdfFailed > 0 && ( - - - - - PDF Failed: {importResult.pdfFailed} + {importResult.skipped > 0 && ( + + Skipped: {importResult.skipped} + + )} + {importResult.errors > 0 && ( + + Errors: {importResult.errors} )}
+ {importResult.imported > 0 && ( +
+ + + + + PDF Success: {importResult.pdfSuccess} + + {importResult.pdfFailed > 0 && ( + + + + + PDF Failed: {importResult.pdfFailed} + + )} +
+ )}
+ {/* Skipped 상세 */} + {importResult.skipped > 0 && importResult.skipDetails && importResult.skipDetails.length > 0 && ( +
+

Skipped:

+
+ {importResult.skipDetails.map((s, idx) => ( +
+ {s.car_name || s.car_no} + + {s.reason === 'already exists' ? `Already imported (ID: ${s.car_id})` : s.reason} + +
+ ))} +
+
+ )} + + {/* Error 상세 */} + {importResult.errors > 0 && importResult.errorDetails && importResult.errorDetails.length > 0 && ( +
+

Errors:

+
+ {importResult.errorDetails.map((e, idx) => ( +
+ {e.car_no} + {e.error} +
+ ))} +
+
+ )} + {/* PDF 실패 상세 정보 */} {importResult.pdfFailed > 0 && importResult.pdfDetails && ( -
-

- PDF 생성 실패 차량 (3회 재시도 완료): +
+

+ PDF Failed (3 retries attempted):

-
+
{importResult.pdfDetails .filter(d => !d.success) .map((detail, idx) => ( -
+
[{detail.car_id}] {detail.car_name} - {detail.attempts}회 시도 - {detail.error || 'Unknown error'} + {detail.attempts} attempts - {detail.error || 'Unknown error'}
))}
-

- ⚠️ Local Cars 탭에서 해당 차량의 "PDF" 버튼을 클릭하여 수동으로 재시도할 수 있습니다. +

+ Retry from Local Cars tab using the "PDF" button.

)} @@ -2391,6 +2447,11 @@ export default function CarsAdminPage() { )} + {importing && ( +
+ Duplicate check → Images → Description → Translation → PDF → Specs +
+ )}