# Roadmap: WITwhat

## Milestones

- v1.0 MVP — Phases 1-14 (shipped 2026-03-22)
- v1.1 Data Architecture & Product Catalog — Phases 15-21 (in progress)

## Phases

<details>
<summary>v1.0 MVP (Phases 1-14) — SHIPPED 2026-03-22</summary>

### Phase 1: Foundation and Shared State
**Goal**: Deliver secure token handling, shared persistence baseline, and core recipient model for multi-user operation.
**Depends on**: Nothing (first phase)
**Requirements**: AUTH-01, AUTH-02, DATA-04, ITEM-02, DSC-01, DSC-02, PLAT-01
**Success Criteria** (what must be TRUE):
  1. User can configure GitHub and Shopify credentials without exposing secrets in logs or plaintext config.
  2. Shared service persists normalized recipient/package data in SQLite and supports concurrent clients.
  3. Data model supports WITwhat item ownership independent from Shopify product mapping.
  4. Windows-targeted build runs end-to-end in local development.
**Plans**: 4 plans

Plans:
- [x] 01-01: Create Rust workspace and baseline crates (app/core/integrations/service)
- [x] 01-02: Implement credential storage and validation flow
- [x] 01-03: Define SQLite schema and repository layer
- [x] 01-04: Build shared service API skeleton and Windows packaging baseline

### Phase 2: External Sync Integrations
**Goal**: Sync recipient and shipment data from GitHub and Shopify with reliable periodic polling.
**Depends on**: Phase 1
**Requirements**: DATA-01, DATA-02, DATA-03, DATA-07
**Success Criteria** (what must be TRUE):
  1. Recipients are imported from the configured GitHub Project.
  2. Recipient records are linked to Shopify customer/order/fulfillment data.
  3. Polling runs every 5 minutes with retry/backoff and does not destabilize the UI.
  4. Sync failures are recoverable without data loss.
**Plans**: 4 plans

Plans:
- [x] 02-01: Implement GitHub Project ingestion and field mapping
- [x] 02-02: Implement Shopify customer/order/fulfillment lookups
- [x] 02-03: Build sync scheduler with jitter/backoff and retry rules
- [x] 02-04: Add merge pipeline and persistence integration

### Phase 3: Core Card Dashboard
**Goal**: Ship primary card-grid view with glance-critical shipment fields and refresh controls.
**Depends on**: Phase 2
**Requirements**: DATA-05, DATA-06, CARD-03, CARD-04, CARD-05, CARD-06, CARD-07
**Success Criteria** (what must be TRUE):
  1. Card grid displays items, first-item image, shipment status, status date, and latest note per recipient.
  2. User can refresh a single card and refresh all data from UI and F5.
  3. Visual hierarchy supports fast status scanning.
**Plans**: 3 plans

Plans:
- [x] 03-01: Build card-grid layout and card component model in Slint
- [x] 03-02: Wire card fields to projection layer and image loading pipeline
- [x] 03-03: Implement per-card, refresh-all, and F5-triggered refresh actions

### Phase 4: Item and Recipient Detail Editing
**Goal**: Enable local operational editing workflows and detailed recipient summary.
**Depends on**: Phase 3
**Requirements**: ITEM-01, ITEM-03, ITEM-04, CARD-10
**Success Criteria** (what must be TRUE):
  1. User can add, edit, and remove items in possession with persisted updates.
  2. User can edit latest note and see updates reflected immediately.
  3. Clicking recipient name opens floating summary showing required detail fields.
**Plans**: 3 plans

Plans:
- [x] 04-01-PLAN.md -- Service-layer mutation contracts and domain model updates
- [x] 04-02-PLAN.md -- Data-driven card UI with item/note editing controls
- [x] 04-03-PLAN.md -- Recipient floating summary panel and snapshot extension

### Phase 5: Discovery Navigation Framework
**Goal**: Establish discovery-mode structure and keyboard transitions.
**Depends on**: Phase 4
**Requirements**: DISC-02, DISC-03, DISC-07, DISC-08, DISC-09
**Success Criteria** (what must be TRUE):
  1. Left-side tabs switch between all four discovery modes.
  2. Up/Down arrows cycle discovery modes reliably.
  3. Esc behavior matches specified one-press and two-press outcomes.
**Plans**: 3 plans

Plans:
- [x] 05-01-PLAN.md -- Discovery mode state machine and card sort logic (TDD)
- [x] 05-02-PLAN.md -- Tab strip UI, global keyboard handler, and integration wiring
- [x] 05-03-PLAN.md -- Slint runtime integration and visual verification (gap closure)

### Phase 6: Advanced Discovery and Fuzzy Search
**Goal**: Complete instant search and layered discovery workflows for recipients and products.
**Depends on**: Phase 5
**Requirements**: DISC-01, DISC-04, DISC-05, DISC-06
**Success Criteria** (what must be TRUE):
  1. Typing any letter or space immediately starts fuzzy search.
  2. Recipient and product modes support option-grid entry and filtered card-view transitions.
  3. Bottom option bar supports multi-select filtering in active discovery mode.
  4. Search/filter responsiveness remains fast for expected dataset sizes.
**Plans**: 3 plans

Plans:
- [x] 06-01-PLAN.md -- Search/filter logic, per-mode state, and extended Esc state machine (TDD)
- [x] 06-02-PLAN.md -- Search bar and chip bar UI components with dashboard wiring
- [x] 06-03-PLAN.md -- Option grid views and filtered card-view transitions

### Phase 7: Archive Lifecycle Controls
**Goal**: Add archive filtering and automatic returned-state archiving with override control.
**Depends on**: Phase 6
**Requirements**: ARCH-01, ARCH-02, ARCH-03
**Success Criteria** (what must be TRUE):
  1. Archived cards are hidden by default and toggleable through Show archived.
  2. Cards auto-archive on transition to Returned status.
  3. Manual archive override persists and survives refresh/sync cycles.
