docs mobile p37 t02 upload outbox - AlexandreZanata/Abastevo GitHub Wiki
P37-T02 — Live upload and outbox lifecycle
Status: LOCAL_DONE on codex/phase-37-live-contributions. Task: P37-T02.
Binds idempotent retry (stable client_submission_id, fresh nonce per
send), owner status/cancel and process recovery (existing outbox +
worker contracts). Additive; no backend change; no device run.
Behavior (DDD)
CaptureOcrViewModel.submitConfirmed()closes the missing capture→outbox link: requires theConfirmedstate and the T01 canonical target, rejects cross-fuel misattribution (target wire vs confirmed product), then enqueues metadata-only (EnqueueContributionUseCase, photo plumbing stays future work and is labelled honestly by the use case). Outcomes:NoTarget,FuelMismatch,Disabled,Queued(historical),Failed(reason)— a transient network failure staysFailedand never becomes ACCEPTED. Identity proof travels at worker submit time through the existing contribution gateway (reserve → presigned PUT → complete → observation withIdempotency-Key/X-Nonce).CaptureScreenConfirmed branch gains an explicit Send button plus honest submit states (queued / failed-with-reason / invalid target); Done stays a plain back action. en/pt-BR strings +3.- Downstream (verified, not rebuilt): Room outbox enqueue/status/
cancel,
ContributionWorkerretry with fresh nonce per send (object success + finalize failure stays FAILED and retries the same id — never a duplicate observation), and app-restart recovery (existing P21-T03/P22-T04 suites, rerun below). No demonstrated backend/ contract defect was found, so no backend fix precedes the consumer.
Validation
- GREEN:
CaptureOcrViewModelTest+2 (no-target staysNoTargetbefore/after confirm; mismatch rejected, matching target enqueues non-historical) → suite PASS. Fixed twooperator-modifier call sites (enqueue.invoke) — no weakened assertions. - Regression: full
:app:testDebugUnitTestcapture subset PASS;:application:test+:data:testDebugUnitTestcontribution/outbox subsets PASS;:app:assembleDebugPASS (Hilt resolves the newEnqueueContributionUseCaseinjection). - Contracts unchanged:
vacuum lint+apicontractPASS; livecurl60 unchanged (no bypass). git diff --checkPASS;scan-secrets.shPASS.
Limits and next
- BLOCKED_LIVE: upload negotiation/bytes/completion against staging unverified from this runner (TLS trust gap); identity-proof live exercise owed. BLOCKED_MEDIA (see T03): no attached VPS private storage, so photo bytes stay out of the live path.
- OWED: end manual/device batch, provider/media proof. No PR/CI/merge/ wiki per ADR-018. iOS archived. G09 UNCERTIFIED.
- Next: P37-T03 private storage and all-copy expiry on this branch.