mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-07 04:12:04 +00:00
fix(labs): preview a CSV text row with the window the write keeps
The dry run showed the printed range beside a text result, which the write stores on the new marker and not on the reading. The preview and the write now read the reading's window from one helper, and the placeholder marker of a dry run takes its bounds through the same rule as a real mint.
This commit is contained in:
1 parent
c7b3f6e4d0
commit
126bab8c00
2 files changed
+45
-7
No files matched your search
@@ -39,6 +39,7 @@ import {
|
||||
type MarkerIndex,
|
||||
} from "@/lib/labs/biomarker-resolve";
|
||||
import { resolveOrMintBiomarker } from "@/lib/labs/biomarker-store";
|
||||
import { mintedBounds } from "@/lib/labs/minted-bounds";
|
||||
import { parseReferenceRange } from "@/lib/labs/parse-reference-range";
|
||||
import { readingInMarkerUnit } from "@/lib/labs/reading-conversion";
|
||||
import {
|
||||
@@ -255,7 +256,21 @@ interface Planned {
|
||||
marker: IndexedMarker | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The window the write keeps on the reading: the printed one for a number, none
|
||||
* for a text result (its range seeds a new marker, not the reading).
|
||||
*/
|
||||
function readingWindow(row: LabCsvRow): {
|
||||
low: number | null;
|
||||
high: number | null;
|
||||
} {
|
||||
return row.valueText === null
|
||||
? { low: row.sourceReferenceLow, high: row.sourceReferenceHigh }
|
||||
: { low: null, high: null };
|
||||
}
|
||||
|
||||
function displayRow(row: LabCsvRow, marker: string) {
|
||||
const window = readingWindow(row);
|
||||
return {
|
||||
line: row.line,
|
||||
marker,
|
||||
@@ -263,8 +278,8 @@ function displayRow(row: LabCsvRow, marker: string) {
|
||||
valueText: row.valueText,
|
||||
unit: row.unit,
|
||||
takenAt: row.takenAt.toISOString(),
|
||||
referenceLow: row.sourceReferenceLow,
|
||||
referenceHigh: row.sourceReferenceHigh,
|
||||
referenceLow: window.low,
|
||||
referenceHigh: window.high,
|
||||
panel: row.panel,
|
||||
note: row.note !== null,
|
||||
};
|
||||
@@ -346,8 +361,7 @@ export async function importLabsCsv(args: {
|
||||
id: `pending:${pendingId++}`,
|
||||
name: row.analyte,
|
||||
unit,
|
||||
lowerBound: row.sourceReferenceLow,
|
||||
upperBound: row.sourceReferenceHigh,
|
||||
...mintedBounds(row.sourceReferenceLow, row.sourceReferenceHigh),
|
||||
panel: row.panel,
|
||||
analyteKey: matchAnalyteKey({ name: row.analyte, unit }),
|
||||
hidden: false,
|
||||
@@ -484,8 +498,7 @@ export async function importLabsCsv(args: {
|
||||
if (!marker) created.add(row.analyte);
|
||||
|
||||
let storedValue = row.value;
|
||||
let storedLow = row.valueText === null ? row.sourceReferenceLow : null;
|
||||
let storedHigh = row.valueText === null ? row.sourceReferenceHigh : null;
|
||||
let { low: storedLow, high: storedHigh } = readingWindow(row);
|
||||
let convertedFrom: { sourceValue: number; sourceUnit: string } | null =
|
||||
null;
|
||||
if (row.value !== null) {
|
||||
|
||||
@@ -368,15 +368,40 @@ describe("a text marker's range and the first unit it adopts", () => {
|
||||
// --- CSV import -------------------------------------------------------------
|
||||
|
||||
describe("a CSV text result", () => {
|
||||
const query = () =>
|
||||
const query = (dryRun = false) =>
|
||||
labsCsvQuerySchema.parse({
|
||||
analyte: "0",
|
||||
value: "1",
|
||||
unit: "2",
|
||||
date: "3",
|
||||
referenceRange: "4",
|
||||
dryRun: dryRun ? "1" : "0",
|
||||
});
|
||||
|
||||
it("previews a text row the way it writes it", async () => {
|
||||
const csv = [
|
||||
"Analyte;Value;Unit;Date;Range",
|
||||
"BUN/Creatinine ratio;SEE NOTE;;2026-09-01;10 - 20",
|
||||
"Sodium;140;mmol/L;2026-09-01;135 - 145",
|
||||
].join("\n");
|
||||
const preview = await importLabsCsv({
|
||||
userId: USER,
|
||||
tz: "UTC",
|
||||
stream: textToStream(csv),
|
||||
maxBytes: 1_000_000,
|
||||
query: query(true),
|
||||
});
|
||||
// The text reading stores no window of its own; the number keeps its.
|
||||
expect(preview.preview).toMatchObject([
|
||||
{
|
||||
marker: "BUN/Creatinine ratio",
|
||||
referenceLow: null,
|
||||
referenceHigh: null,
|
||||
},
|
||||
{ marker: "Sodium", referenceLow: 135, referenceHigh: 145 },
|
||||
]);
|
||||
});
|
||||
|
||||
it("gives a new marker a numeric range and leaves a text range out", async () => {
|
||||
const result = await importLabsCsv({
|
||||
userId: USER,
|
||||
|
||||
Reference in new issue
Block a user