**Plans**: 2 plans

Plans:
- [x] 07-01-PLAN.md -- Archive state module with three-state lifecycle (TDD)
- [x] 07-02-PLAN.md -- Archive filter UI, hover controls, toast undo, and pipeline wiring

### Phase 8: Discord Enrichment and External Jumps
**Goal**: Complete recipient communication shortcuts and outbound navigation from cards.
**Depends on**: Phase 7
**Requirements**: CARD-01, CARD-02, CARD-08, CARD-09, DSC-03, DSC-04
**Success Criteria** (what must be TRUE):
  1. Card shows Discord username and avatar where available.
  2. User can open DM context with one click from recipient/card UI.
  3. User can open Shopify customer and order links from cards in default browser.
  4. External jump actions are reliable and non-blocking to dashboard responsiveness.
**Plans**: 3 plans

Plans:
- [x] 08-01-PLAN.md -- External action helpers (TDD) and data pipeline field extensions
- [x] 08-02-PLAN.md -- Card UI enrichment: avatar circle, contact text, expanded ellipsis menu
- [x] 08-03-PLAN.md -- Callback wiring, seed data, and end-to-end verification

### Phase 9: Item & Note CRUD Wiring
**Goal**: Wire item add/edit/remove and note save handlers to real persistence so edits survive.
**Depends on**: Phase 4
**Requirements**: ITEM-01, ITEM-03
**Gap Closure:** Closes gaps from audit — 2 unsatisfied requirements, 2 broken flows
**Success Criteria** (what must be TRUE):
  1. Adding, editing, and removing items persists changes to storage.
  2. Saving a note persists changes and reflects immediately on the card.
**Plans**: 7 plans

Plans:
- [x] 09-01-PLAN.md -- PendingEditQueue, note save/item remove wiring, sync indicator
- [x] 09-02-PLAN.md -- Shipment Product Lookup modal and item add flow
- [x] 09-03-PLAN.md -- Fix note save refresh, item remove sentinel, sync indicator (UAT gap closure)
- [x] 09-04-PLAN.md -- Multi-item append support for item add flow (UAT gap closure)
- [ ] 09-05-PLAN.md -- Fix image frame on remove, sync indicator overlap, lookup modal clearing (UAT gap closure)
- [ ] 09-06-PLAN.md -- Per-item data model and removal logic (UAT gap closure)
- [ ] 09-07-PLAN.md -- Item squares UI redesign with hover and per-item interaction (UAT gap closure)

### Phase 10: Refresh & Auto-Archive Runtime Wiring
**Goal**: Wire dead refresh buttons and hook auto-archive into the card load pipeline.
**Depends on**: Phase 3, Phase 7
**Requirements**: DATA-05, DATA-06, ARCH-02
**Gap Closure:** Closes gaps from audit — 3 partial requirements, 3 broken flows
**Success Criteria** (what must be TRUE):
  1. Per-card Refresh menu item triggers a data refresh for that card.
  2. Refresh-all button triggers a full data refresh (matching F5 behavior).
  3. Cards auto-archive when status transitions to Returned during card load.
  4. Manual archive state persists across app restarts.
  5. Manual archive state survives refresh recomputes.
**Plans**: 4 plans

Plans:
- [x] 10-01-PLAN.md -- Slint callback declarations, UI properties, auto-archive in initial card load
- [x] 10-02-PLAN.md -- Refresh-all and per-card refresh callback wiring with archive hooks
- [x] 10-03-PLAN.md -- Fix manual-archive preservation in compute_archive_state and add ArchiveStore persistence (UAT gap closure)
- [x] 10-04-PLAN.md -- Wire persistent ArchiveStore init and NoopClient refresh error overrides (UAT gap closure)

### Phase 11: Projection Pipeline & Sort Fixes
**Goal**: Pipe Shopify URLs through projection and wire discovery-mode sorting.
**Depends on**: Phase 8, Phase 5
**Requirements**: CARD-08, CARD-09
**Gap Closure:** Closes gaps from audit — 2 partial requirements, 2 integration gaps, 1 broken flow
**Success Criteria** (what must be TRUE):
  1. Shopify customer and order URLs propagate from data source through projection to card actions.
  2. Cards sort according to the active discovery mode.
**Plans**: 3 plans

Plans:
- [x] 11-01-PLAN.md -- Thread shopify_order_id through pipeline and wire URL construction in projection
- [x] 11-02-PLAN.md -- Wire sort_cards_by_mode into apply_filters
- [x] 11-03-PLAN.md -- Fix sort bypass in filtered_cards identity-match loop (verification gap closure)

### Phase 12: Production Data Client Integration
**Goal**: Connect the app binary to the real DashboardDataClient so the dashboard displays live data from GitHub/Shopify APIs.
**Depends on**: Phase 2
**Requirements**: []
**Gap Closure:** Closes gaps from audit — 1 major integration gap, 1 broken flow
**Success Criteria** (what must be TRUE):
  1. App binary creates LiveClient backed by real Repository and uses it instead of NoopClient.
  2. Dashboard displays data from GitHub/Shopify APIs instead of seed data.
  3. Background sync thread fetches data every 5 minutes and pushes updates to UI.
  4. Config file at %APPDATA%/WITwhat/config.toml holds non-secret settings.
  5. Settings UI allows first-run configuration and resurfacing settings at any time.
**Plans**: 4 plans

Plans:
- [x] 12-01-PLAN.md -- Real HTTP clients for GitHub and Shopify + Repository.load_all_recipient_ids
- [x] 12-02-PLAN.md -- AppConfig module with TOML load/save/validation
- [x] 12-03-PLAN.md -- LiveClient implementation wrapping Arc<Mutex<Repository>>
- [x] 12-04-PLAN.md -- Main.rs rewiring: replace NoopClient/seed_cards, background sync, connection indicator
- [x] 12-05-PLAN.md -- Settings modal UI and callback wiring

