HOCO B2B
Team tasksImad

MOB-11 — Media capture & uploads

Camera/gallery capture, compression, EXIF-free uploads to pre-signed URLs with retry, offline upload queue for the delegate app.

FieldDetails
Task codeMOB-11
PhaseP0 — Foundations (cadrage, UX/UI, architecture & contract)
Product scopeV1
StatusPlanned
StartThu 5 Nov 2026
DueSun 8 Nov 2026
ResponsibleImad — Mobile developer (Flutter)
Co-responsible—
Effort0.75 person-day(s) planned · 3 from scratch · size S
Area · appMobile foundation · mobile
Depends onMOB-03
UnblocksMDA-05
MilestonesMobile foundations ready

Summary

Camera/gallery capture, compression, EXIF-free uploads to pre-signed URLs with retry, offline upload queue for the delegate app.

Description

Visit photos, façade photos, store documents, payment proofs and claim photos all go through the same pre-signed upload flow, and in the delegate app they must survive having no network (CRM-10, FLD-08, SEC-04). Scope: camera and gallery capture (and PDF pick for documents), compression, EXIF stripping with the capture position kept as separate metadata, upload via files.createUpload → PUT to the pre-signed URL → files.completeUpload with retry, an offline upload queue for the delegate app that feeds the outbox, and private-file display through files.downloadUrl. The screens that attach files are in the feature tasks. It needs the files module (SRV-07) and the FilePurpose values from Anis; no design work beyond the capture sheet in DES-03. MDA-05, MDA-07, MRA-07, MRA-08 and MRA-10 call this service.

Subtasks

#SubtaskOwner
1MediaPicker: in-app camera (camera package) for delegate photos, Android photo picker / image_picker for the gallery, file_picker for PDF documents; camera permission rationaleImad
2Compression with flutter_image_compress: longest edge 1600 px, JPEG quality 80, target under 500 KB, EXIF removed; capture lat/lng/accuracy/time kept as metadata for delegate.visits.addPhotoImad
3UploadService: files.createUpload (purpose VISIT_PHOTO, STORE_PHOTO, STORE_DOCUMENT, PAYMENT_PROOF or TICKET_ATTACHMENT, contentType, size) → PUT with progress → files.completeUpload; new URL requested when the 10-min URL expiresImad
4pending_uploads drift table (localPath, purpose, fileId, state, attempts, lastError) and an UploadQueue that runs before dependent outbox mutations (addPhoto waits on its upload via dependsOn)Imad
5Retry policy: exponential backoff, Wi-Fi-or-any setting, pause when battery saver is on; failed items visible in the sync centreImad
6Local storage housekeeping: originals deleted after completeUpload, thumbnails kept for the visit view, low-storage warningImad
7PrivateImage widget loading files.downloadUrl (5-min signed URL) with cache and refresh on 403Imad

Deliverables

  • packages/hoco_core/lib/src/media/ (picker, compressor, upload_service.dart)
  • packages/hoco_offline/lib/src/uploads/upload_queue.dart and the pending_uploads table
  • packages/hoco_ui/lib/src/components/private_image.dart

Acceptance criteria

  • A 12-MP photo is uploaded as a JPEG under 500 KB with no EXIF GPS block; its capture position reaches the server in the addPhoto body (SEC-04, FLD-08)
  • Three photos taken in airplane mode upload automatically after reconnection and the visit then shows them as synced
  • An upload interrupted mid-way restarts with a fresh pre-signed URL and creates no orphan duplicate after completion
  • Private files are only displayed through short-lived signed URLs; an expired URL refreshes transparently
  • A PDF store document (RC, NIF) can be attached from the reseller app (CRM-10)

Requirements covered

RequirementTitleRelease
CRM-10Store photos and documents (façade, interior, RC, NIF, ID) with protected accessV1
FLD-08Visit and check-in: time and position at check-in, duration, checklist, note, photos (mandatory by visit type), call; finished visit lockedV1
SEC-04Protected documents and uploaded files (private storage, signed URLs, access checks)V1

API surface

Endpoint groupOperations
File uploads & downloads3

Test measures

  • Unit tests of the UploadQueue state machine with a fake files API (expiry, failure, retry, dependency release)
  • Test asserting EXIF absence on a compressed sample image
  • Device test: five photos offline → reconnect on a weak 3G profile → all uploaded and attached

Risks

  • Large photo queues on weak networks drain data and battery — compression first, sequential uploads and a visible queue size

KPI

  • Delivered by Sun 8 Nov 2026 within 0.75 person-day(s).
  • Every acceptance criterion above demonstrated before hand-off; linked requirements' acceptance criteria pass.
  • Zero open critical defects, permission gaps or data-integrity regressions at sign-off.

Generated from content/plan/tasks.json by scripts/generate-team-tasks.mjs. Dates are computed by the scheduler (Sunday–Thursday weeks, holidays excluded) — change the plan, not this page.

On this page