Bug Report
File: frontend/health-chain/lib/api/batch-import.api.ts
Problem
stageImport() bypasses the shared http-client and constructs its own fetch call with manual token retrieval:
const res = await fetch(`${base}/${PREFIX}/batch-import/stage?entityType=${entityType}`, {
method: 'POST',
headers: token ? { Authorization: `Bearer ${token}` } : {},
body: form,
});
The shared http-client handles:
- Automatic 401 detection and token refresh
- Consistent error serialisation
- Request retry on transient failures
None of these apply to this raw fetch call.
Impact
- If the user's token expires mid-upload, the request fails with a 401 and the user must re-upload the file manually — no silent retry or refresh occurs
- If
token is null (logged-out state), the request proceeds with no Authorization header and gets a 401 with no useful error message shown
- Error handling diverges from the rest of the app — the UI may show a raw HTTP error string instead of the standard error toast
Fix
Extend the http-client to support FormData / multipart uploads, then use it:
export async function stageImport(file: File, entityType: ImportEntityType) {
const form = new FormData();
form.append('file', file);
return api.post(`/${PREFIX}/batch-import/stage?entityType=${entityType}`, form);
}
Bug Report
File:
frontend/health-chain/lib/api/batch-import.api.tsProblem
stageImport()bypasses the sharedhttp-clientand constructs its ownfetchcall with manual token retrieval:The shared
http-clienthandles:None of these apply to this raw
fetchcall.Impact
tokenisnull(logged-out state), the request proceeds with noAuthorizationheader and gets a 401 with no useful error message shownFix
Extend the
http-clientto supportFormData/ multipart uploads, then use it: