feat: Implement document upload and verification workflow by expanding document statuses, adding verification metadata, and introducing a mandatory flag for documents.
This commit is contained in:
@@ -0,0 +1,68 @@
|
|||||||
|
# Document Upload & Verification Workflow
|
||||||
|
|
||||||
|
This document outlines the standardized workflow for handling file uploads, verification, and persistence within the Krow mobile application. This pattern is based on the `attire` module and should be used as a reference for the `certificates` module.
|
||||||
|
|
||||||
|
## 1. Overview
|
||||||
|
The workflow follows a 4-step lifecycle:
|
||||||
|
1. **Selection**: Picking or capturing a file (PDF/Image) locally.
|
||||||
|
2. **Preview**: Allowing the user to review the document/photo before submission.
|
||||||
|
3. **Upload & Verification**: Pushing the file to storage and initiating a background verification job.
|
||||||
|
4. **Persistence**: Saving the record with its verification status to the database.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Technical Stack
|
||||||
|
- **`FilePickerService`**: Handles PDF/File selection from the device.
|
||||||
|
- **`CameraService` / `GalleryService`**: Handles image capturing (if applicable).
|
||||||
|
- **`FileUploadService`**: Uploads raw files to our secure cloud storage.
|
||||||
|
- **`SignedUrlService`**: Generates secure internal/public links for viewing.
|
||||||
|
- **`VerificationService`**: Orchestrates the automated (AI) or manual verification of the document.
|
||||||
|
- **`DataConnect` (Firebase)**: Persists the structured data and verification metadata.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Implementation Steps
|
||||||
|
|
||||||
|
### A. UI Layer
|
||||||
|
1. **Selection**:
|
||||||
|
- Use `FilePickerService.pickFile(allowedExtensions: ['pdf'])`.
|
||||||
|
- Store the `localPath` in the widget state.
|
||||||
|
2. **Stateless Preview**:
|
||||||
|
- Provide an inline previewer (e.g., `PdfPreviewWidget`) so the user can verify the file contents.
|
||||||
|
3. **Submission**:
|
||||||
|
- Trigger a Cubit/Bloc event which calls the `UploadDocumentUseCase`.
|
||||||
|
- Show a global or inline progress indicator during the "Upload -> Verify -> Save" sequence.
|
||||||
|
|
||||||
|
### B. Domain Layer
|
||||||
|
1. **UseCase**:
|
||||||
|
- Manage the sequence of repository calls.
|
||||||
|
- Handle domain-specific validation (e.g., checking if the document is mandatory).
|
||||||
|
|
||||||
|
### C. Data Layer (The Repository Pattern)
|
||||||
|
The `Repository.uploadDocument` method should perform the following:
|
||||||
|
1. **Upload**: Call `FileUploadService` to get a `fileUri`.
|
||||||
|
2. **Link**: Call `SignedUrlService.createSignedUrl` to generate a `documentUrl`.
|
||||||
|
3. **Verify**: Call `VerificationService.createVerification` with the `fileUri` and relevant rules (e.g., `documentType`).
|
||||||
|
4. **Poll (Optional but Recommended)**: Poll the `VerificationService` for status updates for ~10 seconds to provide immediate feedback to the user.
|
||||||
|
5. **Persist**: Call Data Connect's `upsertStaffDocument` mutation with:
|
||||||
|
- `documentId`
|
||||||
|
- `documentUrl`
|
||||||
|
- `verificationId`
|
||||||
|
- `verificationStatus` (e.g., `PENDING` or `APPROVED`)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. State Management (Cubit/Bloc)
|
||||||
|
- **`status`**: Track `loading`, `uploading`, `success`, and `failure`.
|
||||||
|
- **`errorMessage`**: Store localized error keys from `BlocErrorHandler`.
|
||||||
|
- **`verificationId`**: Store the ID returned from the server to allow later manual refreshes.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Metadata Mapping
|
||||||
|
Ensure the `DocumentStatus` or `VerificationStatus` enum aligns with the backend definition:
|
||||||
|
- `PENDING`: Waiting for job to start.
|
||||||
|
- `PROCESSING`: AI is currently analyzing.
|
||||||
|
- `APPROVED`: Document is valid.
|
||||||
|
- `REJECTED`: Document is invalid (should check `rejectionReason`).
|
||||||
|
- `NEEDS_REVIEW`: AI is unsure, manual check required.
|
||||||
@@ -14,6 +14,7 @@ type Document @table(name: "documents") {
|
|||||||
name: String!
|
name: String!
|
||||||
description: String
|
description: String
|
||||||
documentType: DocumentType!
|
documentType: DocumentType!
|
||||||
|
isMandatory: Boolean @default(expr: "false")
|
||||||
createdAt: Timestamp @default(expr: "request.time")
|
createdAt: Timestamp @default(expr: "request.time")
|
||||||
updatedAt: Timestamp @default(expr: "request.time")
|
updatedAt: Timestamp @default(expr: "request.time")
|
||||||
createdBy: String
|
createdBy: String
|
||||||
|
|||||||
@@ -1,6 +1,13 @@
|
|||||||
enum DocumentStatus {
|
enum DocumentStatus {
|
||||||
UPLOADED
|
|
||||||
PENDING
|
PENDING
|
||||||
|
PROCESSING
|
||||||
|
AUTO_PASS
|
||||||
|
AUTO_FAIL
|
||||||
|
NEEDS_REVIEW
|
||||||
|
APPROVED
|
||||||
|
REJECTED
|
||||||
|
ERROR
|
||||||
|
UPLOADED
|
||||||
EXPIRING
|
EXPIRING
|
||||||
MISSING
|
MISSING
|
||||||
VERIFIED
|
VERIFIED
|
||||||
@@ -12,9 +19,16 @@ type StaffDocument @table(name: "staff_documents", key: ["staffId", "documentId"
|
|||||||
staffName: String!
|
staffName: String!
|
||||||
documentId: UUID!
|
documentId: UUID!
|
||||||
document: Document! @ref(fields: "documentId", references: "id")
|
document: Document! @ref(fields: "documentId", references: "id")
|
||||||
status: DocumentStatus!
|
|
||||||
|
status: DocumentStatus! @default(expr: "'PENDING'")
|
||||||
documentUrl: String
|
documentUrl: String
|
||||||
expiryDate: Timestamp
|
expiryDate: Timestamp
|
||||||
|
|
||||||
|
# Verification Metadata (Align with Attire flow)
|
||||||
|
verificationId: String
|
||||||
|
verifiedAt: Timestamp
|
||||||
|
rejectionReason: String
|
||||||
|
|
||||||
createdAt: Timestamp @default(expr: "request.time")
|
createdAt: Timestamp @default(expr: "request.time")
|
||||||
updatedAt: Timestamp @default(expr: "request.time")
|
updatedAt: Timestamp @default(expr: "request.time")
|
||||||
createdBy: String
|
createdBy: String
|
||||||
|
|||||||
Reference in New Issue
Block a user