CAR-607 ยท cur8-mob

Deal Details V3 Analytics Plan

Tracking plan for the DDV3 screens under src/screens/deal, following the onboarding conventions and the shared @ifgengineering/client-analytics package.

How analytics works in cur8-mob today

What DDV3 already fires

EventPropsWhere
cur8:dealDetails_pageViewed / cur8:portfolioDetails_pageViewedinvestment_name, source: "DDV3"Main screen on mount
cur8:dealDetailsTab_clickeddeal_nameDetails tab selection only (Activity direction untracked)
cur8:dealDetailsInvest_clickedcta: "investNow"|"addMoney", deal_nameSticky CTA, add money, new commitment
cur8:dealDescription_readdeal_id, max_scroll_depth_pct, time_on_page_secondsDescription screen on unmount
cur8:earningsCalendarEntryPointClickeddeal_name, deal_id, is_investorEarnings calendar CTA
cur8:dealDetailsEditCommitment_clickeddeal_name, entity_name, type: "oneOff"Payment receipt modify action
Activity timeline card clickeddealName, activityTypePayment + reallocation rows only
Document page viewedsource: "Timeline", page: "deal docs"Manage drawer documents

Legacy parity check

The old screen (home/dealDetails/) fires: page view, invest clicked, watchlist toggle, earnings calendar, generate statement, deal tour. DDV3 keeps page view, invest, and earnings calendar. Watchlist, statement, and tour don't exist in DDV3, so nothing to port.

The source: "DDV3" prop on shared events is what lets dashboards compare old vs new conversion. It must stay on every shared event.

Gaps and proposed events

P0Funnel and parity: do before rollout

  1. Fix cur8:dealDetailsTab_clicked: fire on both directions, add tab: "details"|"activity". Also fire on swipe, not just toggle tap.
  2. cur8:dealDetailsInvestBlocked_shown { deal_id, deal_name, reason: "kyc"|"cooldown"|"onboarding"|"closed" }: fired when a blocker/verify/24h modal intercepts the invest CTA. This is the funnel drop-off we currently can't see.
  3. cur8:dealDetailsDocument_opened { deal_id, deal_name, document_title, document_category, action: "view"|"download" }: DocumentsSection rows and manage-drawer docs.
  4. cur8:dealDetailsWhyWeInvest_pageViewed { deal_id, deal_name }: supporting screen currently has no event.
  5. Extend activity row tracking to all 8 receipt categories via the existing triggerActivityTimelineCardClicked in use-activity-routing.ts (today only payment/reallocation rows fire).

P1Engagement

  1. cur8:dealDetailsCalculator_used { deal_id, deal_name }: first interaction with the embedded calculator per screen view (once per mount). Full-calculator link reuses existing cur8CalculatorEntryPointClicked with entry_point: "deal_details".
  2. cur8:dealDetailsVideo_played { deal_id, deal_name, video_type: "deal_video"|"webinar_replay" }
  3. cur8:dealDetailsWebinar_clicked { deal_id, deal_name, action: "register"|"replay" }
  4. cur8:dealDetailsGlossary_opened { deal_id, deal_name, term_key }
  5. cur8:dealDetailsManageHolding_opened and cur8:dealDetailsManageHolding_optionClicked { option: "manageEarnings"|"moveToIsa"|"documents"|"liquidate" }
  6. cur8:dealDetailsShariaCta_clicked { deal_id, deal_name }
  7. Investment updates: reuse existing cur8:investmentUpdate_viewed / cur8:investmentUpdatesTab_clicked with a source: "DDV3" prop rather than new events.

P2Deliberately not tracking (noise)

Pull-to-refresh, back buttons, glossary dismiss, per-tick calculator slider changes, "Show all activity" expander, holding carousel swipes, bank account prompt (child already receives analyticsLocation), Dealbot open (existing cur8:dealBot_* family covers it), IF-ISA card (existing ISA funnel events cover the next screen).

Property conventions for new events

Implementation approach

  1. Package first: add payload interfaces to packages/client-analytics/src/types.ts (AnalyticsActions) and wire-name mappings to the switch in src/index.ts. Workspace symlink means no publish step for local dev.
  2. One DRY hook: add use-deal-analytics.ts in src/screens/deal that pre-binds { deal_id, deal_name, source: "DDV3" } and exposes typed trigger functions, mirroring useCommitmentAnalytics.
  3. Wire the P0 events, then P1, keeping each trigger at the interaction site (component/hook), never in redux.
  4. Tests: jest contract tests asserting each trigger fires the right action key with the right props, matching the existing analytics test pattern.
  5. QA: verify events in Mixpanel EU with the source: "DDV3" filter before enabling FF_DEAL_DETAILS_V3 more widely.

Open questions