Skip to content

feat: add signup flow metrics and post-signup activity tracking#420

Merged
superdav42 merged 4 commits intomainfrom
feature/issue-297-metrics-onboarding
Mar 25, 2026
Merged

feat: add signup flow metrics and post-signup activity tracking#420
superdav42 merged 4 commits intomainfrom
feature/issue-297-metrics-onboarding

Conversation

@superdav42
Copy link
Copy Markdown
Collaborator

@superdav42 superdav42 commented Mar 25, 2026

Summary

Implements issue #297 (Finish Metrics and Onboarding) and subtask #398 (Track signup flow).

What's added

inc/class-signup-metrics.php — Signup funnel tracking

  • Hooks into wu_checkout_element_render, wu_checkout_order_created, wu_checkout_done, and wu_checkout_errors
  • Records four event types in the existing wu_events table: checkout_started, checkout_step_completed, checkout_completed, checkout_failed
  • All four event types are registered for webhooks and email triggers via wu_register_all_events

inc/class-activity-tracker.php — Post-signup activity tracking

  • Hooks into transition_post_status, user_register, and woocommerce_new_order on customer sub-sites
  • Records site_post_published, site_user_registered, and site_woocommerce_order events at the network level
  • Only tracks sites managed by WP Ultimo (checked via wu_get_site_by_blog_id)
  • Excludes internal/revision post types via EXCLUDED_POST_TYPES constant (filterable)

inc/class-dashboard-statistics.php — Two new statistics methods

  • get_data_signup_funnel(): per-stage event counts + conversion rate (started → completed)
  • get_data_site_activity(): post/user/WooCommerce order counts per date range

inc/class-wp-ultimo.php — Both classes instantiated alongside the existing Tracker singleton

tests/WP_Ultimo/Signup_Metrics_Test.php — Unit tests covering singleton, event type registration, filter pass-through, and dashboard statistics key structure

Design decisions

  • Uses the existing wu_events table — no new DB tables required
  • Events are queryable via the existing admin event log and REST API
  • WooCommerce tracking is opt-in by presence of the woocommerce_new_order hook — no hard WooCommerce dependency
  • Activity tracker uses a static cache to avoid repeated wu_get_site_by_blog_id lookups per request

Closes #297
Closes #398

Summary by CodeRabbit

  • New Features
    • Dashboard now displays signup funnel metrics with conversion rate calculations
    • Dashboard now tracks and displays site activity metrics including posts, custom post types, users, and orders

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 25, 2026

📝 Walkthrough

Walkthrough

These changes implement signup funnel event tracking and post-signup activity monitoring. A new Signup_Metrics class registers WordPress checkout lifecycle hooks to record funnel events (checkout_started, checkout_step_completed, checkout_completed, checkout_failed) into the wu_events table. The Dashboard_Statistics class gains methods to query and aggregate these events with conversion rate calculations. The plugin initialization sequence loads the metrics component.

Changes

Cohort / File(s) Summary
Signup Funnel Tracking
inc/class-signup-metrics.php
New Signup_Metrics class with checkout lifecycle hooks to record four event types (started, step_completed, completed, failed) into wu_events table. Includes event schema registration, IP detection helper, and daily-starts deduplication logic.
Dashboard Query Methods
inc/class-dashboard-statistics.php
Added get_data_signup_funnel() returning event counts with computed conversion_rate (checkout_completed / checkout_started \* 100), and get_data_site_activity() returning post-signup activity counts. Both query wu_events within the existing date range.
Plugin Initialization
inc/class-wp-ultimo.php
Integrated Signup_Metrics singleton instantiation into the main plugin init() bootstrap sequence.
Test Coverage
tests/WP_Ultimo/Signup_Metrics_Test.php
Comprehensive test suite validating singleton pattern, event type registration, checkout error tracking, and Dashboard_Statistics integration including conversion rate calculation and activity key presence.

Sequence Diagram

