# Feature Research

**Domain:** Prototype device logistics and recipient tracking dashboard — v1.1 new features
**Researched:** 2026-03-22
**Confidence:** HIGH (derived from DATA-FLOW.md authoritative spec + established desktop app patterns)

> This document supersedes the 2026-02-26 FEATURES.md for the v1.1 milestone.
> It focuses exclusively on the new features described in the v1.1 milestone scope.
> Existing v1.0 features (card grid, search, discovery modes, archive, Discord enrichment, item CRUD,
> Shopify-first pipeline) are built and validated; they are not re-litigated here.

---

## Feature Landscape

### Table Stakes (Users Expect These)

Features the operator team assumes exist once v1.1 ships. Missing these = v1.1 is incomplete.

| Feature | Why Expected | Complexity | Notes |
|---------|--------------|------------|-------|
| SQLite persistence — data survives restart | No one expects to lose state after closing the app | HIGH | Full mirror of GH Issues + GH Project data. Replaces in-memory Repository. All reads go through SQLite after implementation (RULE-03). |
| GH Issues round-trip for cards and products | Cloud-of-record must be writable, not just readable | HIGH | `ww-card` and `ww-product` issue create/update/read. GH Issues are authoritative; SQLite is the local mirror (RULE-05). |
| Product catalog — browsable standalone product list | Operators must be able to see what hardware exists without navigating cards | MEDIUM | Products live as `ww-product` GH Issues with `product_id`, `name`, `image_url`, `is_serializable`. Layer 3. |
| Serial instance tracking — per-unit lifecycle | Hardware devices have serial numbers; operators need to know which unit went where | HIGH | Layer 4. State machine: Created → Assigned → In Transit → Delivered → Return In Transit → Returned → Available. Enforces single-active-assignment invariant. |
| Deprecated field cleanup — no ghost fields in structs | Dead fields cause confusion and bugs | MEDIUM | Remove `github_profile_url` (RULE-01), move shipment fields off Recipient (RULE-02), replace `item_summary` with `product_refs` (RULE-07), replace `latest_note` with `Vec<NoteEntry>` (RULE-08). |
| New GH Project columns ingest — Purpose, Vision Rx, product parallel-arrays | GH Project is the source of truth; new columns must flow through sync | MEDIUM | `purpose`, `vision_rx_od`, `vision_rx_os`, `product_names[]`, `product_shopify_urls[]` fields now documented in DATA-FLOW.md Layer 1. |
| Offline mode — app stays usable without connectivity | Network hiccups are common; app must not freeze or lose edits | HIGH | Pending edit queue already exists for optimistic updates. Extend: detect connectivity loss, queue writes, flush-on-reconnect. |

### Differentiators (Competitive Advantage)

Features that are specific to the WITwhat prototype-logistics context and not generic.

| Feature | Value Proposition | Complexity | Notes |
|---------|-------------------|------------|-------|
| Start Return flow — initiate return from a delivered card | Closes the loop without leaving the app; reduces manual Shopify work | MEDIUM | Triggers serial instance state transition (Delivered → Return In Transit). Scope: UI action + GH Issue update + serial state write. Shopify return label is v2+. |
| Lists feature — named groupings of cards | Operators frequently work on cohorts (e.g., "Wave 3 beta testers"); ad-hoc views are fragile | MEDIUM | Lists are a viewing mode (not a new entity type). Cards can belong to multiple lists. Lists stored in SQLite; cloud sync path TBD. |
| Vision Rx surfaced on cards | Prototype devices often need prescription adjustment; having Rx on the card saves a lookup step | LOW | `vision_rx_od` / `vision_rx_os` from GH Project columns, displayed on card detail. |
| Purpose ring on recipient profile picture | Visual at-a-glance categorization (internal tester vs VIP vs press) | LOW | `purpose` field from GH Project drives colored ring in card UI. |
| Product assignment via catalog, not freeform strings | Replacing `item_summary` with validated `product_refs` eliminates data drift | HIGH | Requires Product catalog (Layer 3) to be populated before card assignment is meaningful. |

### Anti-Features (Commonly Requested, Often Problematic)

