# PFM OCR App — Quality Engineering & Verification Plan > Auto-managed by Quality Engineering (QE) guidelines. Do not edit task status manually. > Legend: [TODO] = pending | [IN_PROGRESS] = active | [DONE] = completed --- ## Section 0: QA Configuration & Permissions Layer [QE] > Verification of OS-level permissions and system dependencies before application execution. - 0.1 [DONE] **Android Permission Verification**: Enforce access permissions in `AndroidManifest.xml` (location, camera, internet). - Verify `ACCESS_FINE_LOCATION` and `ACCESS_COARSE_LOCATION` are present. - Verify `CAMERA` and `INTERNET` are declared under `` root. - 0.2 [DONE] **iOS Permission Verification**: Enforce privacy descriptors in `Info.plist`. - Verify `NSLocationWhenInUseUsageDescription` and `NSLocationAlwaysUsageDescription` are configured with user-facing Indonesian text. - 0.3 [DONE] **Linting & Code Integrity Check**: Enforce standard Flutter rules. - No compilation warnings or unused imports in the `lib/` directory. - Deprecated UI properties like `.withOpacity` replaced with `.withValues()` to ensure UI rendering performance. --- ## Section 1: Authentication & Splash [Splash/Login] > Enforce validation and session security checks. - 1.1 [DONE] **Splash Transition**: Verify user session detection. - If token exists and is valid, auto-navigate to `/camera`. - If token does not exist, navigate to `/login`. - 1.2 [DONE] **Login Field Validation**: Ensure strict client-side verification. - Empty username or password triggers inline validation warning. - Password minimum requirement of 6 characters enforced on the input field. - 1.3 [DONE] **Login API & State Integrity**: - Valid credentials store the JWT token securely using Hive/SharedPreferences. - API errors (e.g., 401 Unauthorized, 403 Forbidden) render a red error banner without crashing the application. - Loading indicator overlay blocks user interaction during submission. --- ## Section 2: Camera Capture & Geotagging [Camera] > Enforce IMU stillness limits and immediate coordinate capture. - 2.1 [DONE] **Stillness Thresholds Check**: Verify IMU stillness analyzer in `camera_screen.dart`. - Linear acceleration limit of `0.3 m/s^2` lock/unlock shutter verified. - Angular rotation limit of `0.15 rad/s` tilts lock/unlock shutter verified. - Warning banner "Tahan posisi HP Anda agar tetap tenang!" displays instantly when motion limits are exceeded. - 2.2 [DONE] **Geotagging Capture (Camera)**: Verify GPS coordination retrieval during image capture. - Calling `LocationService.determinePosition()` begins in parallel with image save. - UI displays "Sedang menangkap gambar & lokasi..." overlay. - Location failure (timeout, permissions denied) falls back gracefully without breaking the camera screen transition. - 2.3 [DONE] **Geotagging Capture (Gallery)**: Verify location retrieval when selecting an image. - Selecting an image from the gallery triggers the location API. - Passes coordinates successfully to the image preview screen. --- ## Section 3: Blur Detection & Preview [Preview] > Enforce image sharpness limits and coordinates mapping. - 3.1 [DONE] **Sharpness Threshold Audit**: - Sharpness score below 80.0 displays a red "Foto Terdeteksi Blur!" badge. - Sharpness score of 80.0 and above displays a green "Kualitas Foto Baik" badge. - 3.2 [DONE] **Action Control Routing**: - Clicking "Ambil Ulang" pops the screen and returns to the active camera controller. - Clicking "Unggah Dokumen" is disabled when sharpness score is below the threshold. - Successful confirmation dispatches `addDocument` with `latitude` and `longitude` fields populated. --- ## Section 4: Pending Queue & Synchronization [List] > Enforce queue integrity, retry state preservation, and metadata filtering. - 4.1 [DONE] **Queue State Rendering**: - `uploading` and `processing` states display a progress bar. - `success` state displays a green checkmark and enables the `/editor` navigation list row. - `error` state displays a red error icon and the error string. - 4.2 [DONE] **Context Menu Actions**: - "Delete Document" removes the file and item from memory list state. - "Retry Upload" preserves the original GPS coordinate values (`latitude`, `longitude`) from capture instead of clearing them. - 4.3 [DONE] **Search Filter Matching**: - Search bar query matches: No DO, No PO, No SO, Tanggal, or Customer name (case-insensitive). - 4.4 [DONE] **Confirmed Documents Cards**: - Renders coordinates with `toStringAsFixed(4)` decimals. - "Print Receipt" prints a PDF containing correct details (Items, header metadata, coordinates). --- ## Section 5: Document Editor & Verification [Editor] > Enforce strict metadata structure validation and data synchronization. - 5.1 [DONE] **Header Field Constraints**: - Date picker formats value as `dd MMMM yyyy`. - PO number validates against format `PO/26/\d{10}`. - SO number validates as digits-only with a length of exactly 10. - 5.2 [DONE] **Item Details CRUD & Master SKU**: - Adding a new item allows typing a SKU. - SKU validation checks against `MasterSku` data registry. Matches display the correct product name; non-matches display "SKU Tidak Terdaftar" and raise a validation error. - 5.3 [DONE] **Signature & Submission**: - "Review Complete" triggers the bottom sheet modal. - Bottom sheet requires recipient's name (non-empty) and the agreement checkbox to be checked. - "Confirm" saves the model locally to Hive and issues a `PUT /api/v1/documents/:id` request to the server with coordinates. --- ## Section 6: Backend API contracts [Backend] > Verify route schema validation, file handling, and DB storage integrity. - 6.1 [DONE] **POST /api/v1/documents/upload**: - Multipart request parses `image` file and populates body fields `latitude` and `longitude`. - Returns `201 Created` with mapped schema containing parsed coordinates as floats. - 6.2 [DONE] **PUT /api/v1/documents/:id**: - Parses body coordinates and items array. - Updates DB record and deletes old cascade items. - Returns updated entity payload. - 6.3 [DONE] **Auth Middleware Cleanup**: - Unauthorized uploads clean up the multer temporary disk storage before sending responses.