Skip to content

Analytics instrumentation: install lifecycle, activation funnel, upgrade funnel #793

@kilbot

Description

@kilbot

Goal: instrument WCPOS with enough telemetry to answer two questions reliably — "how do we make the product better?" and "how do we convert more Free users to Pro?" — using industry-standard SaaS product analytics patterns (AARRR funnel, cohort analysis, feature-flag-driven A/B tests on the upgrade page).

Scope: WP admin side of the Free plugin. POS app events (first launch, first order) and Pro-only feature usage live in their respective repos and are out of scope here.


North Star Metric

Activated sites per week — defined as sites that have placed at least one POS order in the last 7 days. This is the single number that captures "the product is working for the user." Everything we build should move this.

Secondary KPI: Free → Pro conversion rate (sites that activate a Pro license within 30 days of install).


Identification model

  • distinct_id = `user_uuid` (random per WCPOS user, already exists)
  • group: site with key = `site_uuid` (random per install, already exists)
  • Always call `posthog.group('site', site_uuid, {...site_props})` alongside every `capture()` so events can be aggregated by install

User properties (`$set` on identify)

  • `user_role` (administrator / shop_manager / cashier / other)
  • `wcpos_edition` (free / pro)
  • `wcpos_version`

Group properties on `site` (update daily via scheduled event)

Already-collected Landing_Profile fields plus a few additions:

  • `php_version`, `wp_version`, `wc_version`, `mysql_version`
  • `wc_country`, `wc_currency`, `locale`, `timezone`
  • `multisite`, `hpos_enabled`
  • `days_since_install`
  • `product_count_band` (1-10 / 11-100 / 101-1000 / 1000+)
  • `order_count_band` (same bands)
  • `pos_user_count`
  • `gateway_count` (number of enabled WC gateways, not names)
  • `tax_enabled`, `multi_currency`

Event taxonomy

Naming convention: `snake_case`, `object_action` pattern (e.g. `upgrade_cta_clicked`).

1. Install lifecycle

Event Trigger Key properties
`wcpos_installed` `register_activation_hook` — once, ever Full environment + store snapshot
`wcpos_upgraded` Plugin version changed between loads `from_version`, `to_version`
`wcpos_deactivated` `register_deactivation_hook` `days_since_install`, `total_pos_orders`
`wcpos_uninstalled` `uninstall.php` Same as deactivated

Why it matters: tells us install volume, upgrade velocity, churn rate, and time-to-churn. Without this we're blind on retention.

2. Activation funnel

Event Trigger Key properties
`admin_landing_viewed` WCPOS admin landing page load `settings_summary` object
`settings_section_viewed` Any settings tab opened `section` (general / checkout / access / tools / logs / license)
`pos_app_opened` "View POS" clicked Not POS-internal events — just the admin-side transition

Note: The deep activation events (`pos_first_launch`, `pos_first_order`) live in the POS app repo. The admin-side `pos_app_opened` is our proxy until those are wired.

3. Upgrade funnel ⭐ (highest ROI — build first)

Event Trigger Key properties
`upgrade_cta_viewed` Any Pro upsell UI rendered on screen `placement` (admin_landing_banner, settings_header, pos_only_products_tooltip, gateways_list_disabled, etc.)
`upgrade_cta_clicked` Pro upsell clicked `placement`, `destination` (wcpos.com/pricing, wcpos.com/features, etc.)
`license_activate_attempted` License key submit
`license_activate_succeeded` Server returned valid license `license_tier` if available
`license_activate_failed` Server rejected license `reason` enum: `invalid_key` / `expired` / `network` / `server_error` — never the raw error message
`pro_plugin_installed` Fired from Pro plugin on first activation `days_since_free_install`

Why it matters: this is the entire reason to instrument. Without it we can't A/B test the upgrade page or know what's working. If we can only afford one phase, build this.

4. Feature adoption snapshot (cheap, high-value)

Include `settings_summary` as a property on `admin_landing_viewed` with current state of:

  • `pos_only_products`, `decimal_qty`, `force_ssl`, `generate_username`
  • `default_customer_is_cashier`, `restore_stock_on_delete`
  • `barcode_field` → just `'default'` or `'custom'`, not the raw value
  • `tracking_consent` state
  • `enabled_gateway_count`

Why it matters: gives us feature-adoption metrics from a single event instead of N per-change events. PostHog query: "% of sites with `decimal_qty` enabled" is trivial.

5. Consent notice

Event Trigger
`consent_notice_viewed` Admin notice rendered
`consent_notice_accepted` Allow clicked
`consent_notice_declined` No thanks clicked
`consent_notice_dismissed` Generic dismiss (X button)

Why it matters: tells us if our consent prompting is working, informs the copy/timing tweaks from #791.


What we're deliberately NOT collecting

  • Every setting toggle — use the `settings_summary` snapshot instead
  • Every admin page view — only WCPOS-specific screens, not generic WP admin
  • Session replay / heatmaps — privacy-heavy, not needed at this stage
  • Per-order telemetry — no order totals, line items, SKUs, prices, customer info
  • Gateway names — count only
  • Admin email / site URL / IP address

This matches the disclosure modal copy from #791 and PR #792.


A/B testing enablement

Once the upgrade funnel events are flowing, use PostHog feature flags to:

  • Test upgrade page copy variants (headlines, pricing framing, feature list order)
  • Test CTA placement on the admin landing page
  • Test notice timing (immediate / 7-day delay / after first order)
  • Test which Pro features to highlight based on what the site actually uses

Every variant gets its own `variant` property on `upgrade_cta_viewed` so conversion rates can be compared directly.


Dashboards to build in PostHog

  1. Install health — daily new installs, 7/30/90-day retention curves, deactivation rate
  2. Activation funnel — installed → landing → POS app opened → (eventually) first order; drop-off % at each step
  3. Upgrade funnel — CTA viewed → CTA clicked → license attempted → license succeeded; by placement
  4. Feature adoption — % of sites using each feature, segmented by store size and country
  5. Environment distribution — PHP / WP / WC / MySQL version mix; country / currency mix
  6. Store size distribution — product and order count band histogram
  7. Consent conversion — % of sites that see the notice → % that accept

Implementation phases

Ship in order. Each phase is shippable on its own and starts producing data immediately.

Phase 1 — Upgrade funnel (highest ROI)

  • `upgrade_cta_viewed` / `upgrade_cta_clicked` on every Pro upsell in the admin
  • `license_activate_*` trio
  • Basic site group identification
  • Outcome: we can run A/B tests on the upgrade page and measure conversion.

Phase 2 — Install lifecycle

  • `wcpos_installed` / `wcpos_upgraded` / `wcpos_deactivated` / `wcpos_uninstalled`
  • Full group property set on install
  • Daily scheduled group property refresh (cron)
  • Outcome: retention and churn metrics.

Phase 3 — Feature adoption + consent

  • `settings_summary` on `admin_landing_viewed`
  • `settings_section_viewed`
  • `consent_notice_*` events
  • Outcome: feature prioritization data, consent UX optimization.

Phase 4 — POS activation (cross-repo)

  • `pos_app_opened` from admin
  • Coordinate with POS app repo for `pos_first_launch` / `pos_first_order`
  • Outcome: full activation funnel end-to-end.

Dependencies

  • PostHog project is already configured (see auto-memory: reference_posthog_config.md)
  • `Landing_Profile` service already collects most group properties — extend it rather than rebuilding
  • All telemetry gated on `tracking_consent === 'allowed'`

Related: #791 (consent UX), #792 (Privacy modal UI)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions