Skip to content

Keep Android receipt data accessible when its image is missing or unreadable #32

Open

Description

@Kamitoad

Current status — 2026-10-12

Status: Implemented — acceptance pending. merged PR #37 fixes the reported image-read/display problem and is merged into main 538b70e; the fix is included in the existing signed APK.

Completed implementation/tests: Native reads retain valid receipt and attachment metadata while returning a transient unavailable-image warning on byte-read failure. ReceiptImage shows a German fallback for native warning or display errors. No-image receipts remain normal; database/schema failures still propagate. Read/edit/trash/restore regressions preserve values, checksums and extraction evidence. Full Android backups remain strict; web full export now also rejects missing or checksum-mismatched referenced images. No backup-format, database schema, Auto Backup, or migration change was made.

Automated evidence: Current main 538b70e passes pnpm check (143 tests in 15 files) and pnpm build; main CI confirms the same revision. Native tests simulate Capacitor boundaries and rendered tests use jsdom.

APK evidence: durable-signed APK run 38185223476 succeeded for the same main commit and produced itemly-installable-update-38185223476. This establishes inclusion in a built APK; installation, signed-update retention, and physical-device acceptance remain separate checks.

Browser evidence: The seven added rendered cases simulate image error events in jsdom; they do not prove real HTTP/image decoding or native filesystem behavior. Positive development feedback is not a complete acceptance run.

Remaining acceptance on disposable Samsung test data:

  • Missing image, denied/unreadable file access where feasible, and corrupt/undecodable image: open through both normal history and trash, with receipt values and image reference preserved.
  • Healthy and deliberately image-less receipts: no false warning.
  • Edit, reopen, trash/restore, app restart and phone restart: retain IDs, amounts, quantities, review state and original evidence.
  • Missing/checksum-invalid originals: full export clearly fails without a success claim. A display-only failure of checksum-matching bytes does not itself mean the backup is incomplete.
  • Install the compatible signed APK as an update and verify retention of pre-existing test data; never uninstall important data to bypass an update rejection.
  • Separately record a real web-browser image-load/display failure check; jsdom events are simulated coverage.

The October 11 local-only implementation note is superseded by the merged-source/APK evidence above. Keep open for acceptance.


Historical problem and repository evidence (fixed by PR #37)

At main commit 782bbcb055581921bc04db0fea96a459449426d5, src/native/api.ts maps receipt data through storedAttachment(), which awaits Filesystem.readFile(). A file error rejects the entire receipt load although its SQLite data still exists. The detail view also needs to handle a file that loads but cannot be displayed.

Acceptance criteria

  • Return and display valid receipt data even when its original image is missing, unreadable, or cannot be decoded/displayed.
  • Preserve the original attachment reference and metadata; distinguish an unavailable image from a receipt created without an image.
  • Show an understandable German message and image placeholder while merchant, date, totals, items, review state, and other receipt data remain accessible.
  • Do not silently delete the reference, replace source evidence, or alter stored amounts/review state when handling an image failure.
  • Cover history-to-detail and trash-to-detail. Any edit or mutation offered in this state must preserve evidence and report its own failure truthfully.
  • Keep full-backup validation strict: missing images still prevent claiming that a complete backup succeeded. This UI fix does not create a database-only backup/restore mode.

Verification and dependencies

Add native-adapter regression tests for missing/read-failing images and rendered detail-view tests for an image display error. Verify readable-image and no-image receipts still behave normally. Run pnpm check and pnpm build; record Samsung acceptance separately.

This is a reliability gap in #13; reuse #27 interaction coverage and coordinate API changes with #29 without waiting for a broader refactor. No milestone is added by this ticket.

Implemented development assignment (PR #37)

Decouple receipt-data loading from attachment-byte loading in the native adapter, introduce an explicit image availability/error result without dropping attachment metadata, and render the German fallback in the detail view. Prove with a fixture that deleting only the image or making its read fail still shows the original receipt values and does not mutate the database. Then test a browser image-display failure.

Related tickets

Related planning: #13 owns device acceptance, #33 tracks export status, and #34 plans the archive. Later recovery strategies are #35 and #36.

Activity

  1. Kamitoad commented on Oct 11, 2026

    @Kamitoad
    OwnerAuthor

    Implementation update — October 11, 2026

    The bounded #32 implementation is complete locally, not committed, merged, or distributed in an APK.

    • Native receipt loading catches image-file read failures only after attachment JSON/schema/path validation. It returns retained attachment metadata plus a transient attachmentWarning: unavailable, rather than dropping the reference or failing valid receipt data.
    • The shared detail image component shows a German placeholder for native read failures and web/native HTTP/decode/display failures. Items, metadata, totals, review state, editing, and trash/restore remain available. Receipts created without images remain normal.
    • Regression tests prove receipt rows are unchanged by failed image reads and that edits/trash/restore preserve attachment JSON, checksums, and original extraction evidence. Stored JSON/schema and database errors still propagate.
    • Android full-backup validation is unchanged and remains strict. Audit found a pre-existing web-export omission: directory listing could silently skip referenced missing files. Web full export now checks database references, including trash/drafts, and rejects missing or checksum-mismatched images without changing its format. No partial-backup mode is added.
    • No database schema/migration, backup-format, Auto Backup, archive, scheduled export, or web-to-Android migration change.

    Verification: pnpm check passed type checks and 143 tests in 15 files (17 new regressions); pnpm build succeeded; git diff --check passed. Rendered UI tests use jsdom and simulated image error events, not real browser/Android decoding. English scope and acceptance notes are in docs/TESTING.md, docs/ANDROID.md, docs/ARCHITECTURE.md, and CHANGELOG.md.

    Keep this issue open: publication and physical Samsung acceptance remain outstanding. Use disposable data to verify missing/denied/corrupt images, history and trash detail, edits/reopen, app/phone restart, strict failed full exports, and healthy/image-less receipts. Never remove a user's only original image for testing. No new manual browser inspection, native compilation, APK build, or real-device run was performed in this implementation pass.

  2. Kamitoad commented on Oct 11, 2026

    @Kamitoad
    OwnerAuthor

    Merged source and APK delivery

    PR #37 was merged into main as 538b70e94dc88b90685e495fbfd630021ec9f3ae after successful CI and Android PR validation. Local pnpm check (143 tests) and pnpm build also passed. Local main is synchronized and clean.

    The explicitly requested durable-signed APK build succeeded:
    https://github.com/Kamitoad/itemly/actions/runs/38185223476

    Artifact: itemly-installable-update-38185223476
    APK: itemly-update-87694934.apk
    Source: merged main commit 538b70e
    App ID: com.kamitoad.itemly.preview
    Version code: 87694934 (higher than the previous durable build's 87324320)

    Downloaded build metadata confirms the same public signing-certificate SHA-256 fingerprint as the October 7 durable build. No signing key was regenerated or exposed. This verifies build identity metadata, not a physical-device installation or Android update-retention test.

    Keep #32 open for the documented Samsung acceptance checks. Build success and positive development feedback do not establish missing-image handling, offline/restart persistence, export failure behavior, or update retention on a real device. Test with disposable data and back up existing real receipts before updating; do not uninstall to work around an unexpected update rejection.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions