## 1. Error file service

- [x] 1.1 Create the `EmployeeImportErrorFile` service with `build(UploadedFile $file, array $errors, array $titleToKey, Account $account, string $companyMode): ?string` (returns the uuid) and `find(string $uuid): ?array` (metadata, or null when it is missing or older than 24 hours)
- [x] 1.2 Load the upload with the right reader. For CSV, use the same delimiter and encoding settings as the importer and a `StringValueBinder` so leading zeros are kept
- [x] 1.3 Remove the rows of sheet 0 that are not in `errors[].row`, from the bottom up, keeping header row 1
- [x] 1.4 Build the header map (slugged key → column) and add "Dòng gốc" and "Lý do lỗi" after the last header, or reuse them when they already exist
- [x] 1.5 Set the "Mã NV" and "SĐT" columns to text format and rewrite their values as explicit strings
- [x] 1.6 Write "Dòng gốc" and "Lý do lỗi" (messages joined with `\n`, wrap text), fill "Lý do lỗi" and the matched reason cells with `#FDE2E1`, and add comments with the messages
- [x] 1.7 Save as `.xlsx` with JSON metadata (`account_id`, `company_mode`, `created_at`, `download_name`) under `storage/app/employee-import-errors/`

## 2. Import integration

- [x] 2.1 In `EmployeeController::import`, call the service after the loop when `errors` is not empty, inside a try/catch that logs failures, and add `error_file_url` (or `null`) to the response
- [x] 2.2 Exclude `dong_goc` and `ly_do_loi` from the blank-row check
- [x] 2.3 Update the OpenAPI annotation of `import` with `error_file_url`

## 3. Download endpoint

- [x] 3.1 Add the route `GET /admin/employees/import-errors/{id}` before the `apiResource` route
- [x] 3.2 Implement `EmployeeController::downloadImportErrors`: 404 when the file is missing or expired, allow the owner, otherwise require `employees_info` and `canAccessCompany(meta.company_mode)`, else 403. Return the file with its `download_name`
- [x] 3.3 Add the OpenAPI annotation for the endpoint

## 4. Cleanup

- [x] 4.1 Add a daily schedule in `app/Console/Kernel.php` that deletes error files and metadata older than 24 hours

## 5. Tests

- [x] 5.1 3-row file (row 2 duplicate code, row 3 valid): the file has the header and 1 row, the "Mã NV" cell is filled, "Dòng gốc" = 2, "Lý do lỗi" = "Mã NV đã tồn tại"
- [x] 5.2 A row with 4 reasons: 4 cells filled, and "Lý do lỗi" has 4 lines
- [x] 5.3 An `unknown_error` row (force an exception): no data cell filled, and "Lý do lỗi" = "Lỗi không xác định"
- [x] 5.4 "Mã NV" `00123` (text cell) stays `00123`, and a CSV upload produces a valid `.xlsx`
- [x] 5.5 Import with no errors: `error_file_url` is null
- [x] 5.6 Download: 401 without auth, 200 for the owner, 403 for an admin without access to the company, 404 after expiry (set `created_at` in the metadata to 25 hours ago)
- [x] 5.7 Re-import a fixed error file: the rows are created and the annotation columns cause no error. A row with only annotation values is skipped
- [x] 5.8 Cleanup removes files older than 24 hours and keeps newer ones
