diff --git a/docs/plans/2026-05-07-scanner-to-api-design.md b/docs/plans/2026-05-07-scanner-to-api-design.md new file mode 100644 index 0000000..dd1cd1a --- /dev/null +++ b/docs/plans/2026-05-07-scanner-to-api-design.md @@ -0,0 +1,109 @@ +# PAD Scanner to API - Design + +## Goal + +Build a Flutter app on the D500 PAD scanner device that captures scanned barcodes and sends the data to a configurable HTTP endpoint via POST request. This is a proof-of-concept to validate the end-to-end data pipeline. + +## Architecture + +``` +D500 Scanner Hardware + │ + ▼ +Device Scan Service (system broadcast) + action: com.android.server.scannerservice.broadcast + key: scannerdata + │ + ▼ +Flutter App + BroadcastReceiver (Android native) + │ + ▼ + EventChannel → Dart stream + │ + ▼ + HTTP POST to user-configured URL + │ + ▼ +User's backend (Postman / custom server) +``` + +## App Pages + +### Main Page (Scan Records) + +- Real-time status indicator (waiting for scan / sending / sent / failed) +- List of scanned barcode records, each showing: + - Barcode content + - Barcode type (CODE128, QR, etc.) + - Timestamp + - Send status (pending / success / failed) +- AppBar with settings gear icon + +### Settings Page + +- URL input field (e.g. `http://192.168.1.100:8000/scan`) +- Save button +- Test connection button (sends a test request) + +## HTTP Request Format + +``` +POST {user-configured-url} +Content-Type: application/json + +{ + "barcode": "scanned content", + "code_type": "CODE128", + "timestamp": "2026-05-07T10:30:00Z" +} +``` + +Expected response: any 2xx status code = success. + +## Technical Implementation + +### Scanner Data Capture + +- Register an Android `BroadcastReceiver` in `MainActivity.kt` to listen for `com.android.server.scannerservice.broadcast` +- Forward scanned data to Flutter via `EventChannel` as a stream +- BroadcastReceiver registration: dynamic (in code), not static (in manifest) - register on resume, unregister on pause + +### HTTP Client + +- Dart `http` package for POST requests +- Async fire-and-forget on each scan result +- Store failed requests in local list for retry display + +### URL Persistence + +- `shared_preferences` package to save/load the configured endpoint URL +- Default value: empty (user must configure before scanning) + +### Dependencies + +```yaml +dependencies: + http: ^1.2.0 + shared_preferences: ^2.2.0 +``` + +## File Changes + +| File | Action | +|------|--------| +| `lib/main.dart` | Rewrite - app entry with routing | +| `lib/pages/scan_page.dart` | New - main scan records page | +| `lib/pages/settings_page.dart` | New - URL configuration page | +| `lib/services/scanner_service.dart` | New - EventChannel wrapper for scanner | +| `lib/services/api_service.dart` | New - HTTP POST client | +| `lib/models/scan_record.dart` | New - scan record data model | +| `android/app/src/main/kotlin/.../MainActivity.kt` | Modify - add BroadcastReceiver + EventChannel | +| `pubspec.yaml` | Modify - add dependencies | + +## Out of Scope + +- FastAPI backend implementation (user handles separately) +- Database persistence in app +- Authentication / encryption +- Offline queue / retry mechanism