# Import operator guide

## Review a staged file

Choose the supplier identifier before staging. It is part of the item identity and cannot be changed after staging. Choose the monetary format explicitly. Download the original CSV from the review if you need to compare it with the supplier's submission.

The review shows added, changed, unchanged and missing records. Every changed record has its old and new values. Missing records are informational and remain in the catalog. A rejected row blocks the whole batch; there is no partial-accept control. The error list includes CSV row numbers and reasons.

Use the JSON report to retain the full review, source digest, mapping version, catalog versions and audit entries. The report is not a signed approval certificate.

## Correct the rejected example

`fixtures/rejected.csv` uses `brg-10` and `BRG-10`; normalization gives both the same key. Remove the duplicate after deciding which record the supplier intended. Replace the unsupported unit with an explicit supported unit, and correct the invalid price. Do not silently select one duplicate row. Stage the corrected file as a new batch and inspect the diff before approval.

## When another import has committed

Approval fails with HTTP 409 if the supplier catalog version changed after this review. Click Refresh review, inspect the recalculated changes, then approve. Refresh changes the review digest; the earlier approval request remains invalid. It is expected that unrelated changes in the same supplier invalidate a review.

## Retry after a connection failure

Refresh the batch before uploading again. If it is applied, its version and audit entry show the result. If it is staged, retry the approval using the current review fields. Repeating a successful approval returns `replayed: true`; it does not increment the version again. Re-staging identical text for the same supplier and mapping selects the same batch.

If a database commit fails partway, SQLite rolls back items, catalog version, batch state and audit together. The test suite injects a failure after a row write and confirms this behavior.

## API examples

All API requests require a signed-in local session cookie. Mutating routes also require the `X-CSRF-Token` returned by `/api/login`. The browser interface handles these values.

| Route | Purpose |
| --- | --- |
| POST /api/login | Sign in with username and password |
| GET /api/summary | Supplier versions and latest 200 batches |
| GET /api/catalog?supplier=ACME&page=1&size=100 | Read a catalog page |
| POST /api/stage | Stage `{supplier, csv, locale}` |
| GET /api/batches/{id}?page=1&size=100 | Read a review page |
| POST /api/batches/{id}/refresh | Recompute review against current catalog |
| POST /api/batches/{id}/approve | Apply `{expected_version, review_digest}` |
| GET /api/batches/{id}/report | Download complete JSON review |
| GET /api/batches/{id}/source | Download original UTF-8 source |

The schema is deliberately narrow. Add a new mapping version and corresponding tests before changing parsing semantics. Restore from a complete stopped-service backup if the database is damaged; there is no automatic corruption repair.
