# Story 3.3: Import Job Status & Error Review UI

## Story

**As a** system administrator,
**I want** to see the live status of an import job and review any row-level errors in detail,
**So that** I can confirm what was imported successfully and diagnose exactly what failed.

## Status

done

## Acceptance Criteria

All ACs met.

## Tasks / Subtasks

- [x] **Task 1: `statusApi(int $id)` endpoint** (AC: 2)
  - [x] `GET /api/import-jobs/{id}/status` → JSON `{success, data: {status, total_rows, processed_rows, success_rows, error_rows}}`. 401 if unauthenticated, 404 if not found.
  - [x] Wired in `public/index.php` with inline auth check.

- [x] **Task 2: Enhance `show()` controller** (AC: 3, 4, 5)
  - [x] Fetches paginated error rows (25/page, `?err_page=N`) from `import_job_errors` only when `error_rows > 0`.
  - [x] Passes `$errorRows`, `$totalErrors`, `$errorPages`, `$errPage` to view.

- [x] **Task 3: Rewrite `show.php` view** (AC: 1, 3, 4, 5, 6)
  - [x] Summary `<dl>` with all job fields including computed duration (started_at → completed_at diff).
  - [x] Success banner (N products imported) and amber warning banner (N rows could not be imported) for terminal states.
  - [x] Red error banner for job-level `error_message` on failed jobs.
  - [x] Error table: Row #, Field, Reason, Original Value (truncated to 100 chars with `title` tooltip for full value). Paginated with Previous/Next links.
  - [x] Polling indicator card shown for non-terminal jobs; JS injected via `window.__importJobId`.

- [x] **Task 4: `public/assets/js/import-job-show.js`** (AC: 1)
  - [x] Polls `/api/import-jobs/{id}/status` every 5 seconds. Updates status badge, processed/success/error counts, progress percentage in-place. On terminal status: `window.location.reload()` to render the full server-side terminal view (error table, banners, duration). 500ms initial delay.

- [x] **Task 5: Index page live badge update** (AC: 6)
  - [x] `index.php` emits inline JS if any active jobs (`pending`/`processing`) exist. Polls every 10 seconds per job via `pollOne(id)`. Stops polling a job once it reaches terminal status (`clearInterval` when `activeIds` is empty). Uses `data-job-id` attribute on `<tr>` for DOM targeting.

## Dev Notes

### Terminal state reload strategy

When the show-page JS detects a terminal status, it calls `window.location.reload()` rather than trying to DOM-update the terminal view. This is simpler and more correct: the terminal view includes server-rendered elements (error table, duration, banners) that can't be reconstructed from the status API response alone.

### File list

**New files:** `public/assets/js/import-job-show.js`  
**Modified files:** `src/Controllers/ImportJobController.php` (statusApi, enhanced show), `src/Views/import-jobs/show.php` (full rewrite), `src/Views/import-jobs/index.php` (polling JS), `public/index.php` (API route)