### Phase 12.1: Secure Credential Storage (INSERTED)
**Goal:** Replace the mock WindowsCredentialManagerStore with real Windows Credential Manager FFI via keyring crate, add Shopify token management to settings modal, and wire stored credentials into LiveClient for Shopify data enrichment.
**Requirements**: AUTH-02
**Depends on:** Phase 12
**Success Criteria** (what must be TRUE):
  1. WindowsCredentialManagerStore uses real keyring Entry calls instead of in-memory HashMap.
  2. User can enter, validate, and store a Shopify access token via the settings modal.
  3. User can clear a stored token, removing it from WCM.
  4. Connection status shows yellow "Connected (no Shopify)" when GitHub works but no token configured.
  5. LiveClient reads token from WCM at sync start and passes it to HttpShopifyClient.
**Plans**: 3 plans

Plans:
- [x] 12.1-01-PLAN.md -- WCM FFI backend via keyring, SecretStore delete(), caller fixes
- [x] 12.1-02-PLAN.md -- Settings modal token section UI and connection status extension
- [x] 12.1-03-PLAN.md -- Main.rs wiring: token validation, WCM write/clear, partial connection status

### Phase 12.1.1: Shopify-first card source pipeline (INSERTED)
**Goal:** Refactor the data pipeline so Shopify orders tagged "wit-what" are the sole card source, match order customers to GH Project recipients via Shopify Profile URL, and show unmatched orders as unassigned cards with visual warning treatment and Pick Recipient assignment flow.
**Requirements**: PIPE-01, PIPE-02, PIPE-03, PIPE-04, PIPE-05, PIPE-06, PIPE-07
**Depends on:** Phase 12.1
**Success Criteria** (what must be TRUE):
  1. Shopify orders tagged "wit-what" are fetched with pagination as the primary card source.
  2. Orders matched to GH Project recipients via customer ID from Shopify Profile URL field.
  3. Unmatched orders appear as unassigned cards with italic/warning name treatment.
  4. Pick Recipient modal allows searching and selecting from unlinked GH Project recipients.
  5. Create New Recipient creates a GH Project item and assigns the order.
  6. Assignment writes Shopify Profile URL back to GH Project via GraphQL mutation.
  7. Next sync auto-matches via the populated Shopify Profile URL.
**Plans**: 6 plans

Plans:
- [x] 12.1.1-01-PLAN.md -- Shopify orders_by_tag + GH mapping shopify_profile_url + snapshot/view model type extensions
- [x] 12.1.1-02-PLAN.md -- GH Project mutation support (update field, add item, field ID lookup)
- [x] 12.1.1-03-PLAN.md -- Sync pipeline refactor to Shopify-first with recipient matching
- [x] 12.1.1-04-PLAN.md -- UI: CardData extension, unassigned card treatment, RecipientPickerModal
- [x] 12.1.1-05-PLAN.md -- Main.rs wiring: sync callback, pick-recipient, assign, create-and-assign callbacks
- [ ] 12.1.1-06-PLAN.md -- End-to-end verification checkpoint

### Phase 13: Data Flow Architecture Document
**Goal:** Create the authoritative data flow reference document (DATA-FLOW.md) mapping every data entity, source, sync direction, storage layer, and transformation.
**Depends on:** Phase 12.1.1
**Success Criteria** (what must be TRUE):
  1. .planning/DATA-FLOW.md exists as a layered reference with field tables and ASCII flow diagrams.
  2. Document covers all four data layers: Recipients, Cards, Products, Serial Instances.
  3. Document includes prescriptive rules section for agents.
  4. Document defines SQLite full-mirror cache architecture and GH Issues storage model.
  5. CLAUDE.md updated with mandatory read + update obligation pointing to DATA-FLOW.md.
**Plans**: 1 plan

Plans:
- [x] 13-01-PLAN.md -- Write DATA-FLOW.md reference document and CLAUDE.md enforcement blurb

### Phase 14: UI Polish
**Goal:** Consolidate all priority UI fixes identified across 11 phase audits into a single polish pass.
**Depends on:** Phase 13
**Requirements**: COLOR-01, TYPO-01, EMPTY-01, LAYOUT-01, ICON-01, XD-01, SPACE-01
**Success Criteria** (what must be TRUE):
  1. All .slint files reference shared color tokens from tokens.slint instead of hardcoded hex literals.
  2. All font-size values use only the 4-size canonical scale (11px, 12px, 13px, 18px).
  3. Empty state guidance text appears for card grid, search, option grid, lookup modal, and recipient picker.
  4. Card body uses VerticalLayout instead of absolute y-coordinates.
  5. Toast background color distinguishes warning (amber) from informational (blue).
**Plans**: 3 plans

Plans:
- [x] 14-01-PLAN.md -- Create tokens.slint and migrate card.slint + dashboard.slint (colors, typography, empty states, icon fixes, toast warning)
- [x] 14-02-PLAN.md -- Migrate remaining 6 .slint files (colors, typography, timer, glyphs, empty states, focus border)
- [ ] 14-03-PLAN.md -- Card VerticalLayout migration, toast-is-warning Rust wiring, visual verification checkpoint

</details>

---

## v1.1 — Data Architecture & Product Catalog (In Progress)

**Milestone Goal:** Complete the data architecture vision: SQLite persistence, GH Issues cloud storage, product catalog with serial tracking, and operational features (returns, lists) — closing every gap identified in DATA-FLOW.md.

### Phase 15: SQLite Foundation, Deprecated Field Cleanup, and UI Polish Gap Closure
- [x] **Phase 15: SQLite Foundation and Cleanup** - Replace in-memory Repository with SQLite, remove all DATA-FLOW.md debt fields, and close the remaining v1.0 UI gap. (completed 2026-03-23)