sequenceDiagram
    actor User
    participant Checkout as Checkout Flow
    participant Metrics as Signup_Metrics
    participant DB as wu_events Table
    participant Dashboard as Dashboard_Statistics

    User->>Checkout: Load checkout page
    Checkout->>Metrics: do_action('wu_checkout_before_render')
    Metrics->>DB: Insert checkout_started event
    
    User->>Checkout: Complete form steps
    Checkout->>Metrics: do_action('wu_checkout_order_created')
    Metrics->>DB: Insert checkout_step_completed event
    
    User->>Checkout: Submit checkout
    alt Checkout Success
        Checkout->>Metrics: do_action('wu_checkout_success')
        Metrics->>DB: Insert checkout_completed event
    else Checkout Failed
        Checkout->>Metrics: do_action('wu_checkout_error')
        Metrics->>DB: Insert checkout_failed event
    end
    
    Dashboard->>DB: Query checkout_* events
    Dashboard->>Dashboard: Calculate conversion_rate
    Dashboard-->>User: Display funnel metrics
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Hop along, dear changelog bright,
Events tracked from checkout to night,
Funnels counted, conversions clear,
Metrics bloom as dashboards cheer! 🌱✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding signup flow metrics and post-signup activity tracking, which matches the primary objectives across all modified files.
Linked Issues check ✅ Passed The PR successfully implements all coding requirements from #297 and #398: signup funnel event tracking via Signup_Metrics class, post-signup activity tracking via Activity_Tracker, dashboard statistics queries via get_data_signup_funnel() and get_data_site_activity(), and comprehensive unit tests validating the implementation.
Out of Scope Changes check ✅ Passed All changes directly support the linked issue objectives: Signup_Metrics tracks checkout funnel, Dashboard_Statistics provides queryable metrics, and Signup_Metrics_Test validates event registration and dashboard integration, with no unrelated modifications detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/issue-297-metrics-onboarding

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

🔨 Build Complete - Ready for Testing!

📦 Download Build Artifact (Recommended)

Download the zip build, upload to WordPress and test:

🌐 Test in WordPress Playground (Very Experimental)

Click the link below to instantly test this PR in your browser - no installation needed!
Playground support for multisite is very limitied, hopefully it will get better in the future.

🚀 Launch in Playground

Login credentials: admin / password

@superdav42
Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 25, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@github-actions
Copy link
Copy Markdown

🔨 Build Complete - Ready for Testing!

📦 Download Build Artifact (Recommended)

Download the zip build, upload to WordPress and test:

🌐 Test in WordPress Playground (Very Experimental)

Click the link below to instantly test this PR in your browser - no installation needed!
Playground support for multisite is very limitied, hopefully it will get better in the future.

🚀 Launch in Playground

Login credentials: admin / password

…#398)

Implements two new tracking classes:

- Signup_Metrics: hooks into the checkout lifecycle to record
  checkout_started, checkout_step_completed, checkout_completed, and
  checkout_failed events in the wu_events table. Each event type is
  also registered for webhooks and email triggers.

- Activity_Tracker: hooks into sub-site WordPress actions to record
  site_post_published, site_user_registered, and site_woocommerce_order
  events for any customer-owned sub-site. Only tracks sites managed by
  WP Ultimo (via wu_get_site_by_blog_id).

Dashboard_Statistics gains two new data methods:
- get_data_signup_funnel(): returns per-stage counts + conversion rate
- get_data_site_activity(): returns post/user/order counts per date range

Both classes are wired up in class-wp-ultimo.php alongside the existing
Tracker singleton. Tests cover singleton behaviour, event type registration,
filter pass-through, and dashboard statistics key structure.

Closes #297
Closes #398
…ty_Manager)

Post_Signup_Activity_Manager was merged into main in #416 before this
branch was rebased. Remove the duplicate Activity_Tracker class and its
instantiation from class-wp-ultimo.php.

Update Dashboard_Statistics::get_data_site_activity() to use the event
slugs produced by Post_Signup_Activity_Manager (subsite_post_created,
subsite_cpt_created, subsite_user_registered, subsite_woocommerce_order)
instead of the now-removed Activity_Tracker slugs.

Update Signup_Metrics_Test to match the corrected slugs.
@superdav42 superdav42 force-pushed the feature/issue-297-metrics-onboarding branch from b6a38b0 to 2da0041 Compare March 25, 2026 03:19
@github-actions
Copy link
Copy Markdown

🔨 Build Complete - Ready for Testing!

📦 Download Build Artifact (Recommended)

Download the zip build, upload to WordPress and test:

🌐 Test in WordPress Playground (Very Experimental)

Click the link below to instantly test this PR in your browser - no installation needed!
Playground support for multisite is very limitied, hopefully it will get better in the future.

🚀 Launch in Playground

Login credentials: admin / password

@superdav42
Copy link
Copy Markdown
Collaborator Author

