Plan · 2026-05-11

Conversion Analytics Modernization

The Dec 2024 GA4 implementation delivered a pageview-only foundation and then froze. Build out the missing conversion events, rotate ownership off a departed consultant, close a HIPAA consent gap, and fix six storefront bugs surfaced during the audit. Kyle + Claude pair-program through it; no consultant.

Active Kyle + Claude No consultant ~30 hours total
12K
GA4 users / 7d
Pageview-only — no conversions
0
Key Events firing
purchase configured, never fires
38%
Combined login drop-off
Diagnosable with 12 events
6
Bugs surfaced during audit
One active data leak

§1The situation

December 2024: AdvancedRx (engagement coordinated by Sarah Lee, Director of Tech) paid Measure Marketing Pro $2,550 for a server-side GA4 implementation. The accepted scope explicitly struck out e-commerce events and lead-form events. Brady (the consultant from Measure Marketing Pro) delivered what he was paid to build — a HIPAA-compliant pageview foundation via Stape sGTM — and walked away in February 2025. No conversion events have fired since.

Active data leak found in the audit: the Stape Google Ads connection is still authenticated as analytics@measuremarketing.pro and silently forwards offline conversion data to Brady's agency Google Ads account. AdvancedRx has zero Google Ads spend — this pipeline writes to a destination Kyle does not control. Disconnect is urgent (Track A.1).

§2What's actually wired today

Brady's technical execution was correct for the slim scope. The infrastructure is textbook dual-container server-side GTM with PHI scrubbing and a signed BAA. The gap is everything after page_view.

Layer 1 · Web
GTM-N8C8PCKJ
GA4 - Config tag fires on every page
2 tags · 1 trigger · 4 variables
Layer 2 · Server
GTM-5NWGFT4G
Hosted on Stape · 4 Power-Ups
Anonymizer scrubs PHI

What's missing: any LWC-side dataLayer.push() call. The container is configured to forward conversion events; no LWC ever pushes one. Zero of 17 customer-facing storefront LWCs have analytics instrumentation today.

§3The funnel as visible in GA4

From the GA4 Pages and Screens report — active users over the last 28 days. Two big drops jump out; one of them happens entirely inside a modal that produces no pageview signal.

/login
10,195
/passwordless-challenge
7,933
−22%
/my-home
6,658
−16%
/cart
2,535
−62%
The 16% drop is "got the email code, never entered it." Code-verification failures are silent in GA4 today — b2bLoginCodeComponent catches errors and shows a toast with no redirect, no page change, no event. The 16% includes users who never tried, retried once and walked away, retried five times, or clicked Resend. Custom login events split them.
The 62% drop is partly the refill wizard being invisible. The wizard launches as a modal inside /my-home — no URL change, no pageviews, no signal for any of its 5 steps. Patients who started the wizard but abandoned mid-flow produce no GA4 evidence. Custom wizard events (one per screen) crack this open.

§4Six bugs surfaced during the audit

The instrumentation audit incidentally uncovered six bugs across pricing, attribution, login, payment failure, consent, and schema. Two are revenue-affecting, one is an active data leak (already covered in §1 callout), one is HIPAA-adjacent.

Bug 1
Wizard pricebook mismatch
Refill wizard reads UnitPrice from Standard Price Book (4,198 entries) instead of the storefront's Advanced RX Store Price Book (949 entries). If the two diverge for any product, customers added via wizard are charged the wrong amount.
B2BRefillFlowController.cls:27
Bug 2
Wizard drops Rx attribution
Wizard path doesn't set Prescription_Link__c, RefillId__c, or Sig__c on the CartItem. The parallel invocable method does. Wizard-added items lose Rx attribution at the CartItem level.
B2BRefillFlowController.toCartItem
Bug 3
Profile-name-gated login lockout
Login query hardcodes Profile.Name = 'Advanced RX Customer Community Plus Login User'. Users on the other two community profiles can never log in — they see "No unique user found" every attempt.
B2BCustomLoginHandler.cls:139
Bug 4
Charged-but-no-order hazard
convertCartToOrder catch throws without refunding. If anything fails after the AuthorizeNet charge succeeds, the customer pays but no Order exists. Helpdesk has been receiving fault emails — query B2B_Custom_Exception__c for historical occurrences.
B2BPaymentMethodsController.cls:282
Bug 5
Cookie consent doesn't gate analytics
Banner sets a cookie when "Accept" is clicked but doesn't pause GTM/Stape firing. No Decline button. No GA4 Consent Mode v2. Analytics fire regardless of consent state. Anonymizer mitigates PHI exposure but compliance posture needs counsel.
b2bCookieComp.js
Bug 6
Order has no Refill_Reminder FK
Reminder→Order attribution requires UTM joining or net-new instrumentation today. Solved structurally by the magic-link plan's Magic_Link_Auth_Event__c when that ships.
Schema gap (deferred to magic-link)