### Phase 16: GH Project New Columns Ingestion
- [x] **Phase 16: GH Project New Columns** - Ingest Purpose, Vision Rx, and product parallel-arrays from GH Project and surface in card UI. (completed 2026-03-23)

### Phase 16.2: BUGSWEEPER live debugging framework for agent-executed Slint frontend testing and UAT (INSERTED)

**Goal:** Build BUGSWEEPER -- a modular live debugging framework that gives Claude Code agents full programmatic control over the running Slint frontend via HTTP/JSON endpoints, enabling fully autonomous testing, debugging, and UAT rounds. Feature-gated for zero production overhead.
**Requirements**: None (infrastructure phase)
**Depends on:** Phase 16
**Plans:** 3/3 plans complete

Plans:
- [ ] 16.2-01-PLAN.md -- Crate scaffold, HTTP server (tiny_http), query_ui bridge, debug endpoints, feature gate wiring
- [ ] 16.2-02-PLAN.md -- UI endpoints: card model JSON serialization, property read/write, callback invocation
- [ ] 16.2-03-PLAN.md -- Data and state endpoints: SQLite queries, discovery/archive state, app config/window info

### Phase 16.1: Discord Username Editing, Avatar Fetching, and Popover Redesign (INSERTED)

**Goal:** Enable inline editing of Discord username in the summary popover with GH Project write-back, resolve Discord user IDs via Discord API, fetch and cache Discord avatar images locally, display real avatar images on cards, and redesign the popover field layout.
**Requirements**: DSC-05, DSC-06, DSC-07, DSC-08, DSC-09, DSC-10, DSC-11, DSC-12, DSC-13
**Depends on:** Phase 16
**Success Criteria** (what must be TRUE):
  1. Discord username is inline-editable in the summary popover with GH Project write-back.
  2. Editing Discord username resolves to a user_id via Discord API guild member search.
  3. Discord avatar images are fetched from CDN and cached at %APPDATA%/WITwhat/avatars/.
  4. Cards display real avatar images when cached, initials when not.
  5. Settings modal has Discord Bot Token section for credential management via WCM.
  6. Popover shows redesigned field order with Email, Last Activity, and pencil edit affordances.
  7. Vision Rx OD/OS fields show pencil icon edit affordance.
  8. Email removed from card face (popover only); card shows "No contact info" when no Discord username.
**Plans**: 4 plans

Plans:
- [ ] 16.1-01-PLAN.md -- Discord API client module, avatar fetcher, SQLite migration, AppConfig extension, contact_secondary change, view model extension (DSC-05, DSC-06, DSC-07, DSC-08)
- [ ] 16.1-02-PLAN.md -- Settings modal Discord Bot Token section, CardData and DashboardWindow extensions (DSC-09, DSC-10)
- [ ] 16.1-03-PLAN.md -- Popover redesign, pencil icons, Discord username inline edit, avatar Image display (DSC-05, DSC-06, DSC-07, DSC-11, DSC-12, DSC-13)
- [ ] 16.1-04-PLAN.md -- Main.rs wiring: projection, callbacks, avatar fetch, settings token, end-to-end checkpoint (DSC-05 through DSC-13)

### Phase 17: GH Issues Client and Product Catalog
**Goal**: Users can browse a standalone product list, products have structured entities in SQLite and GH Issues, and cards reference products via structured refs instead of freeform text.
**Depends on**: Phase 15
**Requirements**: CLOUD-03, CLOUD-04, PROD-01, PROD-02, PROD-03, PROD-04, PROD-05
**Success Criteria** (what must be TRUE):
  1. A product catalog view is reachable from the dashboard and lists all hardware products.
  2. Each product shows product_id, name, image, and whether it is serializable.
  3. Cards show product references (not freeform item_summary text); product tiles link to structured product entities.
  4. User can add a serialized product nested under a parent product via the product add UI.
  5. ww-product GH Issues are created or updated when product data changes, with a stable `schema_version` JSON body.
**Plans**: 9 plans
**Gap Closure:** Closes 6 gaps from UAT round 2

Plans:
- [x] 17-01-PLAN.md -- GhIssuesClient, V004 migration, SqliteStore product CRUD (CLOUD-03, CLOUD-04, PROD-02)
- [x] 17-02-PLAN.md -- Product sync, catalog-backed grid, ProductImagesBranchClient (PROD-01)
- [x] 17-03-PLAN.md -- Product catalog Slint UI: enriched tiles, ellipsis menu, detail panel, AddProductForm (PROD-01)
- [x] 17-04-PLAN.md -- Product picker, unit creation, main.rs wiring, end-to-end checkpoint (PROD-04, PROD-05, CLOUD-03, CLOUD-04)
- [x] 17-05-PLAN.md -- Card product_refs migration: V005, ProductRef struct, projection wiring (PROD-03)
- [x] 17-06-PLAN.md -- AddProductForm styling parity + product tile ellipsis flicker fix (UAT gap closure)
- [x] 17-07-PLAN.md -- Product detail sidecar redesign: right sidebar in filtered view, remove ellipsis (UAT gap closure)
- [x] 17-08-PLAN.md -- Serial unit creation: inline SN input, debounce, radio-button selection (UAT gap closure)
- [x] 17-09-PLAN.md -- Product sync persistence, stale cleanup, Shopify image fetch, lookup modal wiring (UAT gap closure)

### Phase 18: GH Issues Write-Back, Notes, and Card Cloud Storage

**Goal:** Card data is cloud-persisted in GH Issues (ww-card label), notes are stored as GH Issue comments, and all card edits queue through PendingEditFlusher for reliable write-back.
**Requirements**: CLOUD-01, CLOUD-02, CLOUD-05
**Depends on:** Phase 17
**Plans:** 3/3 plans complete

