feat(flyer-import): add session management and retrieval endpoints
Test Suite / backend-pr-quick (push) Has been skipped
Test Suite / quick-import-pr-quick (push) Has been skipped
Test Suite / backend-full (push) Successful in 2m15s
Test Suite / flutter-quality (push) Failing after 1m25s

- Add new API endpoints for retrieving flyer import sessions:
  - GET /flyer-import/sessions/latest - Retrieve latest session for user
  - GET /flyer-import/sessions/:sessionId - Retrieve specific session
- Implement session persistence and restoration in Flutter UI
- Add toJson() methods to FlyerImportItem and FlyerImportResult for serialization
- Add new FlyerImportSession domain model for local session management
- Add unit test file for FlyerImportService
- Update FlyerImportController with new endpoints and user ID extraction
- Update FlyerImportService with session retrieval logic and response mapping
- Update API paths in Flutter client
- Add session restoration on widget init in FlyerImportTab
This commit is contained in:
Nils-Johan Gynther
2026-05-19 21:55:55 +02:00
parent 8b8f8b7b6f
commit 6cd5b80adb
10 changed files with 649 additions and 30 deletions
@@ -37,7 +37,7 @@ class FlyerImportItem {
this.matchConfidence,
});
factory FlyerImportItem.fromJson(Map<String, dynamic> json) {
factory FlyerImportItem.fromJson(Map<String, dynamic> json) {
return FlyerImportItem(
flyerItemId: (json['flyerItemId'] as num?)?.toInt(),
rawName: json['rawName'] as String? ?? '',
@@ -56,6 +56,28 @@ class FlyerImportItem {
matchedProductName: json['matchedProductName'] as String?,
matchedVia: json['matchedVia'] as String?,
matchConfidence: (json['matchConfidence'] as num?)?.toDouble(),
);
}
}
);
}
Map<String, dynamic> toJson() {
return {
'flyerItemId': flyerItemId,
'rawName': rawName,
'normalizedName': normalizedName,
'category': category,
'price': price,
'priceUnit': priceUnit,
'offerText': offerText,
'isOffer': isOffer,
'offerLimitText': offerLimitText,
'comparisonPrice': comparisonPrice,
'comparisonUnit': comparisonUnit,
'parseConfidence': parseConfidence,
'parseReasons': parseReasons,
'matchedProductId': matchedProductId,
'matchedProductName': matchedProductName,
'matchedVia': matchedVia,
'matchConfidence': matchConfidence,
};
}
}
@@ -26,4 +26,12 @@ class FlyerImportResult {
warnings: warnings,
);
}
Map<String, dynamic> toJson() {
return {
'sessionId': sessionId,
'items': items.map((item) => item.toJson()).toList(),
'warnings': warnings,
};
}
}