# Phase 13: Data Flow Architecture Document - Context

**Gathered:** 2026-03-22
**Status:** Ready for planning

<domain>
## Phase Boundary

Create a professional, authoritative data flow reference document (`.planning/DATA-FLOW.md`) that maps every data entity, source, sync direction, storage layer, and transformation in the app. This document becomes the single source of truth for agents building features. Also add a CLAUDE.md enforcement blurb requiring agents to read and maintain the document.

This phase produces documentation and a CLAUDE.md update only -- no code changes.

</domain>

<decisions>
## Implementation Decisions

### Document Format
- Layered reference style (like an API spec / data dictionary hybrid)
- Each data layer gets its own section with field tables and source annotations
- ASCII flow diagrams showing sync pipeline, write-back paths, and fallback behavior
- Both descriptive (what exists) and prescriptive (rules agents must follow)

### Document Location
- `.planning/DATA-FLOW.md` alongside PROJECT.md, REQUIREMENTS.md, ROADMAP.md

### Data Layer Definitions

#### RECIPIENTS (from GitHub Project)
- **Source:** GitHub Project columns
- **Existing GH columns:** Title, Shopify Profile URL, Purpose, Vision Rx - OD, Vision Rx - OS
- **New GH columns needed:** discord_username, discord_user_id, product names (parallel array), product Shopify URLs (parallel array)
- **CORRECTION:** `github_profile_url` does NOT exist and was never intended -- was an early incorrect assumption by agents. Must be documented prominently so agents never re-introduce it.
- **Purpose field** determines a colored ring around the recipient's profile pic in the UI
- **Vision Rx** fields (OD = right eye, OS = left eye) are recipient-level detail data
- Recipients are people, NOT shipments. `shipment_status` and `tracking_state` do NOT belong on recipients -- they belong on cards.

#### CARDS (from Shopify orders + GitHub Issues)
- **Primary source:** Shopify orders tagged "wit-what" (Shopify-first pipeline)
- **Cloud storage:** GitHub Issues in `BigscreenVR/beyond-outgoing` repo, tagged `ww-card`
  - Issue body = structured metadata (recipient_key, product assignments with serial numbers, shipment references)
  - Issue comments = timestamped notes (each comment = one note with date + content)
- **`recipient_name` renamed to `recipient_key`** -- cards reference a valid recipient key, not a display name. Unassigned cards use `unassigned_customer_name` for display.
- **`first_item_image_hint` retired** -- products are now displayed as individual image squares, one per product
- **Notes are a collection** `{date, content}[]`, not a single `latest_note` string. UI surfaces the most recent note.
- **`item_summary` replaced** with deterministic product reference list (product IDs/names assigned to that card)
- **Shipment status and tracking state** are card-level fields sourced from Shopify fulfillment/tracking data

#### PRODUCTS (new layer -- GitHub Issues)
- **Cloud storage:** GitHub Issues in `BigscreenVR/beyond-outgoing` repo, tagged `ww-product`
  - Issue body = product definition (name, image URL, Shopify product URL if linked, serializable flag)
- **Standalone catalog** -- products can be Shopify-linked OR manually created (no Shopify URL required)
- **Two product types:**
  - **Serializable** -- tracked instances with inventory lifecycle. Each instance has a serial number (e.g. "PC-001"). Can only be assigned to one active card at a time. Must be returned before reassignment.
  - **Non-serializable** -- freely assignable to any number of cards. No inventory tracking.
- **GH Project parallel-array columns** for product data per recipient row: one column for product names, one for Shopify URLs. Indexes align to form product tuples. Digested during sync -- unmatched products create new SQLite catalog entries.

#### SERIAL INSTANCES (sub-entity of Products)
- Tracked at the product catalog level, assigned to cards
- Lifecycle: Created -> Assigned -> In Transit -> Delivered -> Return In Transit -> Returned -> Available
- Only one active assignment per serial instance at a time
- Cloud storage: within the parent product's GH Issue (body or structured comment TBD during planning)

### SQLite Cache Architecture
- **Full mirror** of all entities (recipients, cards, products, serial instances, notes)
- **App always reads from SQLite** -- sync updates SQLite from GH/Shopify sources
- **Offline mode:** show cached data with persistent offline indicator. Edits queue locally and sync when connection returns. No functionality disabled.
- **Schema:** App-optimized relational schema with normalized tables and foreign keys (NOT JSON blobs mirroring GH structure)
- **Location:** `%APPDATA%/WITwhat/` directory (alongside existing config.toml, archive_store.json)
- **Conflict resolution:** Last-write-wins with audit log table for all overwrites

