f4bafc1c94
Add a second tab to the Upload page that surfaces the persisted batch
archive and lets the user re-download any 837P batch as a ZIP without
re-parsing the original file.
- Backend: /api/batches now carries per-row claimIds (837P only).
835 batches return an empty list, which the UI uses as the signal
to hide the Re-export button on those rows. Avoids an extra
round-trip to /api/batches/{id} per row.
- Frontend: BatchSummary.claimIds added to the list-endpoint type.
- Upload page: page body wrapped in Tabs.Root with a History trigger
that mirrors ?tab= in the URL for deep-link round-trip. The
History tab renders UploadHistory → HistoryTable → HistoryRow with
a one-click Re-export ZIP button per 837P row. The button calls
POST /api/batches/{id}/export-837 with the row's claim ids and
downloads the ZIP via downloadBlob. Falls back to the in-memory
parsedBatches store when the backend returns no rows so the tab
stays useful in sample-data mode.
- Backend tests: claimIds present on 837P rows, empty on 835 rows.
- Frontend tests: 13 tests covering tab switching, URL deep-link,
loading/error/empty states, the 837P-vs-835 button visibility
split, the Re-export happy path, and the failure toast.