From 7c06516e1e387998620fd0fd0959453b159f8cba Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 18 Aug 2026 19:19:04 +0000 Subject: [PATCH] =?UTF-8?q?fix(skann):=20finetune=20dubblett=20=E2=80=93?= =?UTF-8?q?=20ta=20aldrig=20bort=20automatiskt,=20jamfor=20ej=20inom=20sam?= =?UTF-8?q?ma=20foto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Johans test visade tva falska positiva: 3:e smetana pa annan hylla forsvann, och 2 olika gradde i EN bild -> bara en rakna, andra bortrensad. Orsak: (1) auto-avmarkering tog bort riktiga varor, (2) varor jamfordes mot varandra inom samma foto. Fix: markera men ta ALDRIG bort automatiskt (rejected=false, du valjer); jamfor bara inom samma skanning nar det finns FLERA foton (overlapp), aldrig tva behallare i ett och samma foto. Verifierat mot alla tre fallen. --- apps/api/src/routes/scans.ts | 8 ++++++-- apps/mobile/src/app/scan-review/[jobId].tsx | 5 +++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/apps/api/src/routes/scans.ts b/apps/api/src/routes/scans.ts index e85489e..59b7b37 100644 --- a/apps/api/src/routes/scans.ts +++ b/apps/api/src/routes/scans.ts @@ -338,6 +338,10 @@ async function annotateScanDuplicates( const source = scanSource(job.scanType); const now = new Date().toISOString(); + // Jämför bara mot TIDIGARE bilder i samma skanning när det finns FLERA foton + // (överlappande vinklar). I ett enda foto är två liknande behållare oftast + // två riktiga varor – flagga dem aldrig mot varandra. + const multiImage = (job.s3Keys?.length ?? 0) > 1; const seen: typeof existing = []; const items = result.items.map((it, idx) => { @@ -349,9 +353,9 @@ async function annotateScanDuplicates( source, createdAt: now, }; - const pool = [...existing, ...seen]; + const pool = multiImage ? [...existing, ...seen] : existing; const [top] = findDuplicateCandidates(input, pool); - seen.push({ id: String(it.tempId ?? idx), ...input }); + if (multiImage) seen.push({ id: String(it.tempId ?? idx), ...input }); if (!top) return { ...it, possibleDuplicate: null }; const match = pool.find((p) => p.id === top.itemId); return { diff --git a/apps/mobile/src/app/scan-review/[jobId].tsx b/apps/mobile/src/app/scan-review/[jobId].tsx index 3c810ff..d9cd726 100644 --- a/apps/mobile/src/app/scan-review/[jobId].tsx +++ b/apps/mobile/src/app/scan-review/[jobId].tsx @@ -106,8 +106,9 @@ export default function ScanReviewScreen() { dateIsUseBy: false, confidence: item.confidence, duplicate: item.possibleDuplicate ?? null, - // Hög säkerhet på dubblett → avmarkerad som standard (syns tydligt + går att ångra). - rejected: (item.possibleDuplicate?.score ?? 0) >= 0.7, + // Markera möjlig dubblett men ta ALDRIG bort automatiskt – två av samma + // vara, eller en till på en annan hylla, är ofta helt riktigt. Du väljer. + rejected: false, })), ); }