Plans:
- [x] 18-01-PLAN.md -- V006 migration, CardIssueBody struct, GhIssuesClient methods, SqliteStore extensions (CLOUD-01, CLOUD-02, CLOUD-05)
- [x] 18-02-PLAN.md -- sync_card_issues, note backfill, save_note GH comment posting (CLOUD-01, CLOUD-05)
- [x] 18-03-PLAN.md -- PendingEditFlusher module, LiveClient wiring, edit_queue removal (CLOUD-02)

### Phase 19: Serial Instance Tracking and Start Return
- [ ] **Phase 19: Serial Tracking and Returns** - Implement per-unit serial lifecycle state machine and Start Return flow from Delivered cards.

### Phase 20: Offline Mode Hardening
- [x] **Phase 20: Offline Mode** - Add connectivity detection, offline UI state, and pending edit queue flush-on-reconnect.
 (completed 2026-04-11)

### Phase 20.4: Implement all RETRO-AGENT-FAILURE-PATTERNS mitigations (M-1 through M-10) — agent failure pattern hardening (INSERTED)

**Goal:** [Urgent work - to be planned]
**Requirements**: TBD
**Depends on:** Phase 20
**Plans:** 5/5 plans complete

Plans:
- [x] TBD (run /gsd-plan-phase 20.4 to break down) (completed 2026-04-16)

### Phase 20.5: Modal State Architectural Audit (INSERTED)

**Goal:** Inventory every modal in the app, document every callback in/out, identify every place modal state is read or mutated, and produce a canonical state diagram in `.planning/MODAL-STATE.md`. Subsequent modal changes must update this doc.
**Requirements**: None (infrastructure phase)
**Depends on:** Phase 20.4
**Plans:** 1/1 plans complete

Plans:
- [x] 20.5-01-PLAN.md -- Complete modal state audit: RecipientPickerModal audit + write MODAL-STATE.md

### Phase 20.3: Write-Context Enforcement — Link SQLite Writes to Pending Edit Enqueues (INSERTED)

**Goal:** Introduce a write-context pattern (SyncInbound vs LocalChange) so that every SQLite write method that represents a local or derived change automatically enqueues the corresponding pending edit for GH Issue sync. Eliminates the class of bugs where SQLite is updated but the remote GH Issue is not. Inbound sync writes (data from GH/Shopify) are explicitly marked to skip enqueue, preventing infinite sync loops.
**Depends on:** Phase 20.2
**Plans:** 0 plans

Plans:
- [ ] TBD (run /gsd-plan-phase 20.3 to break down)

### Phase 20.1: UI Polish and Bug Fixes (INSERTED)

**Goal**: Fix accumulated UI bugs, alignment issues, and data integrity problems across the dashboard, product detail sidecar, and GH Issues sync layer.
**Depends on**: Phase 20
**Success Criteria** (what must be TRUE):
  1. Avatar enlargement, card subtext repositioning, and Recipients view avatar rings are implemented.
  2. Missing note warning replaced with (add note) placeholder.
  3. Shopify and Discord token section styling unified in settings modal.
  4. Contextual no-orders message based on connection status.
  5. Avatar image scaling quality fixed.
  6. Avatar images load without Discord bot token.
  7. Font vertical alignment consistent across app (new font if needed).
  8. Product sidecar hides when switching away from product tab.
  9. Serial unit search box seeds new unit SN field.
  10. Default card shipping state shows 'No items added' when empty.
  11. assigned_card_id stores unique card ID, not display name.
  12. Unit assignment reflected in lookup modal and product sidecar.
  13. ww-unit issue body uses consistent pretty-printed JSON format.
  14. State change preserves card assignment when unassign checkbox unchecked.
  15. Serial units textbox shows caret cursor on hover.
  16. Serial units search results top-aligned, [+] button center-aligned.
  17. Creating a product from lookup modal creates a corresponding ww-product GH Issue so the product persists across syncs.
  18. Product images download from Shopify during sync.
  19. Product images display in product squares (on card), product view sidecar, and Product Shipped tab home.
**Plans**: 4 plans

Plans:
- [x] 20.1-01-PLAN.md -- Inter font embedding + Slint UI polish (SC2, SC3, SC4, SC7, SC9, SC10, SC14-slint, SC15, SC16)
- [x] 20.1-02-PLAN.md -- Avatar visual refresh + avatar loading fix (SC1, SC5, SC6, D-01, D-02, D-03)
- [x] 20.1-03-PLAN.md -- Data integrity + GH Issues bug fixes (SC8, SC11, SC12, SC13, SC14-rust, SC17)
- [x] 20.1-04-PLAN.md -- Product image pipeline: download + display (SC18, SC19, D-06, D-07, D-08)

### Phase 20.1.1: Change the (i) button on cards to show a scrollable history of ww-note entries and a new note submission textbox. Remove the notes from card faces and fill the extra space by making the product squares/product-related texts larger. (INSERTED)

**Goal:** Repurpose the (i) button into a scrollable ww-note history popover with a new-note composer; remove the note row from the card face and enlarge product squares; migrate the old summary-popup content into a new recipient-detail sidebar in the Recipients tab, accessible via tile click or dashboard card name click.
**Requirements**: D-01..D-20 (CONTEXT.md — locked user decisions)
**Depends on:** Phase 20.1
**Plans:** 9/9 plans complete

