# Requirements: WITwhat

**Defined:** 2026-02-26
**Core Value:** From dashboard load, the user can find any recipient and confirm shipment state in under 10 seconds.

## v1.0 Requirements (Complete)

### Authentication

- [x] **AUTH-01**: User can configure and securely store a GitHub API token.
- [x] **AUTH-02**: User can configure and securely store a Shopify API token.

### Data Sync

- [x] **DATA-01**: System can import and sync recipients from the configured GitHub Project.
- [x] **DATA-02**: System can link recipient records to Shopify customer profiles.
- [x] **DATA-03**: System can fetch Shopify order, fulfillment, and tracking status per linked recipient.
- [x] **DATA-04**: System can persist normalized recipient/package records in shared state storage.
- [x] **DATA-05**: User can trigger refresh for an individual card.
- [x] **DATA-06**: User can trigger refresh-all from UI and via `F5`.
- [x] **DATA-07**: System auto-polls upstream data every 5 minutes with retry/backoff behavior.

### Card View

- [x] **CARD-01**: Card shows recipient Discord username.
- [x] **CARD-02**: Card shows recipient Discord avatar/icon when available.
- [x] **CARD-03**: Card shows products/items currently in recipient possession.
- [x] **CARD-04**: Card shows image of first item in possession.
- [x] **CARD-05**: Card shows shipment lifecycle status enum (`Not Shipped`, `Label Created`, `In Transit`, `Delivered`, `Return In Transit`, `Returned`).
- [x] **CARD-06**: Card shows date of latest status update.
- [x] **CARD-07**: Card shows latest note.
- [x] **CARD-08**: Card action opens Shopify customer profile in default browser.
- [x] **CARD-09**: Card action opens Shopify order in default browser.
- [x] **CARD-10**: Clicking recipient name opens a floating summary with all items in possession, last shipment date, products received in last shipment, and last status update.

### Item Management

- [x] **ITEM-01**: User can add, edit, and remove WITwhat-owned "items in possession."
- [x] **ITEM-02**: Item model supports non-1:1 mapping with Shopify products.
- [x] **ITEM-03**: User can add/edit latest note for recipient/package context.
- [x] **ITEM-04**: System stores item metadata needed to render first-item thumbnail.

### Discovery and Navigation

- [x] **DISC-01**: Instant fuzzy search begins when user types any letter or space.
- [x] **DISC-02**: UI provides left-side tabs for discovery mode switching.
- [x] **DISC-03**: Discovery modes include `By Status Updated`, `By Ship Date`, `By Recipient`, `By Product Shipped`.
- [x] **DISC-04**: `By Recipient` mode starts with recipient option grid then transitions to filtered card view.
- [x] **DISC-05**: `By Product Shipped` mode starts with product option grid then transitions to filtered card view.
- [x] **DISC-06**: In filtered card view, bottom bar shows additional options for multi-select filtering in current mode.
- [x] **DISC-07**: `Up/Down` arrows cycle discovery mode.
- [x] **DISC-08**: `Esc` once returns current discovery mode to its home screen.
- [x] **DISC-09**: `Esc` twice returns to default discovery mode (`By Status Updated`).

### Archive Behavior

- [x] **ARCH-01**: UI provides `Show archived` checkbox with default unchecked.
- [x] **ARCH-02**: Cards auto-archive when status transitions to `Returned`.
- [x] **ARCH-03**: User can manually override archive state per card.

### Discord Integration

- [x] **DSC-01**: System stores Discord username per recipient.
- [x] **DSC-02**: System stores Discord user ID per recipient.
- [x] **DSC-03**: System fetches/displays Discord avatar where available.
- [x] **DSC-04**: User can open DM context with one click from recipient/card UI.

### Platform

- [x] **PLAT-01**: v1 supports Windows only.

## v1.1 Requirements

### UI Polish (v1.0 Gap Closure)

- [x] **POLISH-01**: User sees RecipientCard with vertical layout (avatar, name, status stack) and toast-is-warning wiring

### Persistence

- [x] **PERSIST-01**: User's card data survives app restart without re-fetching from upstream
- [x] **PERSIST-02**: App reads all dashboard data from SQLite, not in-memory Repository
- [x] **PERSIST-03**: SQLite schema mirrors all entities defined in DATA-FLOW.md (recipients, cards, products, serial instances, notes, pending edits)

### Cloud Storage

- [x] **CLOUD-01**: System can create GH Issues tagged `ww-card` for recipient card records
- [x] **CLOUD-02**: System can update `ww-card` GH Issues when card data changes
- [x] **CLOUD-03**: System can create GH Issues tagged `ww-product` for product catalog entries
- [x] **CLOUD-04**: System can update `ww-product` GH Issues when product data changes
- [x] **CLOUD-05**: Notes are stored as GH Issue comments on `ww-card` issues and synced as `Vec<NoteEntry>`

### Product Catalog