§5Three-track plan

The work splits cleanly along three independent tracks. Different urgencies, different stakeholders, different cost profiles. Track A can ship this week with no consultant; Track B is the bulk of the dev work; Track C runs as separate tickets.

Track A
Ownership & continuity
Rotate Stape Connections off Brady's email. Disconnect Google Ads (active data leak). Add Kristen + Sarah as GTM Admins. Enable BigQuery export. Restore Kyle's SFMC access.
Urgency: High
Effort: ~3 hours, Kyle only
Cost: $0
Track B
Conversion analytics buildout
Add the conversion events Brady's accepted scope explicitly omitted. Mostly single-line dataLayer.push() insertions in existing LWCs — one push per moment we want to measure. Only one Apex piece (server-side purchase) needs real engineering. Not analyst work — LWC editing guided by Claude.
Urgency: Medium-high
Effort: ~25–35 hours total
Owner: Kyle + Claude
Cost: $0 — no consultant
Track C
Storefront bug cleanup
One GitHub Issue per bug from §4. Bug #3 (login lockout) and #4 (charged-but-no-order) are operational priorities. Bug #5 (consent) needs counsel. Bugs #1, #2, #6 are roadmap.
Urgency: Mixed
Effort: ~15–30 hours
Owner: Kyle + Claude
Cost: $0 + counsel time for #5

§6Top 5 highest-ROI events

Ranked by analytical lift per hour invested. Login funnel events (rank 1) are 12 single-line pushes across two LWCs — the cheapest, sharpest diagnostic in the entire plan.

1
login_*
(12 events)
b2bCustomLoginComponent + b2bLoginCodeComponent — splits the 38% login drop into 12 measurable failure modes
2-3 hr
2
purchase
(server-side)
B2BPaymentMethodsController.convertCartToOrder line ~285 — unblockable by ad-blockers, full ecommerce payload
10-15 hr
3
add_to_cart
customProductCarousel.addToCart line 162 — single-point capture for wizard + direct-add
1-2 hr
4
refill_wizard_step_N_viewed
(5 events)
Each of b2bRefillFlowScreen1..5 connectedCallback — makes the modal-launched wizard visible
3-5 hr
5
begin_checkout, add_shipping_info, add_payment_info
b2bCheckoutShippingAddress + b2bCheckoutPayment — checkout-stage friction diagnostics
3-5 hr

§7What's measured today vs after Track B

Walking the refill funnel stage-by-stage. Each row maps a customer journey moment to whether GA4 sees it today (left) and whether it would see it after the corresponding Track B phase ships (right). Green pills are reportable in GA4 funnel reports; amber pills are partial signal; gray pills are dark today.

