cocottetech/@platform/codebase/@features/ai-copilot/docs/T-analytics-dashboard.brief.md
2026-05-18 22:15:12 -07:00

278 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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).