# Phase 20.1 UAT — Continue Here

**Last session:** 2026-04-12
**Status:** Phase 20.1 plans executed, UAT in progress. Multiple rounds of bug fixes committed. Several bugs remain.

## What Was Done

Phase 20.1 (UI Polish and Bug Fixes) was planned (4 plans, 4 waves) and fully executed. All 19 success criteria were implemented. Then multiple UAT rounds revealed bugs — some from the phase work, some pre-existing. Many have been fixed across commits `abf5259` through `eabbe4c`.

## Remaining Bugs (must fix)

### 1. Note editing textbox overflows card boundaries
- **Symptom:** When editing a note on a card, the TextInput + Save/Cancel buttons extend below the card's 196px height boundary.
- **Attempted:** `clip: true` + `single-line: true` on the editing Rectangle, and a redesign as inline HorizontalLayout. Neither fully resolved it.
- **Key file:** `crates/app/ui/card.slint` — search for `editing-note`. The editing Rectangle is 38px (was 20px for the display-only note), which pushes content beyond the fixed 196px card height set in `dashboard.slint`.
- **Fix direction:** Either increase card height when editing, or make the editing area exactly 20px (same as the non-editing note display) with a compact inline layout.

### 2. Cannot scroll the cards list in the shipped products tab
- **Symptom:** When on the Product Shipped tab viewing cards for a specific product, the card grid can't be scrolled if there are more cards than fit on screen.
- **Key file:** `crates/app/ui/dashboard.slint` — the card grid uses absolute `x`/`y` positioning (lines ~690) inside a non-scrollable container. Needs a Flickable wrapper or similar.

### 3. Product image change is non-functional
- **Symptom:** Clicking the product image in the sidecar opens a file picker, user selects an image, but the displayed image doesn't update.
- **Attempted:** Added local cache write + sidecar property update in `upgrade_in_event_loop`. Added diagnostic `eprintln!("[set-image]")` logging.
- **Key file:** `crates/app/src/main.rs` — search for `on_on_product_sidecar_set_image` (~line 4305). The handler uploads to GitHub branch, updates SQLite, writes local cache, and tries to update the sidecar image. Check stderr logs for `[set-image]` to see where it fails.
- **Note:** The `rfd::FileDialog` runs on a background thread which may have issues on Windows.

### 4. Product view sidebar disappears when leaving+returning to shipped products tab
- **Symptom:** Open Product Shipped tab → click a product → switch to another tab → switch back → sidecar is gone.
- **Attempted:** Changed `on_tab_clicked` to only hide sidecar when leaving ByProductShipped tab, and restore on return. May not be working correctly.
- **Key file:** `crates/app/src/main.rs` — search for `on_tab_clicked` and `ByProductShipped`.

## Confirmed Fixed (do not re-investigate)

- Product images loading from private GitHub repos (gh api + base64)
- Product images on cards without product_refs (name-based fallback)
- Shopify CDN images downloading via prefetch
- Recipient grid unassigned colors (is-unassigned field)
- Serial search input visibility (removed alignment:center)
- Settings modal layout (merged status+buttons row)
- App startup performance (read_product_by_name instead of read_all_products)
- Image-fit: contain on product tiles and sidecar
- [+] button vertical centering
- Lookup modal hiding (0 avail, 0 assigned) for products with no units
- Product sync merge preserving locally-created products
- Card grid 2 columns when sidecar open
- Dark window background (no white flash)
- **Unit list top-alignment** (clipped Rectangle + absolute y-positioning, outer VerticalLayout alignment:stretch, header vertical-stretch:0)

## Critical Anti-Patterns

| Pattern | Description | Severity |
|---------|-------------|----------|
| Claiming BUGSWEEPER verification without testing | Don't claim a fix is verified via BUGSWEEPER/screenshots unless you actually tested the specific behavior with targeted endpoint calls AND examined the screenshot carefully for the specific element in question | blocking |
| Slint Flickable bottom-alignment | VerticalLayout inside Flickable ALWAYS bottom-aligns content. See `code_tips/SLINT_TIPS.md`. Use clipped Rectangle with absolute y-positioning instead. | blocking |

## Key Files

- `crates/app/ui/card.slint` — card component, note editing
- `crates/app/ui/dashboard.slint` — card grid layout, window properties
- `crates/app/ui/product-detail.slint` — product sidecar, unit list
- `crates/app/src/main.rs` — all callback handlers, startup, image picker
- `crates/app/src/product_image_cache.rs` — image download and caching
- `code_tips/SLINT_TIPS.md` — Slint layout gotchas (READ BEFORE EDITING SLINT)
- `code_tips/SQLITE_TIPS.md` — SQLite gotchas

## Build & Test

```bash
cargo build --features bugsweeper
./target/debug/app.exe &
# Poll health
for i in $(seq 1 60); do curl -s http://127.0.0.1:9876/api/debug/health && break; sleep 0.5; done
# Navigate to Product Shipped tab and open Potato
curl -s -X POST -H "Content-Type: application/json" -d '{"name":"tab-clicked","args":[3]}' http://127.0.0.1:9876/api/ui/callback
curl -s -X POST -H "Content-Type: application/json" -d '{"name":"tile-clicked","args":["Potato"]}' http://127.0.0.1:9876/api/ui/callback
# Test unit search filter
curl -s -X POST -H "Content-Type: application/json" -d '{"name":"detail-unit-search-changed","args":["gsw"]}' http://127.0.0.1:9876/api/ui/callback
```