Funnel moment
Today
After Track B
Patient lands on /login
✓ pageview
✓ + login_view
Patient submits email + DOB
✗ dark
✓ login_dob_email_submitted
DOB mismatch / invalid email / no user found
✗ dark
✓ 4 distinct failure events
Email code sent (passes DOB step)
~ inferred from pageview
✓ login_dob_passed
Patient enters the code
✗ dark
✓ login_code_submitted
Code rejected (wrong / expired)
✗ dark
✓ login_code_failed
Patient clicks "Resend code"
✗ dark
✓ login_code_resend_requested
Authenticated → /my-home loads
✓ pageview
✓ + login_success
"My Medications" list rendered
✗ dark
✓ view_item_list (with Rx IDs)
Refill wizard opened (modal)
✗ no URL change
✓ refill_wizard_start
Each of the 5 wizard screens
✗ invisible
✓ 5 step events + exit event
Patient adds Rx to cart
~ /cart pageview (polluted)
✓ add_to_cart with line items
Checkout — shipping screen
✗ dark
✓ begin_checkout + add_shipping_info
Checkout — payment method selected
✗ dark
✓ add_payment_info (with card type)
Order submitted + paid
~ /order pageview only
✓ purchase (server-side, full payload)
Charged-but-no-order (Bug #4)
✗ silent except helpdesk email
✓ Bug #4 fix routes to Error_Log__c

§8Concrete questions Track B answers

The point of all the events isn't the events — it's the questions you can answer about real customer behavior. Six examples below; each is unanswerable today and becomes a one-query report in GA4 once Track B ships.

What % of users get the code email and never enter it?
Today: The 16% drop from /passwordless-challenge to /my-home is a black box — could be email-never-arrived, code-typed-wrong, code-expired, or walked-away.
After Track B: Four-way split via login_code_submitted, login_code_failed, login_code_resend_requested, and login_success. You see exactly which failure mode dominates.
Where in the 5-step refill wizard do patients abandon?
Today: Invisible. Wizard launches as a modal inside /my-home — no pageviews fire for individual steps. The 62% drop from /my-home to /cart mixes wizard-abandoners with users who never opened it.
After Track B: One event per screen (refill_wizard_step_1_viewed...step_5_viewed) gives a step-by-step funnel report. You see exact drop per step.
Which prescriptions drive the most revenue?
Today: Not in GA4. Possible via Salesforce SOQL queries against Order data, but no slicing by traffic source or user cohort.
After Track B: Server-side purchase event carries items[] with Product2 IDs + family + prices. GA4 "Top selling items" report works natively. Slice by source, cohort, time.
When the magic link launches, did it actually lift conversion?
Today: Unanswerable. No baseline of the current login-funnel performance exists in measurable form.
After Track B: The 12 login events become a measured baseline. After magic link launches, compare bridge-auth conversion rate to the baseline. Direct lift measurement.
What % of users who reach /my-home actually start a refill?
Today: Unmeasurable. Both "patients who came to check order history" and "patients who started the wizard and quit" look identical in GA4.
After Track B: Direct via refill_wizard_start ÷ /my-home pageviews. Tells you whether the friction is at "find the wizard" or "complete the wizard."
What's the cart-to-purchase conversion rate, and which checkout step drops the most?
Today: Can count /cart pageviews and orders, but the ratio is noisy (empty-cart redirects, failed adds that never redirect). No per-step visibility inside checkout.
After Track B: add_to_cartbegin_checkoutadd_shipping_infoadd_payment_infopurchase. Five-stage funnel with clean drop-off at every step.

§9Sprint sequencing — Kyle + Claude calendar

Track A ships this week with no consultant, parallel to magic-link prereq work. Sprints 1–3 ship Track B in dependency order, Kyle pair-programming with Claude. Track C tickets run alongside. Each sprint is ~10 hours of focused effort spread across 2 weeks of calendar time — evening/weekend shape, not heads-down full days.

This week — Track A · ~3 hours
Disconnect Google Ads (5 min — urgent, stops the data leak). Identify Google Sheets owner. Add Kristen/Sarah as GTM Admins. Enable BigQuery export. Escalate SFMC access. Run prod SOQL queries for Bug #1/#3/#4 sizing. Kyle only.
Sprint 1 — Schema + core ecommerce · ~9 hrs
Phase B1: dataLayer schema design (~2-3 hrs). Phase B2: view_item, view_item_list, add_to_cart, begin_checkout, add_shipping_info, add_payment_info, client-side purchase (~6-10 hrs). Kyle + Claude.
Sprint 2 — Wizard + login · ~10 hrs
Phase B3: refill wizard events — start, step_1..5, exit (~3-5 hrs). Phase B4: 12 login funnel events (~2-3 hrs). Bug #3 fix (profile-name lookup → DeveloperName or removed gate, 4-8 hrs). Kyle + Claude.
Sprint 3 — GA4 config + server-side · ~15 hrs
Phase B5: GA4 Key Events + custom dimensions + attribution (~1-2 hrs). Phase B6: server-side purchase from convertCartToOrder (~10-15 hrs — the only substantial Apex piece). Bug #4 fix (refund logic). Bug #5 (consent) counsel review starts in parallel. Kyle + Claude.

§10Verification basis & current blockers

The findings throughout this plan come from a multi-console audit conducted 2026-05-11, plus a thorough read of every storefront-facing LWC and the cart-to-order Apex conversion path.

Audit basis:
  • GTM web container GTM-N8C8PCKJ — 2 tags, 1 trigger, 4 variables, 4 versions, last published 2026-02-26
  • GTM server container GTM-5NWGFT4G — 1 client (GA4), 1 trigger, 1 tag
  • Stape container mzldlvji — Pro tier $20/mo, 4 Power-Ups, 3 Connections — all signed in as analytics@measuremarketing.pro
  • GA4 property 306115267 — 12K active users / 7d, 1 Key Event configured, 0 firing
  • 17 customer-facing storefront LWCs read for instrumentation fire points
  • Cart-to-order Apex traced: b2bCheckoutPaymentprocessPayments → AuthorizeNet → convertCartToOrderB2B_Cart_To_Order flow → OrderSummary + OrderPaymentSummary + OrderPayment__c
  • Login Apex traced: B2BCustomLoginHelperB2BCustomLoginHandlerUserManagement.initPasswordlessLogin / verifyPasswordlessLogin
  • SFMC dispatch flow JBSystemFlow_Refill_Reminder_c confirms Refill_Reminder__c.Id is sent to SFMC as SalesforceObjectId
  • Stape BAA — signed (verified with Kyle 2026-05-11)
Current blockers: Kyle is locked out of SFMC as of 2026-05-11 — blocks verification of the refill reminder email URL template (Phase 0 question #1). Six other Phase 0 verifications are unblocked and listed in plan.md §10.

§11What's next

Three decisions for Kyle this week, before any execution starts.