Plans:
- [x] 20.1.1-01-PLAN.md -- NoteEntry.author + V012 migration + sqlite.rs notes round-trip + DATA-FLOW.md update (D-05, D-11)
- [x] 20.1.1-02-PLAN.md -- GhIssuesClient::list_issue_comments + parse_note_comment (D-11 read-back)
- [x] 20.1.1-03-PLAN.md -- NoteDisplayEntry + format_relative_time + view_model notes field + save_note author (D-04, D-05, D-09)
- [x] 20.1.1-04-PLAN.md -- Notes popup UI: PopupWindow, scrollable list, composer, Ctrl+Enter (D-01..D-10)
- [x] 20.1.1-05-PLAN.md -- LiveClient::fetch_notes_for_card + main.rs callback wiring for popover open/post-note (D-11, D-12, D-13)
- [x] 20.1.1-06-PLAN.md -- Card-face Row 5 removal + product square growth + note_preview cleanup across 4 files (D-14, D-15)
- [x] 20.1.1-07-PLAN.md -- New recipient-detail.slint component (D-16, D-17, D-20)
- [x] 20.1.1-08-PLAN.md -- Mount sidebar in dashboard + delete summary-popup + ByRecipient tile-click rewire + sidebar callback wiring (D-16, D-18, D-19)
- [x] 20.1.1-09-PLAN.md -- card-name-navigate full impl (tab switch + tile select + sidebar show) (D-19 second clause)

### Phase 20.1.1.1: Phase 20.1.1 gap closure — recipient tab sidebar coexistence, notes popover stability, product add button (INSERTED)

**Goal:** Close 9 UAT defects and land 2 redesigns from Phase 20.1.1: restore sidebar-alongside-grid coexistence in the Recipients tab, stabilize notes popover (content-height rows, stay-open-on-post, immediate SQLite render, dedup), swap labeled Purpose for a colored pill, reorder sidebar fields (Discord/Shopify at top), and restore hover-only + vertically-aligned product-add (+) button on card faces. Validate live via BUGSWEEPER + screen-timelapse.
**Requirements**: D-01..D-14 (CONTEXT.md — locked user decisions from 2026-04-15 UAT)
**Depends on:** Phase 20.1.1
**Plans:** 5/6 plans complete

Plans:
- [x] 20.1.1.1-01-PLAN.md — card.slint: content-height note rows + hover-gated aligned (+) button (D-04, D-11, D-12)
- [x] 20.1.1.1-02-PLAN.md — recipient-detail.slint: remove X close button, Purpose pill, field reorder (D-08, D-09, D-10)
- [x] 20.1.1.1-03-PLAN.md — dashboard.slint: fix sidebar mount guard for coexistence (D-01)
- [x] 20.1.1.1-04-PLAN.md — live_client.rs + view_model.rs: resolve GH login at init, dedup optimistic note author (D-07)
- [x] 20.1.1.1-05-PLAN.md — main.rs: tab-restore sidebar + targeted note patch on post + D-03/D-06 verification (D-02, D-03, D-05, D-06)
- [ ] 20.1.1.1-06-PLAN.md — Validation: BUGSWEEPER + screen-timelapse evidence for D-01..D-12; VALIDATION.md; revert mutations (D-13, D-14)

### Phase 20.1.1.1.1: Phase 20.1.1 round 2 gap closure — note dedup, sidebar nav, role pill dropdown, button flicker, sync issues (INSERTED)


**Goal:** Close 13 defects from UAT round 2: purpose pill dropdown (D-01/D-02), sidebar navigation lifecycle (D-03/D-04/D-05/D-06), note dedup (D-07), product add button flicker and alignment (D-08/D-09), stale Rx data (D-10), product icon scaling (D-11), return status (D-12), item display label (D-13), and Shopify sync connectivity (D-14).
**Requirements**: D-01..D-14 (CONTEXT.md -- locked user decisions from 2026-04-15 UAT round 2)
**Depends on:** Phase 20.1.1.1
**Plans:** 5/5 plans complete

Plans:
- [x] 20.1.1.1.1-01-PLAN.md -- card.slint: hover flicker fix, button alignment, product square scaling (D-08, D-09, D-11)
- [x] 20.1.1.1.1-02-PLAN.md -- recipient-detail.slint: purpose pill dropdown, hollow border, Esc fix (D-01, D-02, D-05)
- [x] 20.1.1.1.1-03-PLAN.md -- sqlite.rs: note dedup key fix (card_id, author, content) (D-07)
- [x] 20.1.1.1.1-04-PLAN.md -- dashboard.slint + main.rs: sidebar nav, breadcrumb dismiss, purpose-options, post-sync refresh (D-03, D-04, D-06, D-10)
- [x] 20.1.1.1.1-05-PLAN.md -- main.rs + live_client.rs: data correctness (D-12, D-13, D-14) + human verification

### Phase 21: Lists Feature
- [ ] **Phase 21: Lists** - Deliver named card groupings as a new discovery mode with full membership management.

## Phase Details

### Phase 15: SQLite Foundation and Cleanup
**Goal**: Users see a fast-loading dashboard backed by SQLite persistence, with all legacy data-model debt fields removed and the Phase 14 card layout gap closed.
**Depends on**: Phase 14
**Requirements**: POLISH-01, PERSIST-01, PERSIST-02, PERSIST-03, CLEAN-01, CLEAN-02, CLEAN-03, CLEAN-04
**Success Criteria** (what must be TRUE):
  1. App data survives a restart without fetching from GitHub or Shopify — cards load instantly from SQLite.
  2. Dashboard reads all card data from SQLite (not in-memory Repository); in-memory Repository is test-only.
  3. SQLite schema contains all entities from DATA-FLOW.md: recipients, cards, card_products, notes, products, serial_instances, archive_records, pending_edits.
  4. `github_profile_url`, shipment fields on Recipient, `item_summary`, and `latest_note` scalar are gone from all structs and the transformation pipeline.
  5. RecipientCard shows vertical layout (avatar, name, status stack) with toast-is-warning wiring active.
**Plans**: 3 plans

Plans:
- [ ] 15-01-PLAN.md -- Remove github_profile_url and shipment fields from Recipient (CLEAN-01, CLEAN-02)
- [ ] 15-02-PLAN.md -- Replace item_summary/latest_note/first_item_image_hint with structured types and UI polish (CLEAN-03, CLEAN-04, POLISH-01)
- [ ] 15-03-PLAN.md -- SQLite foundation: SqliteStore, refinery migrations, LiveClient rewire (PERSIST-01, PERSIST-02, PERSIST-03)

