# Phase 16: GH Project New Columns Ingestion - Context

**Gathered:** 2026-03-22
**Status:** Ready for planning

<domain>
## Phase Boundary

Ingest Purpose, Vision Rx OD/OS, and product parallel-array columns from GitHub Project. Surface Purpose as colored avatar border rings on cards with tooltip and chip-bar filters. Display Vision Rx in recipient summary popover with inline editing and Copy Rx. Store product parallel-arrays on recipients for summary display. Product serial ingestion is deferred to Phase 19.

</domain>

<decisions>
## Implementation Decisions

### Purpose color mapping
- Purpose is a GH Project Single Select field with 6 known values: Tester, VIP, Big Team, Marketing, Hardware Dev, Demo Event
- Colors should be discovered from the GH Project API (single-select option colors), not hardcoded
- Every card gets a ring: white fallback when Purpose is empty or unassigned
- Purpose text appears as tooltip on avatar hover AND as a labeled field in the recipient summary popover

### Purpose chip-bar filters
- Purpose values appear as colored filter chips on the existing chip bar alongside other chips (e.g., "Show archived")
- Chips use the same GH-derived color as the avatar ring
- Multi-select toggle behavior: default all off (show everything); clicking activates to filter TO that Purpose
- Multiple Purpose chips can be active simultaneously (additive filtering)

### Vision Rx display & editing
- Vision Rx OD and OS shown in recipient summary popover only (not on card face)
- Inline editable: click to edit, save writes back to GH Project via GraphQL mutation (reuse existing `update_field_text` infrastructure)
- "Copy Rx" button copies both values to clipboard in single-line slash-separated format: `OD {value} / OS {value}`

### Product parallel-arrays
- Columns: `product_names`, `product_shopify_urls` (comma-separated text fields in GH Project)
- `product_serials` column exists but deferred entirely to Phase 19
- These are **permanent** recipient-level fields (not transitional) — they serve both the WITwhat recipient summary and the GH Project UI as glanceable data
- Ingested and stored on the recipients table in SQLite
- Displayed in the recipient summary popover as a product list
- Independent from card-level `product_names` (which comes from Shopify order line items)

### Avatar border treatment
- 2px colored ring around the avatar circle on every card
- Color derived from GH Project Purpose single-select option color
- White ring when Purpose is empty or card is unassigned
- Purpose tooltip triggers on avatar hover only (not entire header)

### Claude's Discretion
- Fallback color strategy if GH API color can't be read or doesn't map well to dark theme
- Exact clipboard formatting details for Copy Rx
- How to handle comma-separated parsing edge cases (trailing commas, whitespace)
- Avatar ring implementation approach within Slint constraints (no per-corner border-radius)

</decisions>

<canonical_refs>
## Canonical References

**Downstream agents MUST read these before planning or implementing.**

### Data architecture
- `.planning/DATA-FLOW.md` — Authoritative data flow reference. Layer 1 (Recipients) field table defines purpose, vision_rx_od, vision_rx_os, product_names, product_shopify_urls as NEW fields. GH Project Column Mapping table shows exact column names.
- `.planning/DATA-FLOW.md` RULE-03 — SQLite is single read source; new fields must flow through SqliteStore
- `.planning/DATA-FLOW.md` RULE-06 — No new data fields without documented source

### Requirements
- `.planning/REQUIREMENTS.md` — GHCOL-01 through GHCOL-05 define the acceptance criteria for this phase

### GH Project ingestion
- `crates/integrations/src/github/project_mapping.rs` — Current field mapping logic (GithubMappedRecipient). Must be extended for Purpose, Vision Rx, and product arrays.
- `crates/integrations/src/github/project_client.rs` — GH Project GraphQL client. Must be extended to fetch single-select option colors.

### Existing UI patterns
- `crates/app/ui/tokens.slint` — Color tokens (Colors global). New Purpose colors should be added here or passed dynamically.
- `crates/app/ui/card.slint` — Card component with avatar area. Avatar ring implementation goes here.
- `crates/app/ui/chip-bar.slint` — Existing chip bar component. Purpose filter chips extend this.
- `crates/app/ui/dashboard.slint` — CardData struct. Must be extended with purpose_color and purpose_label fields.

### SQLite persistence
- `crates/service/src/db/sqlite.rs` — SqliteStore. Recipients table must gain purpose, vision_rx_od, vision_rx_os, product_names, product_shopify_urls columns.

</canonical_refs>

<code_context>
## Existing Code Insights

### Reusable Assets
- `project_mapping.rs`: `map_rows()` already reads fields from `GithubProjectRow.fields` HashMap — extending to read Purpose, Vision Rx, and product arrays follows the same pattern
- `update_field_text` in GH Project client: existing write-back mechanism for Shopify Profile URL — reuse for Vision Rx edits
- Chip bar (`chip-bar.slint`): existing component for filter chips — Purpose chips extend this model
- `SqliteStore`: already has recipients table with upsert logic — add new columns via refinery migration

### Established Patterns
- GH Project fields read as `row.fields.get("ColumnName")` in project_mapping.rs
- Slint color tokens defined in `tokens.slint` Colors global
- Card data flows: GithubMappedRecipient -> Recipient -> RecipientCardSnapshot -> DashboardCardViewModel -> CardData (Slint)
- Chip bar uses ChipData struct with label/active properties

### Integration Points
- `GithubMappedRecipient` struct: extend with purpose, vision_rx_od, vision_rx_os, product_names, product_shopify_urls
- `Recipient` domain model (wit_core): extend with same new fields
- `RecipientCardSnapshot` / `DashboardCardViewModel`: thread purpose_color through to CardData
- `SqliteStore` recipients table: new columns + migration
- Recipient summary popover (built in card.slint): add Vision Rx section, Purpose label, product list
- Chip bar model: extend with Purpose chips alongside existing filter chips
- `apply_filters` in discovery.rs: add Purpose filtering logic

</code_context>

<specifics>
## Specific Ideas

- Purpose colors should match the GH Project UI colors — discover from API, don't guess
- Gray is already in use as a GH Project Purpose color, so the no-Purpose fallback must be white (not gray)
- Copy Rx format: `OD -2.50 +1.00 x180 / OS -3.00 +0.75 x175` (single line, slash-separated)
- Purpose chips should be visually consistent with existing chip bar items but use the Purpose-specific colors

</specifics>

<deferred>
## Deferred Ideas

- `product_serials` column ingestion and display — Phase 19 (Serial Tracking)
- Product parallel-array write-back to GH Project (if card data changes) — future phase after ww-card GH Issues

</deferred>

---

*Phase: 16-gh-project-new-columns-ingestion*
*Context gathered: 2026-03-22*