[Pulse Supervisor] E2E checkout tests are failing on this PR but passing on main (run 23523339169). The regression was introduced by the metrics/Activity_Tracker changes. The 'Run Checkout Tests (After Setup)' step fails — please investigate whether the new metrics hooks interfere with the checkout flow (e.g., hooks firing during checkout that cause unexpected side effects).

wu_checkout_errors is an action (not a filter) that fires with the
checkout form name as a string argument (views/checkout/form.php:23).

The previous implementation used add_filter and declared a return type
of \WP_Error. When the action fired with a string argument, the method
returned the string, causing a PHP TypeError (return type mismatch)
that produced a fatal error on the /register page.

Fix:
- Change add_filter to add_action (correct hook type)
- Change method signature to accept a string form name
- Remove \WP_Error return type (void action callback)
- Access checkout errors via Checkout::get_instance()->errors
- Update test to verify string argument is accepted without error
@github-actions
Copy link
Copy Markdown

🔨 Build Complete - Ready for Testing!

📦 Download Build Artifact (Recommended)

Download the zip build, upload to WordPress and test:

🌐 Test in WordPress Playground (Very Experimental)

Click the link below to instantly test this PR in your browser - no installation needed!
Playground support for multisite is very limitied, hopefully it will get better in the future.

🚀 Launch in Playground

Login credentials: admin / password

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
inc/class-dashboard-statistics.php (1)

226-235: Consider combining queries for better performance.

Each slug is queried individually, resulting in 4 separate database calls. While acceptable for dashboard use, this could be optimized into a single query with GROUP BY.

♻️ Optional: Single query with GROUP BY
-		foreach ($slugs as $slug) {
-			$counts[ $slug ] = (int) $wpdb->get_var(
-				$wpdb->prepare(
-					"SELECT COUNT(*) FROM {$table} WHERE slug = %s AND date_created BETWEEN %s AND %s",
-					$slug,
-					$this->start_date,
-					$this->end_date
-				)
-			);
-		}
+		$placeholders = implode(',', array_fill(0, count($slugs), '%s'));
+		$query_args   = array_merge($slugs, [$this->start_date, $this->end_date]);
+
+		// phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare
+		$results = $wpdb->get_results(
+			$wpdb->prepare(
+				"SELECT slug, COUNT(*) as cnt FROM {$table} WHERE slug IN ({$placeholders}) AND date_created BETWEEN %s AND %s GROUP BY slug",
+				...$query_args
+			),
+			OBJECT_K
+		);
+
+		foreach ($slugs as $slug) {
+			$counts[ $slug ] = isset($results[ $slug ]) ? (int) $results[ $slug ]->cnt : 0;
+		}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@inc/class-dashboard-statistics.php` around lines 226 - 235, The loop issues
multiple DB calls: replace the per-slug $wpdb->get_var calls with one grouped
query using $wpdb->prepare and IN(...) to fetch counts for all $slugs at once
(e.g. SELECT slug, COUNT(*) FROM {$table} WHERE slug IN (...) AND date_created
BETWEEN %s AND %s GROUP BY slug), then map the result rows back into $counts
(ensuring every slug in $slugs gets an integer 0 if not returned); update the
logic around $slugs, $counts, $wpdb->prepare, and date range ($this->start_date,
$this->end_date) accordingly so a single query supplies the counts.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@inc/class-dashboard-statistics.php`:
- Around line 226-235: The loop issues multiple DB calls: replace the per-slug
$wpdb->get_var calls with one grouped query using $wpdb->prepare and IN(...) to
fetch counts for all $slugs at once (e.g. SELECT slug, COUNT(*) FROM {$table}
WHERE slug IN (...) AND date_created BETWEEN %s AND %s GROUP BY slug), then map
the result rows back into $counts (ensuring every slug in $slugs gets an integer
0 if not returned); update the logic around $slugs, $counts, $wpdb->prepare, and
date range ($this->start_date, $this->end_date) accordingly so a single query
supplies the counts.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: def77e56-2365-4fd5-aef8-1ebc29278b41

📥 Commits

Reviewing files that changed from the base of the PR and between 18f5556 and 30301ba.

📒 Files selected for processing (4)
  • inc/class-dashboard-statistics.php
  • inc/class-signup-metrics.php
  • inc/class-wp-ultimo.php
  • tests/WP_Ultimo/Signup_Metrics_Test.php

@superdav42 superdav42 merged commit 896176b into main Mar 25, 2026
10 of 11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Metrics: Track signup flow (subtask of #297) Finish Metrics and Onboarding

1 participant