# Phase 8: Discord Enrichment and External Jumps - Context

**Gathered:** 2026-03-12
**Status:** Ready for planning

<domain>
## Phase Boundary

Complete recipient communication shortcuts and outbound navigation from cards. Adds Discord avatar/username display, Discord DM launch, Shopify customer/order links, email copy, and external link error handling. All external actions live in the existing ellipsis menu. Does not add new data sync pipelines or in-app messaging.

</domain>

<decisions>
## Implementation Decisions

### Discord identity on cards
- Small circular avatar (24-28px) to the left of the recipient name on the card face
- When Discord avatar is unavailable, show initials circle (first letter(s) of recipient name in a colored circle)
- Discord username displayed as secondary text below recipient name (e.g., `@alice_discord`)
- When no Discord username exists: fall back to email address sourced from GitHub or Shopify; if neither exists, show "No contact info"
- Discord username + avatar should also appear on the By Recipient discovery mode option grid, not just the card view

### DM launch
- "Open Discord DM" button lives in the existing three-dots/ellipsis menu (not hover-reveal, not on card face)
- Uses `discord://` protocol deep link to open Discord desktop app directly to user profile (`discord://discord.com/users/{user_id}`)
- DM menu item is hidden when recipient has no `discord_user_id` (not shown disabled)
- "Copy Email" menu item also added to ellipsis menu when email is available; copies to clipboard

### Shopify links
- "View Customer" and "View Order" as items in the ellipsis menu, grouped below Discord/email actions with a separator
- Links open in default system browser
- Hidden when URL data is unavailable (no Shopify customer linked = no "View Customer"; no order = no "View Order")
- One card = one Shopify order; "View Order" is always a single link, no sub-menu needed

### Ellipsis menu structure
- Menu items organized in sections with separators:
  1. Communication: Open Discord DM, Copy Email (conditional on data availability)
  2. External links: View Customer, View Order (conditional on data availability)
  3. Card actions: Archive/Unarchive/Archive Now (existing from Phase 7)
- Only show items where data exists; hide unavailable actions entirely

### External jump feedback
- Silent launch on success (no toast, no indicator) — OS handles browser/app switch
- Discord deep link failure: fallback to browser URL (`https://discord.com/users/{user_id}`), then error toast if browser also fails
- All external link errors logged (not just shown in UI)
- "Copy Email" shows brief "Copied to clipboard" toast (~1.5 seconds)

### Claude's Discretion
- Exact avatar circle styling (border, shadow, color generation for initials)
- Exact ellipsis menu item icons and styling
- External URL opening implementation approach (std::process::Command vs crate)
- How to source email from GitHub/Shopify data (field mapping)

</decisions>

<code_context>
## Existing Code Insights

### Reusable Assets
- `discord_username` and `discord_user_id` already exist in core domain (`crates/core/src/domain/recipient.rs`) and service API (`crates/service/src/api/recipients.rs`)
- `shopify_customer_id` exists in core domain; Shopify URLs need to be constructed or stored
- Three-dots ellipsis menu already exists in `card.slint` (lines 345-411) with Archive/Unarchive/Archive Now options
- Toast system already established (5-second archive toasts, 1.5-second Esc toasts) in `main.rs`
- By Recipient discovery option grid exists in Phase 6 implementation

### Established Patterns
- Card hover overlay pattern (top-right, 164px wide) from Phase 7 — but DM goes in ellipsis menu, not hover
- `CardData` struct in `dashboard.slint` is the Slint-side data contract; needs new fields for Discord/Shopify
- `DashboardCardViewModel` in `view_model.rs` is the Rust-side view model; needs corresponding fields
- `RecipientCardSnapshot` in `service_client.rs` bridges service → app; needs Discord/email/Shopify URL fields
- Seed data in `main.rs` `seed_cards()` populates test CardData — needs Discord/Shopify test data

### Integration Points
- `RecipientSnapshot` in service layer already exposes `discord_username` — needs to also expose `discord_user_id`, email, and Shopify URLs
- No existing URL-opening pattern in codebase — Phase 8 introduces this capability
- No existing clipboard pattern — Phase 8 introduces clipboard copy for email
- Ellipsis menu popup in `card.slint` needs new items added above existing archive actions

</code_context>

<specifics>
## Specific Ideas

- The ellipsis menu evolves from a card-action menu to a comprehensive action hub with communication, external links, and card management sections
- Contact info line (below name) serves dual purpose: Discord identity when available, email fallback otherwise — ensures every card has some contact context
- The "Copy Email" action provides quick outreach even when Discord isn't available
- Avatar initials provide visual differentiation between cards even before Discord data is fetched

</specifics>

<deferred>
## Deferred Ideas

None — discussion stayed within phase scope.

</deferred>

---

*Phase: 08-discord-enrichment-and-external-jumps*
*Context gathered: 2026-03-12*