- [x] **PROD-01**: User can browse a standalone product list showing all hardware products
- [x] **PROD-02**: Product entities include product_id, name, image_url, and is_serializable flag
- [x] **PROD-03**: Cards reference products via `product_refs` instead of freeform `item_summary`
- [x] **PROD-04**: User can add serialized products nested under their parent product via the product add UI
- [x] **PROD-05**: User can create new serialized product instances from a parent product

### Serial Tracking

- [x] **SERIAL-01**: User can view serial instances per product with lifecycle state
- [x] **SERIAL-02**: Serial instance states follow: Created, Assigned, In Transit, Delivered, Return In Transit, Returned, Available
- [x] **SERIAL-03**: System enforces single-active-assignment invariant (one serial can only be assigned to one card)
- [x] **SERIAL-04**: Fuzzy search matches serial numbers when searching cards and products

### Deprecated Field Cleanup

- [x] **CLEAN-01**: `github_profile_url` removed from all structs and queries (RULE-01)
- [x] **CLEAN-02**: Shipment status/tracking fields moved off Recipient to card-level (RULE-02)
- [x] **CLEAN-03**: `item_summary` replaced by `Vec<ProductRef>` on cards (RULE-07)
- [x] **CLEAN-04**: `latest_note` replaced by `Vec<NoteEntry>` on cards (RULE-08)

### GH Project Columns

- [x] **GHCOL-01**: System ingests `Purpose` column from GH Project and displays colored avatar border on cards
- [x] **GHCOL-02**: Purpose value shows as tooltip on card header hover and in recipient summary popover
- [x] **GHCOL-03**: System ingests `Vision Rx OD` and `Vision Rx OS` columns from GH Project
- [x] **GHCOL-04**: Vision Rx values display in recipient summary popover with inline editing
- [x] **GHCOL-05**: System ingests product parallel-array columns (`product_names`, `product_shopify_urls`, `product_serials`) from GH Project

### Discord Enrichment (Phase 16.1)

- [x] **DSC-05**: User can inline-edit Discord username in summary popover with GH Project write-back
- [x] **DSC-06**: System resolves Discord username to user_id via Discord API guild member search
- [x] **DSC-07**: System fetches Discord avatar image from CDN and caches to local disk at `%APPDATA%/WITwhat/avatars/`
- [x] **DSC-08**: Card displays real Discord avatar image when cached, initials circle when not
- [x] **DSC-09**: User can configure Discord bot token in Settings modal stored in WCM
- [x] **DSC-10**: Settings modal shows Discord bot token management (add, change, clear) with confirmation
- [x] **DSC-11**: Summary popover shows redesigned field order: Purpose, Email, Discord Username, Products in Possession, Last Activity, Last Status Update, Vision Rx
- [x] **DSC-12**: Vision Rx OD/OS and Discord Username fields show pencil icon edit affordance
- [x] **DSC-13**: Last Activity field replaces Last Shipment Date and Last Received with status-mapped display (InTransit->"Shipped", ReturnInTransit->"Returning")

### Offline Mode

- [ ] **OFFLINE-01**: App detects connectivity loss and continues functioning with cached SQLite data
- [ ] **OFFLINE-02**: Edits made while offline are queued and flushed when connectivity returns
- [ ] **OFFLINE-03**: Flush-then-sync ordering prevents sync from overwriting pending edits

### Start Return

- [x] **RETURN-01**: User can initiate a return from a Delivered card via UI action
- [x] **RETURN-02**: Start Return transitions serial instance state from Delivered to Return In Transit
- [x] **RETURN-03**: Start Return writes state change to GH Issue (ww-card + ww-product)
- [x] **RETURN-04**: Start Return opens Shopify return page (`[order_url]/return`) in default browser

### Lists

- [ ] **LIST-01**: User can create, rename, and delete named lists
- [ ] **LIST-02**: User can add and remove cards from lists
- [ ] **LIST-03**: User can view a list as a filtered card view
- [ ] **LIST-04**: Cards can belong to multiple lists simultaneously

## v2 Requirements

### Shopify Write Actions

- **SHOP-01**: Generate return shipping labels from WITwhat.
- **SHOP-02**: Post comments to Shopify order timeline from WITwhat.

## Out of Scope

| Feature | Reason |
|---------|--------|
| Shopify return label generation in v1.1 | Complex carrier/address workflow; v1.1 opens Shopify return page instead |
| Real-time collaborative editing / WebSocket sync | Low conflict rate for small team; offline flush covers real failure mode |
| Full in-app product editor (images, SKU management) | Product data managed in GH Issues; WITwhat reads and caches |
| Per-user authentication and role model | Internal tooling with shared credentials via WCM |
| Cross-platform desktop support | v1.x is Windows only |
| In-app Discord messaging/bot workflows | v1.x focuses on identity/avatar + DM launch |

## Traceability

