feat: edit parsed records before importing

The import preview only showed counts + skipped-row errors with no way to
fix anything. Now every parsed record is editable before import:

- backend: shared validatePatientImport() (used by the previewImport tool)
  + POST /api/ai/import/validate for dry-run re-validation; the import
  preview payload now carries the original records (and the source record on
  each invalid row) so the UI can edit them.
- frontend: the import card gets a "Review & edit" dialog listing every
  record with a ready / needs-fixing badge; opening one reuses the full
  PatientFormDialog in a new non-persisting review mode (editable file
  number) and re-validates on save, so skipped rows can be fixed and
  included.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Khalid Abdi
2026-06-18 21:03:33 +03:00
parent 064aa22099
commit f9615fa74e
8 changed files with 376 additions and 59 deletions
+25
View File
@@ -18,6 +18,7 @@ import {
saveAiConfig,
toAiConfig,
} from "../services/ai/config.js";
import { validatePatientImport } from "../services/ai/import.js";
import { getPolicy, savePolicy } from "../services/ai/policy.js";
import * as patients from "../services/patients.js";
@@ -189,3 +190,27 @@ aiRouter.post(
}
},
);
// --- Migration import re-validation (dry run) -------------------------------
// Powers the "review & edit before import" UI: the client edits parsed records
// and calls this to refresh which are ready vs. need fixing. Writes nothing.
aiRouter.post(
"/import/validate",
requireAuth,
requireOrg,
requirePermission({ patient: ["write"] }),
async (req, res, next) => {
try {
const records = (req.body as { records?: unknown[] }).records;
if (!Array.isArray(records)) {
throw new HttpError(400, "records must be an array.");
}
if (records.length > 500) {
throw new HttpError(400, "Too many records (max 500).");
}
res.json(validatePatientImport(records));
} catch (err) {
next(err);
}
},
);