feat(ocr): Fuzzy-Match aus Shopping-History — Hauptpfad #415 #418

Merged
admin-mrrm merged 3 commits from feat/415-fuzzy-match-parseitems into main 2026-05-28 12:53:19 +02:00
Collaborator

Summary

  • Server-seitiger Fuzzy-Match (Levenshtein + DE-Normalisierung ä/ö/ü/ß, case-fold)
  • OcrService.parseItems(text, history?) liefert optional suggestions[] pro Item
  • ListsService.getShoppingHistoryTitles(ownerSub) als Dictionary-Source (distinct titles aus eigenen Shopping-Lists)
  • ReviewScreen (mobile + web) zeigt "Meintest du X?"-Chip mit 1-Tap-Übernahme, dismissbar
  • api-client Response-Schema rückwärtskompatibel um optionales suggestions[] erweitert

Ersatzfeature für die nach #82-Pivot verworfene on-device-OCR-Strategie — Vorschläge kommen jetzt server-seitig aus dem eigenen Kauf-Verlauf statt aus einer auf-Gerät-DB.

Fixes #415

Test plan

  • pnpm --filter @mrrmlab/api test (440 grün, +13 neue)
  • pnpm typecheck für api, api-client, feature-shopping-list, mobile, web
  • Manuell: Bild mit Tippfehler hochladen → Suggestion-Chip erscheint → Tap übernimmt
  • Manuell: Bild ohne History-Treffer → keine Chip, kein Crash
## Summary - Server-seitiger Fuzzy-Match (Levenshtein + DE-Normalisierung ä/ö/ü/ß, case-fold) - `OcrService.parseItems(text, history?)` liefert optional `suggestions[]` pro Item - `ListsService.getShoppingHistoryTitles(ownerSub)` als Dictionary-Source (distinct titles aus eigenen Shopping-Lists) - ReviewScreen (mobile + web) zeigt "Meintest du X?"-Chip mit 1-Tap-Übernahme, dismissbar - api-client Response-Schema rückwärtskompatibel um optionales `suggestions[]` erweitert Ersatzfeature für die nach #82-Pivot verworfene on-device-OCR-Strategie — Vorschläge kommen jetzt server-seitig aus dem eigenen Kauf-Verlauf statt aus einer auf-Gerät-DB. Fixes #415 ## Test plan - [x] `pnpm --filter @mrrmlab/api test` (440 grün, +13 neue) - [x] `pnpm typecheck` für api, api-client, feature-shopping-list, mobile, web - [ ] Manuell: Bild mit Tippfehler hochladen → Suggestion-Chip erscheint → Tap übernimmt - [ ] Manuell: Bild ohne History-Treffer → keine Chip, kein Crash
Server-seitiger Fuzzy-Match auf OCR-Output gegen die historischen
Shopping-List-Items des Nutzers. Garbage-OCR ('Milh') liefert jetzt
Vorschläge ('Milch') statt Müll-Items.

- fuzzy-match.ts: pure Levenshtein-Funktion + DE-Normalisierung
  (ä/ö/ü/ß → ae/oe/ue/ss, case-fold), default threshold 0.7
- OcrService.parseItems(text, history?) gibt optional suggestions
- ListsService.getShoppingHistoryTitles(ownerSub) zieht distinct
  titles aus list_items joined mit lists.type='shopping'
- Controller lädt History pro parse-image-Request, übergibt an OCR
- api-client Response-Schema um optionales suggestions[] erweitert
  (backward-compatible — alte Clients ignorieren das Feld)
feat(review): Suggestion-Chip in ReviewScreen (#415)
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
7434621d62
Wenn die API zum erkannten Artikel einen Fuzzy-Match-Vorschlag liefert,
zeigt der Review-Screen unter der Zeile eine "Meintest du …?"-Chip mit
1-Tap-Übernahme. Klein gehalten: nur Top-1-Vorschlag, dismissbar,
nicht-blockierend. Mobile + Web teilen denselben Komponentenbaum.
Merge branch 'main' into feat/415-fuzzy-match-parseitems
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is passing
7b13f20349
admin-mrrm deleted branch feat/415-fuzzy-match-parseitems 2026-05-28 12:53:19 +02:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
admin-mrrm/mrrmlabapp!418
No description provided.