| Requirement | Phase | Status |
|-------------|-------|--------|
| AUTH-01 | Phase 1 | Complete |
| AUTH-02 | Phase 1 | Complete |
| DATA-01 | Phase 2 | Complete |
| DATA-02 | Phase 2 | Complete |
| DATA-03 | Phase 2 | Complete |
| DATA-04 | Phase 1 | Complete |
| DATA-05 | Phase 10 | Complete |
| DATA-06 | Phase 10 | Complete |
| DATA-07 | Phase 2 | Complete |
| CARD-01 | Phase 8 | Complete |
| CARD-02 | Phase 8 | Complete |
| CARD-03 | Phase 3 | Complete |
| CARD-04 | Phase 3 | Complete |
| CARD-05 | Phase 3 | Complete |
| CARD-06 | Phase 3 | Complete |
| CARD-07 | Phase 3 | Complete |
| CARD-08 | Phase 11 | Complete |
| CARD-09 | Phase 11 | Complete |
| CARD-10 | Phase 4 | Complete |
| ITEM-01 | Phase 9 | Complete |
| ITEM-02 | Phase 1 | Complete |
| ITEM-03 | Phase 9 | Complete |
| ITEM-04 | Phase 4 | Complete |
| DISC-01 | Phase 6 | Complete |
| DISC-02 | Phase 5 | Complete |
| DISC-03 | Phase 5 | Complete |
| DISC-04 | Phase 6 | Complete |
| DISC-05 | Phase 6 | Complete |
| DISC-06 | Phase 6 | Complete |
| DISC-07 | Phase 5 | Complete |
| DISC-08 | Phase 5 | Complete |
| DISC-09 | Phase 5 | Complete |
| ARCH-01 | Phase 7 | Complete |
| ARCH-02 | Phase 10 | Complete |
| ARCH-03 | Phase 7 | Complete |
| DSC-01 | Phase 1 | Complete |
| DSC-02 | Phase 1 | Complete |
| DSC-03 | Phase 8 | Complete |
| DSC-04 | Phase 8 | Complete |
| PLAT-01 | Phase 1 | Complete |
| POLISH-01 | Phase 15 | Complete |
| PERSIST-01 | Phase 15 | Complete |
| PERSIST-02 | Phase 15 | Complete |
| PERSIST-03 | Phase 15 | Complete |
| CLOUD-01 | Phase 18 | Complete |
| CLOUD-02 | Phase 18 | Complete |
| CLOUD-03 | Phase 17 | Complete |
| CLOUD-04 | Phase 17 | Complete |
| CLOUD-05 | Phase 18 | Complete |
| PROD-01 | Phase 17 | Complete |
| PROD-02 | Phase 17 | Complete |
| PROD-03 | Phase 17 | Complete |
| PROD-04 | Phase 17 | Complete |
| PROD-05 | Phase 17 | Complete |
| SERIAL-01 | Phase 19 | Complete |
| SERIAL-02 | Phase 19 | Complete |
| SERIAL-03 | Phase 19 | Complete |
| SERIAL-04 | Phase 19 | Complete |
| CLEAN-01 | Phase 15 | Complete |
| CLEAN-02 | Phase 15 | Complete |
| CLEAN-03 | Phase 15 | Complete |
| CLEAN-04 | Phase 15 | Complete |
| GHCOL-01 | Phase 16 | Complete |
| GHCOL-02 | Phase 16 | Complete |
| GHCOL-03 | Phase 16 | Complete |
| GHCOL-04 | Phase 16 | Complete |
| GHCOL-05 | Phase 16 | Complete |
| DSC-05 | Phase 16.1 | Complete |
| DSC-06 | Phase 16.1 | Complete |
| DSC-07 | Phase 16.1 | Complete |
| DSC-08 | Phase 16.1 | Complete |
| DSC-09 | Phase 16.1 | Complete |
| DSC-10 | Phase 16.1 | Complete |
| DSC-11 | Phase 16.1 | Complete |
| DSC-12 | Phase 16.1 | Complete |
| DSC-13 | Phase 16.1 | Complete |
| OFFLINE-01 | Phase 20 | Pending |
| OFFLINE-02 | Phase 20 | Pending |
| OFFLINE-03 | Phase 20 | Pending |
| RETURN-01 | Phase 19 | Complete |
| RETURN-02 | Phase 19 | Complete |
| RETURN-03 | Phase 19 | Complete |
| RETURN-04 | Phase 19 | Complete |
| LIST-01 | Phase 21 | Pending |
| LIST-02 | Phase 21 | Pending |
| LIST-03 | Phase 21 | Pending |
| LIST-04 | Phase 21 | Pending |

**Coverage:**
- v1.0 requirements: 40 total (all complete)
- v1.1 requirements: 47 total (38 original + 9 Phase 16.1 Discord enrichment)
- Mapped to phases: 47 (all v1.1 requirements mapped)
- Unmapped: 0

---
*Requirements defined: 2026-02-26*
*Last updated: 2026-03-23 after Phase 16.1 planning (DSC-05 through DSC-13)*