| Feature | Why Requested | Why Problematic | Alternative |
|---------|---------------|-----------------|-------------|
| Shopify return label generation (v1.1) | Feels like natural next step after "Start Return" | Shopify Returns API is complex; label generation requires carrier selection, address validation, and Shopify Carrier Service setup — easily 2x the scope of Start Return itself | Trigger the Shopify return intent in GH Issue + serial state; generate label in Shopify admin separately (v2). |
| Real-time collaborative editing / WebSocket sync | Multiple users editing the same card simultaneously | Adds significant infra complexity; the actual conflict rate for a small prototype-distribution team is near-zero | Optimistic updates + flush-on-reconnect covers the real failure mode (brief disconnects). |
| Storing serial instances in a separate SQLite table with no GH Issue link | Faster to query locally | Breaks the cloud-of-record invariant (RULE-05). Serial instances must live inside their parent `ww-product` GH Issue body or comments to be authoritative | Keep serial instances inside the `ww-product` GH Issue. SQLite is the cache, not the record. |
| Full in-app product editor (images, SKU management) | Seems productive | Product data is already well-managed in GitHub; duplicating an editor adds surface area | Keep product CRUD in GH Issues (title = name, body = structured metadata). WITwhat reads and caches. |
| Per-user authentication and role model | Multi-user teams expect this | Out of scope for internal tooling with a small fixed team; adds auth infrastructure complexity | Use shared credentials via secure credential storage (Windows Credential Manager, already in scope). |

---

## Feature Dependencies

```
SQLite persistence
    └──requires──> schema design (cards, products, serial_instances, recipients, notes)
                       └──enables──> offline mode (reads still work without network)
                       └──enables──> GH Issues round-trip (SQLite is the write-through cache)

GH Issues round-trip (ww-card / ww-product)
    └──requires──> SQLite persistence (local mirror before cloud write)
    └──enables──> Product catalog (ww-product issues are the product store)
    └──enables──> Notes as Vec<NoteEntry> (GH Issue comments are authoritative)

Product catalog (Layer 3)
    └──requires──> GH Issues round-trip (ww-product is the cloud store)
    └──enables──> Serial instance tracking (serials are sub-entities of products)
    └──enables──> product_refs on cards (replaces item_summary; needs valid product IDs)

Serial instance tracking (Layer 4)
    └──requires──> Product catalog (serial instances are sub-entities of products)
    └──enables──> Start Return (transition Delivered → Return In Transit on a serial)

Deprecated field cleanup
    └──requires──> product_refs replaces item_summary (needs Product catalog)
    └──requires──> Vec<NoteEntry> replaces latest_note (needs GH Issues round-trip for comments)
    └──conflicts──> any feature that reads item_summary or latest_note as canonical

New GH Project columns ingest
    └──requires──> map_rows() update in project_mapping.rs
    └──enables──> purpose ring (UI reads purpose field)
    └──enables──> vision Rx display (UI reads vision_rx_od / vision_rx_os)
    └──enables──> product parallel-array sync (product_names / product_shopify_urls into SQLite)

Offline mode
    └──requires──> SQLite persistence (reads must go through SQLite, not live API)
    └──requires──> pending edit queue (already partially implemented; extend for flush-on-reconnect)
    └──enhances──> GH Issues round-trip (writes queue when offline, flush when back)

Start Return feature
    └──requires──> Serial instance tracking (must transition serial state)
    └──requires──> GH Issues round-trip (write the state change to ww-card and ww-product)
    └──enhances──> card UX (action button on Delivered cards)

Lists feature
    └──requires──> SQLite persistence (list membership stored locally)
    └──enhances──> discovery modes (Lists becomes a new discovery mode or filter layer)
```

### Dependency Notes

- **SQLite is the critical path blocker.** Product catalog, serial tracking, offline mode, and
  full notes history all depend on SQLite being the read/write layer. Nothing from this v1.1
  scope can ship without SQLite first.
- **GH Issues round-trip unlocks cloud storage.** Offline mode requires it (writes queue when
  down). Product catalog requires it (ww-product is the store). Notes history requires it (GH
  comments are the source).
- **Product catalog must precede deprecated field cleanup.** `item_summary` cannot be replaced
  with `product_refs` until Product IDs exist to reference. Cleanup is gated on catalog.
- **Start Return requires serial instances.** You cannot transition a serial without serial
  instances being tracked. Start Return is a late-milestone feature.
- **Lists have no hard blockers** beyond SQLite, making them a good candidate for parallelism
  with heavier features.

---

## MVP Definition

### v1.1 Launch With

The minimum set that closes the DATA-FLOW.md architecture gaps and delivers operational features.

- [ ] SQLite full-mirror cache — replaces in-memory Repository entirely; RULE-03 satisfied
- [ ] GH Issues read/write for ww-card and ww-product — RULE-05 satisfied
- [ ] Product catalog (Layer 3) — standalone product entities browsable in app
- [ ] Serial instance tracking (Layer 4) — per-unit lifecycle state machine enforced
- [ ] Deprecated field cleanup — RULE-01, RULE-02, RULE-07, RULE-08 all resolved
- [ ] New GH Project columns ingest — Purpose, Vision Rx, product parallel-arrays
- [ ] Offline mode with pending edit flush-on-reconnect
- [ ] Start Return feature (serial state transition + GH Issue write)
- [ ] Lists feature (card groupings, SQLite-backed, new discovery mode)

