---
id: SEED-001
status: dormant
planted: 2026-03-26
planted_during: v1.1 Phase 17 — GH Issues Client and Product Catalog
trigger_when: any phase touching product display, image pipeline, offline caching, or UI polish for product catalog
scope: Medium
---

# SEED-001: Async product image loading for product tiles and sidecar

## Why This Matters

Product images are stored in SQLite (Shopify CDN URLs and product-images branch URLs) but never rendered in the UI. Product tiles show placeholder "?" instead of actual images. The sidecar shows a grey box. This makes the product catalog feel incomplete — images are the primary visual identifier for hardware products.

The product-images branch stores uploaded images at `raw.githubusercontent.com/BigscreenVR/beyond-outgoing/product-images/images/{product_id}.jpg`, but this URL requires GitHub authentication for private repos. The Shopify CDN URLs are public but may be rate-limited.

## When to Surface

**Trigger:** Any phase that touches product display, image pipeline, or offline caching.

This seed should be presented during `/gsd:new-milestone` when the milestone scope matches any of these conditions:
- Product catalog UI improvements or polish
- Image caching or offline support
- Authenticated HTTP fetching infrastructure
- Product tile or sidecar visual enhancements

## Scope Estimate

**Medium** — Needs async HTTP fetch with GitHub auth token, image byte decoding, local disk cache, and Slint `Image::from_rgba8()` binding. Probably 1-2 phases: one for the fetch/cache pipeline, one for wiring into tiles and sidecar.

## Breadcrumbs

Related code and decisions found in the current codebase:

- `crates/app/src/main.rs` — `has_image: false` hardcoded on product tiles (~line 1893); sidecar `set_detail_has_image()` wiring
- `crates/app/src/live_client.rs` — Shopify image auto-fetch stores CDN URL in `image_url` field
- `crates/app/src/dashboard/discovery.rs` — `build_product_option_grid` produces tiles with `image_url` field
- `crates/integrations/src/github/product_images_branch_client.rs` — `build_raw_url()` produces the private repo URL
- `crates/app/ui/product-detail.slint` — `if root.has-image : Image { source: root.product-image; }` ready for binding
- `crates/app/ui/option-grid.slint` — `has-image` and `image` fields on `ProductTileData` struct

## Notes

Set Image upload pipeline IS functional — files get uploaded to the product-images branch via GitHub Contents API. The gap is purely on the download/render side. The app already has `reqwest` available in the integrations crate for HTTP fetching. Shopify access token is in WCM for authenticated CDN access if needed.