### CLAUDE.md Enforcement
- Short pointer (3-5 lines) in CLAUDE.md pointing to `.planning/DATA-FLOW.md`
- 2-3 critical inline rules:
  - No new data fields without a documented source in DATA-FLOW.md
  - SQLite is the single read source for the app
  - GH Issues (`ww-card`, `ww-product`) are the cloud of record
- **Mandatory read + update obligation:** agents must read DATA-FLOW.md before data-touching work AND update it when they change data architecture

### Claude's Discretion
- Exact ASCII diagram style and detail level
- Table formatting choices within the layered reference structure
- How to organize the prescriptive rules section (inline per layer vs. consolidated)
- Level of detail for serial instance lifecycle documentation

</decisions>

<canonical_refs>
## Canonical References

**Downstream agents MUST read these before planning or implementing.**

### Project Context
- `.planning/PROJECT.md` -- Core value, constraints, key decisions
- `.planning/REQUIREMENTS.md` -- v1 requirement definitions and traceability
- `.planning/ROADMAP.md` -- Phase sequence and success criteria

### Current Data Architecture (to analyze and document)
- `crates/core/src/domain/recipient.rs` -- Recipient domain model (contains incorrect github_profile_url assumption)
- `crates/core/src/domain/package.rs` -- Package domain model
- `crates/core/src/domain/item.rs` -- Item domain model with OwnershipMode
- `crates/app/src/service_client.rs` -- RecipientCardSnapshot, DashboardDataClient trait
- `crates/app/src/dashboard/view_model.rs` -- DashboardCardViewModel
- `crates/app/src/dashboard/projection.rs` -- Snapshot -> ViewModel projection
- `crates/app/src/live_client.rs` -- LiveClient, sync pipeline, SyncUpdateCallback
- `crates/app/src/config.rs` -- AppConfig (TOML)
- `crates/app/src/dashboard/archive.rs` -- ArchiveStore, ArchiveState lifecycle
- `crates/app/src/dashboard/edit_queue.rs` -- PendingEditQueue
- `crates/integrations/src/github/project_client.rs` -- GithubProjectClient trait
- `crates/integrations/src/github/project_mapping.rs` -- GH row -> GithubMappedRecipient mapping
- `crates/integrations/src/shopify/order_fulfillment_client.rs` -- Shopify order/fulfillment/tracking traits
- `crates/integrations/src/shopify/http_client.rs` -- HTTP Shopify client implementation
- `crates/service/src/db/repository.rs` -- In-memory Repository (current storage)
- `crates/app/ui/dashboard.slint` -- CardData struct, DashboardWindow properties/callbacks

### External Systems
- GitHub Project: `https://github.com/orgs/BigscreenVR/projects/11/views/19`
- GitHub Repo for Issues: `BigscreenVR/beyond-outgoing` (cards tagged `ww-card`, products tagged `ww-product`)

</canonical_refs>

<code_context>
## Existing Code Insights

### Reusable Assets
- `RecipientCardSnapshot` struct: good starting point for understanding current card data shape, but needs significant revision per decisions above
- `DashboardCardViewModel`: current view model -- document what changes are needed
- `ArchiveStore` + `PendingEditQueue`: existing local persistence patterns that inform SQLite migration

### Established Patterns
- Layered transformation: Raw API -> Domain model -> Snapshot -> ViewModel -> Slint CardData
- Background sync thread with `slint::invoke_from_event_loop` for UI updates
- Trait-based client abstraction (`DashboardDataClient`, `GithubProjectClient`, `ShopifyOrderFulfillmentClient`)
- Optimistic concurrency with version fields

### Integration Points
- The data flow document will reference every layer in the existing transformation pipeline
- CLAUDE.md already exists at repo root -- append enforcement blurb

</code_context>

<specifics>
## Specific Ideas

- User wants the document to be a "professional, core project document" -- high quality, not a draft
- Products stored in GH Project use parallel-array column encoding: one column for names, one for Shopify URLs, indexes aligned
- `github_profile_url` correction must be prominently documented since agents have been using it incorrectly
- Separation of recipient-level vs card-level data ownership must be crystal clear
- Serial number tracking for serializable products is explicitly desired even though it adds complexity
- The document should serve as "a consistent reference for what to and not to do when building new features"

</specifics>

<deferred>
## Deferred Ideas

- **SQLite migration implementation** -- this phase documents the architecture; actual SQLite implementation is a future phase
- **GH Issues storage implementation** -- creating and reading `ww-card` / `ww-product` issues is a future phase
- **Product catalog UI** -- building the product management interface is a future phase
- **Serial number tracking UI** -- inventory management views are a future phase
- **Parallel-array GH column creation** -- actually adding the new columns to GH Project is a future phase
- **discord_username / discord_user_id GH column creation** -- adding these columns is a future phase

</deferred>

---

*Phase: 13-data-flow-architecture-document*
*Context gathered: 2026-03-22*