### Add After Validation (v1.x)

- [ ] Shopify return label generation — trigger once Start Return is stable and team requests it
- [ ] Bulk product assignment — assign multiple serials to multiple cards at once
- [ ] List sharing / cloud sync for lists — once Lists usage patterns are understood

### Future Consideration (v2+)

- [ ] Full Shopify write actions (timeline comments, order tags, return label API)
- [ ] Per-user authentication and role model
- [ ] Alerting for stale/blocked serial instances (e.g., In Transit > N days)

---

## Feature Prioritization Matrix

| Feature | User Value | Implementation Cost | Priority |
|---------|------------|---------------------|----------|
| SQLite persistence | HIGH | HIGH | P1 — unblocks everything else |
| GH Issues round-trip (ww-card / ww-product) | HIGH | HIGH | P1 — cloud-of-record requirement |
| Deprecated field cleanup | HIGH | MEDIUM | P1 — technical debt removal required before new features build on clean model |
| New GH Project columns ingest | MEDIUM | LOW | P1 — low cost, unblocks Purpose ring and Vision Rx display |
| Product catalog (Layer 3) | HIGH | MEDIUM | P1 — required for serial tracking and product_refs |
| Serial instance tracking (Layer 4) | HIGH | HIGH | P1 — core operational feature for hardware tracking |
| Offline mode + flush-on-reconnect | HIGH | MEDIUM | P1 — reliability requirement for field use |
| Start Return feature | HIGH | MEDIUM | P2 — depends on serial tracking; high operational value |
| Lists feature | MEDIUM | MEDIUM | P2 — enhances discovery; no hard blockers beyond SQLite |
| Vision Rx / Purpose ring display | LOW | LOW | P2 — low-cost UI wins once columns are ingested |

**Priority key:**
- P1: Must have for v1.1 launch
- P2: Should have; add when P1 features are stable
- P3: Nice to have, future consideration

---

## UX Pattern Notes

These are expected behaviors based on established desktop app conventions and the project's
existing UX model. They inform implementation without being prescriptive about exact UI.

### SQLite Persistence
- First launch after SQLite migration: show a one-time "Loading from cache..." indicator while
  seeding from GH/Shopify. Subsequent launches show stale data immediately then refresh.
- No "Save" button — all mutations write through to SQLite synchronously in the app layer.

### Offline Mode
- Visual indicator when connectivity is lost (distinct from "syncing" state).
- Pending edit count shown when edits are queued (e.g., "3 pending").
- Automatic flush attempt on reconnect, not user-triggered.
- Edits made offline must not be lost on app restart — queue persisted in SQLite.

### Serial Instance Lifecycle
- State displayed on the item square within a card.
- State transitions are explicit actions (not automatic from sync), except:
  - "In Transit" automatically derived from Shopify fulfillment status (existing behavior).
  - "Delivered" automatically derived from Shopify tracking status (existing behavior).
- Start Return is a manual action on a Delivered card — shows confirmation prompt before
  transitioning to Return In Transit.
- "Available" state = serial is back in inventory and can be reassigned.

### Product Catalog
- Accessible as a discovery mode tab or sub-view (consistent with existing left-tab model).
- Products show: name, image, serial instance count (available vs total), Shopify link if present.
- Serializable products show a list of serials with current state and assigned-card link.

### Lists Feature
- Lists appear as a named filter/view in the discovery modes — consistent with existing
  By Status Updated / By Ship Date / By Recipient / By Product Shipped model.
- Adding a card to a list is a secondary action on the card (not disruptive to card grid browsing).
- A card can belong to multiple lists simultaneously.

### GH Issues Write-Back
- Write-back is fire-and-forget with retry from the pending queue on failure.
- Conflict detection: use GH Issue `updated_at` to detect stale writes; surface conflict to user
  rather than silently overwriting.

---

## Sources

- `.planning/DATA-FLOW.md` — authoritative field definitions, layer architecture, RULES 01–08
- `.planning/PROJECT.md` — v1.1 milestone target features and constraints
- Established desktop app patterns for SQLite caching, offline queuing, and lifecycle state
  machines (training data, MEDIUM confidence — verify implementation details during phases)
- Existing WITwhat codebase conventions from Phases 09–14

---
*Feature research for: WITwhat v1.1 — Data Architecture and Product Catalog milestone*
*Researched: 2026-03-22*