### Phase 16: GH Project New Columns Ingestion
**Goal**: Purpose-colored avatar borders appear on cards, Vision Rx values appear in the recipient summary popover, and product parallel-arrays flow from GH Project into the data pipeline ready for product catalog resolution.
**Depends on**: Phase 15
**Requirements**: GHCOL-01, GHCOL-02, GHCOL-03, GHCOL-04, GHCOL-05
**Success Criteria** (what must be TRUE):
  1. Each card's avatar border uses a distinct color derived from the recipient's Purpose GH Project column value.
  2. Hovering a card header shows Purpose as a tooltip; Purpose also appears in the recipient summary popover.
  3. Recipient summary popover shows Vision Rx OD and Vision Rx OS values with inline editing.
  4. `product_names`, `product_shopify_urls`, and `product_serials` parallel-array columns are ingested from GH Project and stored in the recipients table.
**Plans**: 3 plans

Plans:
- [ ] 16-01-PLAN.md -- Data pipeline: GraphQL parsing, project_mapping, domain models, SQLite migration, sync cycle, projection, CardData (GHCOL-01, GHCOL-02, GHCOL-03, GHCOL-05)
- [ ] 16-02-PLAN.md -- Card UI: avatar ring, Purpose tooltip, ChipData extension, Purpose chips, Purpose filtering (GHCOL-01, GHCOL-02)
- [ ] 16-03-PLAN.md -- Popover UI: Vision Rx inline editing, Copy Rx, Purpose label, Recipient Products list (GHCOL-03, GHCOL-04, GHCOL-05)

### Phase 17: GH Issues Client and Product Catalog
**Goal**: Users can browse a standalone product list, products have structured entities in SQLite and GH Issues, and cards reference products via structured refs instead of freeform text.
**Depends on**: Phase 15
**Requirements**: CLOUD-03, CLOUD-04, PROD-01, PROD-02, PROD-03, PROD-04, PROD-05
**Success Criteria** (what must be TRUE):
  1. A product catalog view is reachable from the dashboard and lists all hardware products.
  2. Each product shows product_id, name, image, and whether it is serializable.
  3. Cards show product references (not freeform item_summary text); product tiles link to structured product entities.
  4. User can add a serialized product nested under a parent product via the product add UI.
  5. ww-product GH Issues are created or updated when product data changes, with a stable `schema_version` JSON body.
**Plans**: 9 plans
**Gap Closure:** Closes 6 gaps from UAT round 2

Plans:
- [x] 17-01-PLAN.md -- GhIssuesClient, V004 migration, SqliteStore product CRUD (CLOUD-03, CLOUD-04, PROD-02)
- [x] 17-02-PLAN.md -- Product sync, catalog-backed grid, ProductImagesBranchClient (PROD-01)
- [x] 17-03-PLAN.md -- Product catalog Slint UI: enriched tiles, ellipsis menu, detail panel, AddProductForm (PROD-01)
- [x] 17-04-PLAN.md -- Product picker, unit creation, main.rs wiring, end-to-end checkpoint (PROD-04, PROD-05, CLOUD-03, CLOUD-04)
- [x] 17-05-PLAN.md -- Card product_refs migration: V005, ProductRef struct, projection wiring (PROD-03)
- [x] 17-06-PLAN.md -- AddProductForm styling parity + product tile ellipsis flicker fix (UAT gap closure)
- [x] 17-07-PLAN.md -- Product detail sidecar redesign: right sidebar in filtered view, remove ellipsis (UAT gap closure)
- [ ] 17-08-PLAN.md -- Serial unit creation: inline SN input, debounce, radio-button selection (UAT gap closure)
- [x] 17-09-PLAN.md -- Product sync persistence, stale cleanup, Shopify image fetch, lookup modal wiring (UAT gap closure)

### Phase 18: GH Issues Write-Back, Notes, and Card Cloud Storage
**Goal**: Card data is cloud-persisted in GH Issues (ww-card label), notes are stored as GH Issue comments and surfaced as a full history, and all card edits queue through PendingEditFlusher for reliable write-back.
**Depends on**: Phase 17
**Requirements**: CLOUD-01, CLOUD-02, CLOUD-05
**Success Criteria** (what must be TRUE):
  1. ww-card GH Issues are created for new cards and updated when card data changes.
  2. Notes appear as a list (not a single latest note) in the recipient summary popover, sourced from GH Issue comments.
  3. A note added in the app appears as a new comment on the corresponding ww-card GH Issue.
  4. Pending edits flush to GH Issues in FIFO order before any sync cycle runs on reconnect.
**Plans**: 3 plans

Plans:
- [x] 18-01-PLAN.md -- V006 migration, CardIssueBody struct, GhIssuesClient methods, SqliteStore extensions (CLOUD-01, CLOUD-02, CLOUD-05)
- [x] 18-02-PLAN.md -- sync_card_issues, note backfill, save_note GH comment posting (CLOUD-01, CLOUD-05)
- [ ] 18-03-PLAN.md -- PendingEditFlusher module, LiveClient wiring, edit_queue removal (CLOUD-02)

### Phase 19: Serial Instance Tracking and Start Return
**Goal**: Individual serial units are visible with lifecycle state per product, a unit can only be assigned to one card at a time, and users can initiate a return from a Delivered card without leaving the app.
**Depends on**: Phase 17, Phase 18
**Requirements**: SERIAL-01, SERIAL-02, SERIAL-03, SERIAL-04, RETURN-01, RETURN-02, RETURN-03, RETURN-04
**Success Criteria** (what must be TRUE):
  1. Product detail shows a list of serial instances each with a state badge: Created, Assigned, In Transit, Delivered, Return In Transit, Returned, or Available.
  2. Assigning a serial to a second card while already assigned is rejected by the system.
  3. Searching by serial number matches cards and products in the fuzzy search results.
  4. A Delivered card shows a Start Return action; activating it transitions the serial to Return In Transit and opens `[order_url]/return` in the default browser.
  5. Serial state changes write to the corresponding ww-card and ww-product GH Issues via PendingEditFlusher.
