feat(app): scan-mode sync, confirmation-gated documents, single-pass product classification
Fixes reported from APK field testing: DO/Product scan mode was inconsistent between the camera drawer and documents screen (now one shared provider, with an orange/green color cue); unconfirmed scans leaked into history with placeholder data before the user tapped confirm (backend now gates GET /documents on a new `confirmed` column, flipped only by PUT); and Product Scan ran the GPU classifier twice, once at upload and again on review (now a single pass at upload, persisted and read directly by the editor). Also removes the unused "Hubungkan ke PO" field and fabricated PO/SO/DO placeholder values from the Product Scan flow, closes out the per-document-polling and save-recovery tasks (6.1/6.3), and splits several touched files to stay under the repo's 256-line guideline. Full detail in docs/iteration-log.md and backend/docs/iteration-log.md. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
2febe0c886
commit
ada6488592
67 files changed
+5705
-1142
No files matched your search
@@ -0,0 +1,39 @@
|
||||
import '../../models/document_model.dart';
|
||||
|
||||
enum PollOutcomeKind { done, failed, pending }
|
||||
|
||||
/// Result of inspecting a single `GET /documents/:id` poll response.
|
||||
/// Deliberately separated from the Dio call site
|
||||
/// (`pending_documents_provider.dart`'s `_pollUntilParsed`) so the
|
||||
/// parse-status branching is unit-testable without mocking network I/O -
|
||||
/// mirrors the pure-function pattern already used for `document_sync_merge.dart`
|
||||
/// (task 6.2) and `product_scan_response_parser.dart` (task 7.1).
|
||||
class PollOutcome {
|
||||
final PollOutcomeKind kind;
|
||||
final DocumentModel? document;
|
||||
final String? message;
|
||||
|
||||
const PollOutcome._(this.kind, {this.document, this.message});
|
||||
|
||||
factory PollOutcome.done(DocumentModel document) =>
|
||||
PollOutcome._(PollOutcomeKind.done, document: document);
|
||||
|
||||
factory PollOutcome.failed(String message) =>
|
||||
PollOutcome._(PollOutcomeKind.failed, message: message);
|
||||
|
||||
static const PollOutcome pending = PollOutcome._(PollOutcomeKind.pending);
|
||||
}
|
||||
|
||||
/// `parseStatus` absent/unrecognized (a legacy/cached response predating
|
||||
/// backend task 9.1) is treated the same as `"pending"` - keep polling rather
|
||||
/// than surface a false failure.
|
||||
PollOutcome resolvePollOutcome(DocumentModel fetched) {
|
||||
switch (fetched.parseStatus) {
|
||||
case 'done':
|
||||
return PollOutcome.done(fetched);
|
||||
case 'failed':
|
||||
return PollOutcome.failed('Gagal mengekstrak data (parsing gagal di server).');
|
||||
default:
|
||||
return PollOutcome.pending;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user