# T — Analytics + business dashboard ## Goal Quinn's daily-driver (brief A) tells her *what wants her attention*. Audit (brief I) tells her *what was done in her name*. Neither tells her *how her business is performing*. The `strategist` specialist already produces these reads ("the OF cohort cooled since Berlin"), but they only land as chat proposals. This brief adds a **pinned dashboard surface** — revenue trends, prospect funnel, cohort warmth, per-surface performance — so Quinn can answer "how am I doing this week" in one tap. The dashboard is the **strategist's front-window**, not a separate specialist. It pulls from the same data sources strategist already reads (engagement_events, content_posts, agent_actions, tour_legs); the dashboard is the *visual* surface for those reads, while chat proposals remain the *conversational* surface. ## Designer skim - **Headline UX**: One scrollable dashboard. Five panels: revenue · prospect funnel · per-surface performance · cohort warmth · tour ledger. Each panel has a default view, a strategist-narrated insight chip, and a "tell me more" tap that opens a chat thread with strategist for that slice. - **Panels (5)**: T1 revenue · T2 funnel · T3 per-surface · T4 cohort warmth · T5 tour ledger. - **Voice lean**: working register throughout — analytical, literary; hearth on insight chips when the news is good; plain when revenue dips or a cohort hard-flatlines. - **Pair-with**: [strategist contract](./specialist-strategist.contract.md), [`day-in-life.flow.md`](./day-in-life.flow.md) (dashboard appears in the day flow when Quinn checks in on web companion). - **Blocking Qs**: see [OPEN-DECISIONS.md](./OPEN-DECISIONS.md) → T-Q1 cadence-of-refresh, T-Q2 web-vs-iOS depth parity. ## States to design - **Each panel** has 4 base states: empty (new user, no data yet) · sparse (some data, low confidence) · typical · anomaly-highlighted. - Whole dashboard: cold-load skeleton; degraded (strategist offline — show last-known with timestamp); offline (use cached, banner). - Per-panel "tell me more" handoff transition to chat. - Per-panel time-window pickers (7d / 30d / 90d / custom). - Comparison-mode (this period vs prior period) — toggle at top. - Insight-chip variants: positive, neutral, anomaly, plain (failure-adjacent). ## T1 — Revenue panel **Default view**: a single number (current period gross), trend sparkline, comparison to prior equivalent period, breakdown chip stack (OF / Tryst / TS4Rent / PPV / tips / other). **Insight chip** (strategist-narrated): > Up 18% over last 30 days — OF subscribers carrying it. Tryst is flat. **Tap-through**: opens chat with strategist scoped to "explain the revenue movement this period." **Drilldown view (tap the headline number)**: - Daily series with per-source overlay. - Per-source share-of-revenue donut. - "Big days" callouts (top 3 days; tap → audit drawer scoped to that day). **Privacy**: per-leg revenue figures live in audit; T1 aggregates across all sources. Hotel/leg detail revenue stays in R drawer. ## T2 — Prospect funnel panel **Default view**: stacked funnel — Free → DM → Tip → PPV → Subscribe → Booking. Counts per stage, conversion rates between stages, period delta. **Insight chip** (strategist): > 47 prospects entered the funnel this week, 8 reached PPV. The DM→Tip conversion is steady at 14%; below it the drop-off is from PPV pricing — strategist has a price-test proposal ready. **Tap-through**: opens chat — strategist may propose an experiment (per [brief plan P4 conversion experiments]). **Drilldown**: - Per-stage list of prospects (links to brief B3 prospect drawer). - Per-funnel-source breakdown (X-sourced vs Tryst-sourced vs cold). - Cohort retention by entry-week. ## T3 — Per-surface performance panel **Default view**: a row per Quinn-active N1+N2 surface (per [brief O](./O-surfaces-roster.brief.md)). Each row: post count (or bump count for N2 directories), engagement rate, conversion to funnel-stage-2+, period delta. **Insight chip** (strategist): > Instagram drafts are sitting unapproved 4 days on average — content-social wants you to either relax draft-approval there or accept the cooling effect. **Tap-through**: opens specialist drawer for `content-social` (or relevant specialist), pre-filtered to this surface. **Drilldown**: - Per-surface time-series (posts × engagement). - Per-surface auto vs Quinn-approved ratio (cross-references brief I trust panel). - Top-3 posts of period. ## T4 — Cohort warmth panel **Default view**: heat-mapped cohort matrix — entry week × subsequent-week revenue contribution. Newer cohorts on top. **Insight chip** (strategist): > The October cohort is the warmest in 90 days — re-engage before December and they'll likely convert again. Earlier cohorts (Aug, Sep) are cooling; one nudge-DM cluster might revive Sept. **Tap-through**: opens chat — strategist may propose a follow-up DM cluster targeting a cohort. **Drilldown**: - Per-cohort prospect list with funnel-stage snapshot. - "Send a follow-up cluster" affordance — drafts a triage+content-onlyfans DM cluster scoped to a chosen cohort. ## T5 — Tour ledger panel **Default view**: rolling list of past + active + planned legs (per [brief R](./R-tours-events-hotels.brief.md)). Per row: city, dates, planned revenue vs actual, net. **Insight chip** (strategist): > Berlin Oct over-performed (€4,920 vs target €4,200). Amsterdam under-performed (€2,100 vs €3,000). Worth interrogating the Amsterdam hotel choice — Adina worked, the canal-side property didn't. **Tap-through**: opens leg-detail drawer (R2b) for the relevant leg. **Drilldown**: - Cumulative tour-only revenue ribbon. - Per-city historical performance (cities Quinn has visited multiple times — what's the trend?). - Tour vs home-base revenue split. ## Cross-surface aggregation + attribution The panels above (T1 revenue, T2 funnel, T3 per-surface, T4 cohort, T5 tour ledger) all draw on cross-surface data. Three concerns govern how that data is rolled up + how prospect-funnel paths across surfaces get credit. **Owned UX-side here; engineering owned at [_engineering-surface-metrics.md](./_engineering-surface-metrics.md)** (schemas + scheduler + attribution model implementations). ### §T-aggregate — Aggregation across surfaces **What aggregates and what doesn't**: | Panel | Aggregate-canonical? | Sources | |---|---|---| | T1 Revenue | **Yes** — sum across all surfaces with revenue signal | OF subs/tips, Tryst-driven bookings (per [surface-tryst.brief.md §9](./surface-tryst.brief.md)), Fansly, manual ledger entries, content PPV | | T2 Funnel stage counts | **Yes** — counts roll across surfaces; per-source breakdown is a drilldown | Tryst profile-views, X impressions, OF subs, iMessage replies, etc. | | T3 Per-surface | **No** — per-surface by definition; tier-gated empty-states honored per surface's `§canonical-facts` | Single-surface raw | | T4 Cohort warmth | **Yes** — cohort defined by *first cross-surface touchpoint*; warmth weighted by all subsequent touchpoints | All touchpoints | | T5 Tour ledger | **Yes** — per-leg revenue rolls across surfaces in the tour window | All revenue sources during leg dates | **Read path**: panels read from `metric_aggregates` (the materialized rollup table). Engineering's rollup cadence: 15 min active window, 1h recent, daily older, immutable past 90 days. **Freshness UI**: each aggregate panel shows a "computed N min ago" stamp in compact gray text (12pt). Tap to manually re-trigger rollup — `strategist` re-runs over the underlying surface_metrics. Per [T6b](#t6b--refresh-model), the pull-to-refresh affordance is intentionally low-affordance because inference costs real money. **Per-surface contribution breakdown**: every aggregate panel has a `surface_breakdown` chip stack (e.g. T1 revenue: `OF 62% · Tryst 21% · Fansly 17%`). Tap a chip → drilldown filters to that surface. **Tier-gating implication**: if Quinn is on Tryst Basic (no native analytics per [§canonical-facts](./surface-tryst.brief.md)), Tryst contributes nothing to view-count aggregates and shows `—` in surface_breakdown rather than `0` (zero would falsely suggest "no views" — `—` means "unmeasured"). T3 Tryst row shows the upgrade nudge; T1/T2/T4 aggregates honor the absence cleanly. **Insight chip (strategist)**: > Revenue's up 18% — OF carrying it (62% share). Tryst views aren't measured at your tier; jumping to Standard would let me tell you whether Tryst's quietly contributing. ### §T-attribution — Cross-surface touchpoint funnel **Where**: lives inside T2 funnel as an additional view-mode toggle (`Funnel · Top paths`). Default view is stage-counts (T2 above); `Top paths` switches to multi-surface chain visualization. **Top paths view**: ``` Top funnel paths this week ───────────────────────────── Tryst → iMessage → OF subscription · 8 conversions · $312 revenue X → OF subscription · 5 conversions · $185 revenue Eros → iMessage → booking · 3 conversions · $1,800 revenue Tryst → Signal → booking · 2 conversions · $1,200 revenue (11 single-touch paths consolidated) · 11 conversions · $267 revenue ``` Each path is a clickable row → opens chat with strategist scoped to "explain this path; tell me what works." **Per-prospect view** (in `prospect-detail.screen.md` — companion to brief B3): ``` Felix · first-touch Tryst (Apr 8, 14:02) ↓ 19 hours iMessage (Apr 9, 09:14) ↓ 13 hours OF subscription (Apr 9, 22:11) ↓ ongoing 3 tips totaling $47 Attribution credit (time-decay default): Tryst 60% X 0% OF 40% Lifetime revenue: $89 ``` **Privacy** (per [_engineering-surface-metrics §9](./_engineering-surface-metrics.md)): - Anonymous touchpoints (profile_view with no identifier match) **aggregate only** — they count in T2 funnel top-of-funnel totals, never appear in per-prospect paths. - Per-prospect paths are Quinn-only — never visible to coop peers (per [brief N](./N-provider-coop.brief.md)), never shared org-wide pre-explicit-consent (W §W4 deferred). - Brief V data-export covers Quinn's full attribution graph as her data. **Insight chip (strategist)**: > Your warmest path this month is Tryst → iMessage → OF. The Tryst-first prospects who DM within 48h convert at 3× the rate of cold OF subs. Want me to draft a Tryst-bio nudge to point more of them to iMessage faster? ### §T-attribution-model — Model picker A small chrome control in T2 + on prospect-detail.screen.md that selects which attribution model is in use for the displayed numbers: ``` Attribution: [ Time-decay ▾ ] (?) ├─ First-touch ├─ Last-touch ├─ Time-decay (default) └─ Position-based (40/40/20) ``` **Model semantics** (per [_engineering-surface-metrics §8](./_engineering-surface-metrics.md)): - **First-touch** — 100% credit to the earliest surface. Brand-discovery view. - **Last-touch** — 100% credit to the surface that hosted the conversion. Conversion view. - **Time-decay** (default) — exponential decay, 7-day half-life. Balanced; favors recent-but-not-only-recent. - **Position-based** — 40% first / 40% last / 20% middle. Surfaces middle-funnel value. **(?) info popover** explains the choice in plain voice: > Different attribution models tell different stories. Time-decay is the balanced default — Cocotte gives more credit to recent touches without ignoring the first one. Switch to First-touch when you want to see what's bringing prospects in; Last-touch when you want to see what's closing. Same data, different lens. **Persistence**: per-Quinn preference, stored in `users.attribution_model_pref`. Model selection updates instantly (no recompute — engineering computes all four models in parallel; the picker just selects which is displayed). **Tap the (?)** → opens chat with strategist scoped to "help me pick an attribution model." **Insight chip (strategist, when Quinn switches model)**: > Switched to First-touch — Tryst's credit jumped to 78%. That's where prospects discover you. Switch back to Time-decay (default) to see what's actively warming them right now. --- ## T6 — Dashboard chrome and access ### T6a — Where the dashboard lives - **iOS**: a drawer (sibling to brief B's catalog) reached from chat-home's top-bar overflow OR by Quinn saying "show me the dashboard." The drawer dismisses with swipe-back to chat scroll position. - **Web companion** ([brief G §G4](./G-web-surfaces.brief.md)): full-page view (G's CRM-style desktop affordance). Same panels, more drilldown density per panel since desktop has the screen real estate. ### T6b — Refresh model - Default panel data is cached and refreshed by `strategist` once per vigil (per [brief Q](./Q-vigil-journal-auto-conversations.brief.md)) — "morning numbers" pattern. - A subtle pull-to-refresh on the panel re-runs the strategist computation. Per-pull cost is real (LLM calls) so this is intentionally low-affordance. - Streaming panels (revenue current-day, funnel current-day) update on engagement-event arrival via SSE/WebSocket on web companion. iOS uses push for high-stakes anomalies only (per [brief C](./C-notifications.brief.md)). ### T6c — Anomaly surfacing in chat When `strategist` detects an anomaly (revenue spike, funnel collapse, cohort-warmth flatline), the insight chip changes register (plain) and **also** surfaces as a chat message — Quinn shouldn't have to open the dashboard to learn that something broke or surged. Chat is the canonical attention surface; the dashboard is for *intentional* analytical sessions. ### T6d — Comparison mode A toggle at the top: `this week / 30d / 90d` × `vs prior / vs same period last year`. Each panel re-renders with delta callouts. Lean: comparison-vs-prior is the default for `this week`; comparison-vs-last-year is the default for `90d+`. ### T6e — Privacy on the dashboard The dashboard is **operator-facing only**. Never exported, never embedded in outbound, never visible to coop peers (per [brief N](./N-provider-coop.brief.md) coop intel network is separate). Revenue figures are confidential per [brief K §K3-misc](./K-safety-blocklist.brief.md) — never quoted in outbound drafts. ## In-the-wild copy **T1 revenue insight chip, good news** (hearth): > Up 18% over last 30 days — OF subscribers carrying it. Tryst is flat. **T1 revenue insight chip, anomaly** (plain): > Revenue dropped 31% week-over-week. Two OF days missed scheduling because of the platform.api hiccup Tuesday. Audit has the details. **T2 funnel insight chip, opportunity** (working): > 47 in, 8 reached PPV. The DM→Tip stage is your widest leak. Want strategist to draft a price-test? **T3 per-surface insight, friction** (working): > Instagram drafts have been sitting unapproved 4 days on average. Relax draft-only or accept the cooling — your call. **T4 cohort insight, re-engagement opportunity** (hearth): > October cohort is your warmest in 90 days. One nudge-DM cluster before December and they likely come back. **T5 tour ledger insight, mixed result** (working): > Berlin over, Amsterdam under. The canal-side hotel was the difference — Adina-Mitte worked, the canal-side didn't. Worth a re-scout next time. **Pull-to-refresh confirmation** (plain — costs money): > Re-running strategist over 30 days. ~10s, ~$0.04 in inference. **Comparison mode toggle hint** (working): > Compared to last month, you're up across the board except Instagram. Tap a panel to dig in. ## Out of scope - Marketing-funnel analytics for sites Quinn doesn't own (third-party attribution). - Cross-org dashboards (single-Quinn for P0; multi-org with Demimonde is P5+). - Export to PDF / CSV (defer; users will ask if needed). - A/B test infrastructure UI — referenced in T2 conversion experiments but lives in a separate experiments brief if it grows. - Tax / accounting view — Quinn handles separately; not a CocotteAI concern. ## Open questions - **T-Q1** Refresh cadence — strict once-per-vigil or also on app-foreground? Lean: once-per-vigil + manual pull. Foregrounding alone shouldn't burn inference. `[blocking]` - **T-Q2** Web-vs-iOS depth parity — should iOS show all panels at the same depth, or surface a "open in web" affordance for the densest views (e.g. cohort matrix)? Lean: iOS shows summary + key drilldowns; "open in web" for high-density grids like T4 matrix. `[blocking]` - **T-Q3** Anomaly threshold — what counts as worth a chat surfacing vs just an insight-chip change? Lean: ±20% revenue WoW, ±10pp funnel-stage conversion shift, cohort flatline >2 weeks. Engineering-tunable. `[engineering]` - **T-Q4** "Tell me more" handoff continuity — does the chat thread that opens from a panel keep that panel pinned at the top while strategist explains? Lean: yes, the panel pins as a card-style reference while the conversation flows below it. `[nice-to-have]` - **T-Q5** Per-cohort experiments — when Quinn approves a strategist-proposed price test or DM-cluster from the dashboard, where does that action's progress surface afterward? Lean: in the dashboard panel that spawned it, with a "test running, day 3 of 7" status. `[nice-to-have]` - **T-Q6** Attribution model default — Time-decay proposed (7-day half-life); confirm half-life against Quinn's actual sales cycle (SM-Q3 in `_engineering-surface-metrics.md`). `[engineering]` - **T-Q7** Attribution per coop — should cross-coop revenue attribution be visible at all, or strictly per-coop-isolated? Lean: per-coop-isolated unless explicit coop-data-share consent. `[blocking once P5 multi-org lands]` - **T-Q8** "Top paths" view — how many paths to show before consolidating to "(N single-touch paths)"? Lean: top 8 multi-touch + consolidated single-touch tail. `[nice-to-have]` ## Related - [brief I](./I-audit-trust-replay.brief.md) — the *what was done* surface; T is the *how is it going* surface. - [brief A](./A-chat-surface.brief.md) — anomaly surfacing in chat (T6c). - [brief G](./G-web-surfaces.brief.md) §G2 — web companion's CRM view is T's desktop expression. - [brief Q](./Q-vigil-journal-auto-conversations.brief.md) — refresh cadence ties to vigil close. - [brief R](./R-tours-events-hotels.brief.md) §R6 — tour ledger panel feeds back into multi-leg routing. - [strategist contract](./specialist-strategist.contract.md) — T is strategist's front-window. - [voice](./00-system-voice.md) §V4 — strategist voice lean (working). - [brief K](./K-safety-blocklist.brief.md) — revenue figures never echoed outward. - [_engineering-surface-metrics.md](./_engineering-surface-metrics.md) — schemas + ingestion + scheduler + attribution model implementations powering §T-aggregate / §T-attribution / §T-attribution-model. - [_engineering-talent-scout-port.md §0.2](./_engineering-talent-scout-port.md) — design rationale for cross-surface aggregation + attribution. - [specialist-prospect-resolver.contract.md](./specialist-prospect-resolver.contract.md) — touchpoint linking (resolves which touchpoints belong to which prospect). - [surface-tryst.brief.md §canonical-facts](./surface-tryst.brief.md) — tier-gating example (Basic tier shows `—` not `0` in surface_breakdown).