**Plans**: TBD

### Phase 20: Offline Mode Hardening
**Goal**: The dashboard continues functioning during a connectivity outage with a clear offline indicator, and all edits made offline are automatically flushed to GH Issues when the connection returns.
**Depends on**: Phase 18
**Requirements**: OFFLINE-01, OFFLINE-02, OFFLINE-03
**Success Criteria** (what must be TRUE):
  1. Dashboard shows a distinct offline indicator when GitHub/Shopify APIs are unreachable; cached card data remains visible and usable.
  2. Edits made while offline (notes, item changes, serial transitions) queue locally and apply to the UI optimistically.
  3. When connectivity returns, queued edits flush to GH Issues before the next sync cycle runs; no sync can overwrite a pending edit.
**Plans**: 2 plans

Plans:
- [x] 20-01-PLAN.md -- SqliteStore pending-edit methods, conflict avoidance in sync, pending-edit-count wiring
- [x] 20-02-PLAN.md -- Breathing green dot animation and text indicator removal

### Phase 21: Lists Feature
**Goal**: Users can create named lists, assign cards to multiple lists simultaneously, and view a list as a filtered card grid from a dedicated discovery tab.
**Depends on**: Phase 15
**Requirements**: LIST-01, LIST-02, LIST-03, LIST-04
**Success Criteria** (what must be TRUE):
  1. User can create, rename, and delete named lists from the Lists discovery tab.
  2. User can add a card to a list and remove it; a card can belong to more than one list at the same time.
  3. Selecting a list shows a filtered card view containing only that list's cards.
  4. List membership persists across app restarts.
**Plans**: TBD

## Progress

| Phase | Milestone | Plans Complete | Status | Completed |
|-------|-----------|----------------|--------|-----------|
| 1. Foundation and Shared State | v1.0 | 4/4 | Complete | 2026-02-27 |
| 2. External Sync Integrations | v1.0 | 4/4 | Complete | 2026-02-27 |
| 3. Core Card Dashboard | v1.0 | 3/3 | Complete | 2026-02-28 |
| 4. Item and Recipient Detail Editing | v1.0 | 3/3 | Complete | 2026-03-07 |
| 5. Discovery Navigation Framework | v1.0 | 3/3 | Complete | 2026-03-08 |
| 6. Advanced Discovery and Fuzzy Search | v1.0 | 3/3 | Complete | 2026-03-08 |
| 7. Archive Lifecycle Controls | v1.0 | 2/2 | Complete | 2026-03-11 |
| 8. Discord Enrichment and External Jumps | v1.0 | 3/3 | Complete | 2026-03-13 |
| 9. Item & Note CRUD Wiring | v1.0 | 4/7 | In Progress | - |
| 10. Refresh & Auto-Archive Runtime Wiring | v1.0 | 4/4 | Complete | 2026-03-21 |
| 11. Projection Pipeline & Sort Fixes | v1.0 | 3/3 | Complete | 2026-03-21 |
| 12. Production Data Client Integration | v1.0 | 5/5 | Complete | 2026-03-21 |
| 12.1. Secure Credential Storage | v1.0 | 3/3 | Complete | 2026-03-21 |
| 12.1.1. Shopify-first card source pipeline | v1.0 | 5/6 | In Progress | - |
| 13. Data Flow Architecture Document | v1.0 | 1/1 | Complete | 2026-03-22 |
| 14. UI Polish | v1.0 | 2/3 | In Progress | - |
| 15. SQLite Foundation and Cleanup | 3/3 | Complete    | 2026-03-23 | - |
| 16. GH Project New Columns | 3/3 | Complete   | 2026-03-24 | - |
| 16.1. Discord Enrichment | 4/4 | Complete    | 2026-03-24 | - |
| 16.2. BUGSWEEPER | 2/3 | Complete    | 2026-03-24 | - |
| 17. Product Catalog | v1.1 | 9/9 | Complete    | 2026-03-26 |
| 18. Card Cloud Storage | v1.1 | 3/3 | Complete    | 2026-03-27 |
| 19.1. LookupModal Dual-Mode | v1.1 | 7/10 | In Progress (gap closure R2) | - |
| 19. Serial Tracking and Returns | v1.1 | 0/TBD | Not started | - |
| 20. Offline Mode | v1.1 | 2/2 | Complete    | 2026-04-11 |
| 20.1. UI Polish and Bug Fixes | v1.1 | 4/4 | Complete    | 2026-04-16 |
| 21. Lists | v1.1 | 0/TBD | Not started | - |

## Backlog

### Phase 999.1: Card urgent toggle in notes popover (BACKLOG)

**Goal:** In the notes popover, add a "Card urgent" toggle at the very top. Toggling it sets an `urgent` state on the card. Cards flagged as urgent display the (i) button as a (!) button with red text and a red border, as a reminder to the user that the card needs prompt followup.

**Requirements:** TBD
**Plans:** 0 plans

Plans:
- [ ] TBD (promote with /gsd-review-backlog when ready)

### Phase 999.2: Unit assignment and lifecycle transition historical tracking (BACKLOG)

**Goal:** Track and visualize the full history of serial unit state transitions and assignment events. Display a graphical timeline showing points for each state transition. Assignment events show the new recipient's avatar and can be clicked to surface the corresponding card above that timeline node.

**Requirements:** TBD
**Plans:** 0 plans

Plans:
- [ ] TBD (promote with /gsd-review-backlog when ready)
