Hyphen User Guides

Analytics Feature Description

Feature description and testing guide for the analytics and reporting module with 18 features

Version 1.0|Updated 2026-04-12|QA Team, Customer Success, Product Stakeholders

1. What Is the Analytics & Reporting System?

The Analytics & Reporting system tracks, measures, and visualizes how readers interact with the Hyphen publishing platform. It combines two data sources:

  1. Google Analytics 4 (GA4) — Tracks real-time reader behavior on the Reader Portal: page views, scroll depth, article reading time, paywall interactions, device types, geographic data, and traffic sources.

  2. Internal Platform Data (PostgreSQL/Prisma) — Tracks subscription metrics, revenue, reader registrations, institutional usage, content moderation, and social media performance from the platform's own database.

Together, these provide a complete picture across the entire reader lifecycle: from first visit to content consumption to subscription conversion to long-term retention.


2. Business Objectives & KPIs

Primary KPIs Tracked

KPI CategoryMetricsData SourceUpdate Frequency
TrafficPage Views, Unique Visitors, Sessions, Avg. Session Duration, Bounce RateGA4Near real-time
Content EngagementScroll Depth (25/50/75/100%), Read Completion Rate, Avg. Time on Article, Top ArticlesGA4Near real-time
Subscription HealthTotal Subscribers, New Subscribers, Churn Rate, MRR, ARR, ARPU, LTVPrisma DBReal-time
RevenueMonthly Recurring Revenue, Annual Recurring Revenue, Revenue by Plan, Growth RatePrisma DB (Payment table)Real-time
ConversionPaywall View Rate, Paywall Click-Through Rate, Subscribe Start Rate, Subscribe Completion RateGA4 (custom events)Near real-time
RegistrationVisitor-to-Registration Rate, Email Verification Rate, Registration-to-Subscription RateGA4 + PrismaMixed
AudienceDesktop/Mobile/Tablet Split, Browser Distribution, Top Countries, Traffic Sources (Organic/Direct/Social/Referral/Email/Paid)GA4Near real-time
InstitutionalSeat Utilization Rate, Active Users per Institution, Content Access PatternsPrisma DBReal-time
Social MediaImpressions, Reach, Engagement Rate, Follower Growth, Best Posting TimesPlatform APIs (Meta, X)Periodic sync
E-CommerceProduct Views, Add-to-Cart Rate, Checkout Start RateGA4 (custom events)Near real-time
NewsletterNewsletter Views, Scroll Depth, Read Completion, Share RateGA4 (custom events)Near real-time

Business Questions the System Answers

QuestionWhere to Find the Answer
"How many people are reading our content?"Analytics Overview > Key Metrics Cards (Page Views, Unique Visitors)
"Which articles are most popular?"Analytics Overview > Top Content section
"How are subscriptions growing?"Analytics Overview > Subscription Metrics (MRR, New Subscribers, Churn)
"Where is our traffic coming from?"Analytics Overview > Traffic Sources (Organic, Direct, Social, etc.)
"How well is the paywall converting?"Analytics Overview > Paywall Funnel (view -> click -> start -> complete)
"What devices do our readers use?"Analytics Overview > Device Breakdown (Desktop/Mobile/Tablet)
"Are institutional subscribers using their access?"Analytics > Institutional Usage Reports
"How are our social posts performing?"Social > Analytics (Impressions, Engagement, Best Times)
"How deep are readers reading articles?"Analytics Overview > Scroll Depth (25/50/75/100% distribution)
"Which marketing channels drive the most conversions?"GA4 > Acquisition > UTM attribution from conversion surfaces

3. System Architecture — Where Data Comes From

Reader Portal (Next.js)                      Admin Console (Next.js)
+---------------------------+                +---------------------------+
|                           |                |                           |
|  GoogleAnalytics.tsx      |   GA4 Data     |  Analytics Page           |
|  (gtag.js script)   -----+---API---------->  /api/analytics/*         |
|                           |                |  (ga4-data-client.ts)     |
|  analytics.ts             |                |                           |
|  (custom events)          |   Custom       |  Dashboard Page            |
|  - paywall_view           |   Events       |  /api/stats/dashboard     |
|  - article_scroll_depth   |                |                           |
|  - subscribe_start        |                |  /api/analytics/          |
|  - shop_add_to_cart       |                |   - traffic-sources       |
|  - conversion_surface_*   |                |   - content-performance   |
|  - newsletter_*           |                |   - subscription-metrics  |
|  etc.                     |                |   - paywall-funnel        |
|                           |                |   - registration-funnel   |
|  CookieConsent.tsx        |                |   - device-browser        |
|  (consent gating)         |   Prisma       |   - institutional-usage   |
|                           |   DB Data      |   - author-stats          |
|  ReadingTracker.tsx       +---API---------->   - export                |
|  (progress to backend)    |                |                           |
|                           |                |  /api/stats/subscribers   |
+---------------------------+                +---------------------------+
         |                                              |
         v                                              v
   Google Analytics 4                          PostgreSQL Database
   (GA4 Property)                              (Prisma Models)
   - pageview events                           - Subscription
   - custom events                             - Payment
   - real-time data                            - Reader
   - audience data                             - ReadingHistory
   - acquisition data                          - Institution
                                               - InstitutionUser
                                               - Comment
                                               - ArticleRating
                                               - ConversionEvent

Data Source Mapping

Data PointSourceHow It Gets There
Page viewsGA4Automatic — gtag.js fires page_view on every navigation
Unique visitorsGA4Automatic — GA4 deduplicates by client ID
Article scroll depthGA4Custom event — observeScrollDepth() in article templates fires at 25/50/75/100%
Article read completeGA4Custom event — fires when reader scrolls to 100%
Paywall viewsGA4Custom event — trackPaywallView() fires when PaywallOverlay renders
Subscribe button clicksGA4Custom event — trackPaywallClickSubscribe() fires on paywall CTA click
Subscription startGA4Custom event — trackSubscribeStart() fires when reader begins checkout
Subscription completeGA4Custom event — trackSubscribeComplete() fires after payment verification
Product viewsGA4Custom event — trackProductView() fires on shop product page
Add to cartGA4Custom event — trackAddToCart() fires on "Add to Cart" button click
Newsletter scroll depthGA4Custom event — observeNewsletterScrollDepth() fires at 25/50/75/100%
Conversion surface interactionsGA4 + InternalDual tracked — GA4 events + ConversionEvent table
MRR / ARR / RevenuePrisma DBCalculated from Payment + Subscription tables
Subscriber countsPrisma DBCOUNT queries on Subscription table
Churn ratePrisma DBCancelled subscriptions / total subscriptions
Institutional usagePrisma DBInstitutionUser activity data
Reading historyPrisma DBReadingTracker component POSTs progress data to admin API
Traffic sourcesGA4 Data APIServer-side query via ga4-data-client.ts
Device breakdownGA4 Data APIServer-side query for deviceCategory dimension

4. GA4 Event Catalog — Every Event the Platform Fires

4.1 Automatic Events (fired by gtag.js)

EventWhen FiredParameters
page_viewEvery page navigationpage_path, page_title

4.2 Article Engagement Events

EventWhen FiredParametersTrigger LocationStatus
article_viewReader opens an article pagearticle_slug, article_section, content_typeArticle page templatesPending wiring
article_scroll_depthReader scrolls past 25%, 50%, 75%, or 100% of articlearticle_slug, article_section, scroll_depth (25/50/75/100)observeScrollDepth() in article templatesWired
article_read_completeReader scrolls to 100% of articlearticle_slug, read_time_secondsobserveScrollDepth() at 100% milestoneWired

4.3 Paywall Events

EventWhen FiredParametersTrigger LocationStatus
paywall_viewPaywallOverlay or paywall gate renders on screenarticle_slug, article_sectionPaywallOverlay, ArticlePaywallGate componentsPending wiring
paywall_click_subscribeReader clicks "Subscribe" on a paywallarticle_slugPaywallOverlay CTA click handlerPending wiring

4.4 Subscription Events

EventWhen FiredParametersTrigger LocationStatus
subscribe_startReader begins subscription checkoutplan_name, plan_priceCheckout page on mountPending wiring
subscribe_completePayment verified and subscription activatedplan_name, payment_methodAfter payment verification successPending wiring

4.5 E-Commerce / Shop Events

EventWhen FiredParametersTrigger LocationStatus
shop_product_viewReader opens a product detail pageproduct_handle, product_name, priceShop product pagePending wiring
shop_add_to_cartReader clicks "Add to Cart"product_handle, product_name, price, quantityCartProvider addItem handlerPending wiring
shop_checkout_startReader clicks "Checkout" in cartcart_value, item_countCart checkout redirectPending wiring

4.6 Conversion Surface Events

EventWhen FiredParametersTrigger Location
conversion_surface_impressionConversion surface is displayed to readersurface_id, surface_name, surface_type, conversion_goal, page_urlConversionSurfaceRenderer on trigger
conversion_surface_clickReader clicks surface CTAsurface_id, surface_name, surface_type, conversion_goal, cta_typeConversionSurfaceProvider trackClick
conversion_surface_dismissReader dismisses surfacesurface_id, surface_name, surface_type, conversion_goalConversionSurfaceProvider dismissSurface
conversion_surface_conversionReader completes desired actionsurface_id, surface_name, conversion_goal, conversion_typeConversionSurfaceProvider trackConversion
coupon_copiedReader copies a coupon codesurface_id, coupon_code, discount_percent, discount_amountSurface component copy handler

4.7 Newsletter Events

EventWhen FiredParametersTrigger Location
newsletter_viewReader opens a newsletter edition pagenewsletter_slug, edition_number, topicNewsletter edition page
newsletter_scroll_depthReader scrolls newsletter at 25/50/75/100%newsletter_slug, scroll_depthobserveNewsletterScrollDepth()
newsletter_read_completeReader reaches 100% of newsletternewsletter_slug, read_time_secondsAt 100% milestone
newsletter_shareReader shares a newsletternewsletter_slug, platformSocialShare on newsletter page
newsletter_list_viewReader views newsletter archive listtopicNewsletter listing page
newsletter_signupReader subscribes to newslettersource, surface_idNewsletter form submit

4.8 Registration Events

EventWhen FiredParametersTrigger LocationStatus
registration_startReader begins registration flowsource, surface_idRegistration page or conversion surface CTAPending wiring

Event Flow Summary

Reader Journey:
  Visit site -----> page_view (automatic)
  Browse article -> article_view
  Scroll reading -> article_scroll_depth (25%, 50%, 75%)
  Finish article -> article_scroll_depth (100%) + article_read_complete
  Hit paywall ----> paywall_view
  Click Subscribe > paywall_click_subscribe
  Start checkout -> subscribe_start
  Complete payment> subscribe_complete

  Browse shop ----> shop_product_view
  Add to cart ----> shop_add_to_cart
  Checkout -------> shop_checkout_start

  See promo modal > conversion_surface_impression
  Click CTA ------> conversion_surface_click
  Copy coupon ----> coupon_copied
  Complete action > conversion_surface_conversion

5. Admin Dashboard — Quick Daily Snapshot

Admin dashboard
The admin dashboard provides a quick daily snapshot of key platform metrics.

Location

Admin Console > Dashboard (landing page after login)

What It Shows

4 Primary Stat Cards:

CardSourceDescription
Total ArticlesPrisma DBAll articles across all statuses
SubscribersPrisma DBActive subscriber count + "+X this month"
Total ViewsPrisma DB / GA4Total article view count
EngagementPrisma DBComments + shares combined

6 Status Cards:

CardSourceClickable?
Pending ReviewPrisma DB (Article.status = pending_review)Yes -- opens filtered content page
DraftsPrisma DB (Article.status = draft)Yes -- opens filtered content page
Published (7d)Prisma DBNo
Comments QueuePrisma DB (Comment.status = pending)Yes -- opens moderation page
FlaggedPrisma DB (Comment.status = flagged)Yes -- opens moderation page
New ReportsPrisma DB (ContentReport.status = open)Yes -- opens moderation page

3-Column Section:

  • Most Popular articles (by view count)
  • Under Review articles (pending editorial review)
  • Quick Actions (New Article, Moderation, Analytics)

Social Overview Widget:

  • Scheduled Today / This Week / Failed post counts
  • Quick links to Compose Post and Social Analytics

Recently Published:

  • Last 6 published articles with views, comments, shares

6. Analytics Overview Page — Deep Metrics

Analytics overview
The analytics overview page with detailed traffic, subscription, content, and geographic metrics.

Location

Admin Console > Analytics

Controls

  • Date Range Picker: 7d, 30d (default), 90d, 12m, Custom
  • Refresh Button: Reloads all data
  • Export Button: Downloads CSV report (requires ANALYTICS_EXPORT permission)

Section Layout

SectionPositionData SourceDescription
Key Metrics CardsTop rowGA4Page Views, Unique Visitors, Sessions, Avg. Session Duration -- each with % change vs previous period
Traffic ChartLeft 2/3GA4Time-series line chart with toggleable lines (Page Views, Unique Visitors, Sessions)
Traffic SourcesRight 1/3GA4Channel breakdown bars (Organic, Direct, Social, Referral, Email, Paid)
Subscription MetricsLeft halfPrismaTotal Subscribers, New Subscribers, Churn Rate, MRR, plan breakdown, subscriber trend sparkline, Conversion Rate, ARPU, LTV
Top ContentRight halfGA4Table: Rank, Title, Page Views, Time on Page, Shares, Comments
Paywall Conversion FunnelLeft halfGA44-stage funnel: Paywall Viewed -> Clicked Subscribe -> Subscription Started -> Subscription Completed
Scroll Depth DistributionRight halfGA4Estimated distribution at 25%, 50%, 75%, 100% thresholds
Device BreakdownLeft 1/3GA4Desktop / Mobile / Tablet percentages
Top CountriesRight 1/3GA4Top 5 countries with flag icons and percentage
GA4 Link BannerBottom--"Need more detailed analytics?" link to Google Analytics

7. Paywall Conversion Funnel

What It Tracks

The paywall funnel measures the step-by-step conversion journey from seeing a paywall to completing a paid subscription.

StageGA4 EventDescriptionExample Count
Paywall Viewedpaywall_viewReader saw a paywall overlay or gate10,000
Clicked Subscribepaywall_click_subscribeReader clicked the "Subscribe" CTA on a paywall2,500 (25% of stage 1)
Subscription Startedsubscribe_startReader began the checkout process1,200 (12% of stage 1)
Subscription Completedsubscribe_completeReader completed payment and subscription activated450 (4.5% of stage 1)

How to Read the Funnel

  • The conversion rate shown at each stage is relative to the top of the funnel (stage 1)
  • A healthy paywall funnel converts 2-5% of paywall views to completed subscriptions
  • Large drop-offs between stages indicate friction points:
    • Big drop between "Viewed" and "Clicked Subscribe" = paywall messaging isn't compelling
    • Big drop between "Started" and "Completed" = checkout friction (price, payment method, UX)

Data Source

GA4 Data API -- server-side query aggregating custom event counts over the selected date range.


8. Registration Funnel

What It Tracks

The registration funnel measures how effectively the platform converts anonymous visitors to active subscribers.

StageData SourceDescription
Total VisitorsGA4Unique visitors in the period
RegisteredPrisma DBReaders who created an account
VerifiedPrisma DBReaders who verified their email
Active SubscribersPrisma DBReaders with active paid subscriptions

API Endpoint

GET /api/analytics/registration-funnel?days=30


9. Subscription & Revenue Metrics

Analytics overview
Subscription and revenue metrics are available on the Analytics Overview page. Scroll down to see active subscribers, MRR, churn rate, and conversion funnel data.

Metrics Displayed

MetricDefinitionSource
Total SubscribersActive + recently cancelled subscribersPrisma: Subscription table
Active SubscribersCurrently paying subscribersPrisma: Subscription.status = ACTIVE
New SubscribersSubscriptions created in the current monthPrisma: Subscription.createdAt within month
Cancelled SubscribersSubscriptions cancelled in the periodPrisma: Subscription.status = CANCELED
Churn Rate(Cancelled / Total) as percentageCalculated
MRR (Monthly Recurring Revenue)Sum of monthly subscription paymentsPrisma: Payment table aggregation
ARR (Annual Recurring Revenue)MRR x 12Calculated
ARPU (Avg Revenue Per User)MRR / Active SubscribersCalculated
LTV (Lifetime Value)ARPU / Monthly Churn RateCalculated (estimated)
Conversion RateTrial-to-paid conversion percentagePrisma: Subscription.status transitions

Revenue by Plan Breakdown

Shows subscriber distribution and revenue contribution per plan (e.g., "Digital Only: 45%, Print+Digital: 30%, Annual: 25%").

Revenue Trend

Monthly time-series chart of revenue, showing growth trajectory.

API Endpoint

GET /api/analytics/subscription-metrics


10. Content Performance Analytics

Analytics overview
Content performance metrics are part of the Analytics Overview. Per-article data includes pageviews, read time, engagement rate, and social shares.

Metrics Per Article

MetricSourceDescription
Page ViewsGA4Total times the article was loaded
Active UsersGA4Unique readers who viewed the article
Avg. Engagement TimeGA4Average time spent reading
Scroll DepthGA4Distribution at 25/50/75/100% thresholds

Top Content Table

Ranked list showing the highest-performing articles by page views, with time-on-page, shares, and comments.

Author Statistics

GET /api/analytics/author-stats — Per-author metrics for editorial performance review.

API Endpoint

GET /api/analytics/content-performance


11. Traffic Source Analysis

Channels Tracked

ChannelHow It's IdentifiedExample
Organic SearchVisitors from search engines (Google, Bing)google / organic
DirectVisitors who typed URL or used bookmark(direct) / (none)
SocialVisitors from social media linksfacebook / social, twitter / social
ReferralVisitors from other websites linking to youblog.example.com / referral
EmailVisitors from email links (UTM tagged)newsletter / email
PaidVisitors from paid advertisinggoogle / cpc, facebook / paid

UTM Attribution from Conversion Surfaces

When readers click a conversion surface CTA, the URL is automatically tagged with:

  • utm_source=conversion_surface
  • utm_medium=promo
  • utm_campaign=cs_{goal}_{surfaceId}

This appears in GA4 traffic source reports, allowing you to measure the direct impact of conversion surfaces on subscriptions.

API Endpoint

GET /api/analytics/traffic-sources


12. Device & Browser Analytics

Device Categories

  • Desktop (screen > 1024px)
  • Mobile (screen < 768px)
  • Tablet (768-1024px)

Browser Distribution

Top browsers by usage (Chrome, Safari, Firefox, Edge, etc.)

Operating Systems

Distribution across Windows, macOS, iOS, Android, Linux.

API Endpoint

GET /api/analytics/device-browser


13. Institutional Usage Reporting

What It Tracks

For each institution with an active subscription:

MetricDescription
Seats Used / TotalHow many assigned seats are actively logging in
Utilization Rate(Active users / Total seats) as percentage
Active UsersUsers who logged in during the period
Content AccessedNumber of articles/issues accessed

Use Case

Sales and customer success teams use this data to:

  • Identify underutilized institutional accounts for engagement outreach
  • Prepare usage reports for institutional renewal conversations
  • Upsell additional seats to institutions with high utilization

API Endpoint

GET /api/analytics/institutional-usage


14. Social Media Analytics

Location

Admin Console > Social > Analytics

Tabs

  1. Performance -- Impressions, Reach, Engagements, Engagement Rate, Posts Published, Likes, Comments, Clicks
  2. Content -- Per-post performance breakdown
  3. Growth -- Follower growth trends
  4. Best Times -- Optimal posting time recommendations based on engagement data
  5. Executive -- Summary view for leadership (requires SOCIAL_EXECUTIVE_READ permission)

Metrics

MetricDescription
Total ImpressionsTimes posts were displayed
Total ReachUnique people who saw posts
Total EngagementsLikes + comments + shares + clicks
Avg. Engagement RateEngagements / Impressions
Posts PublishedNumber of posts in the period
Follower GrowthNet new followers

15. Data Export & Reporting

Export Formats

  • CSV -- Comma-separated values for spreadsheet analysis
  • JSON -- Machine-readable format for programmatic use

Available Exports

ExportContents
TrafficPage views, visitors, sessions by date
SubscriptionsSubscriber counts, MRR, churn by month
RevenueRevenue by month and by plan
ContentTop articles with page views, engagement time

How to Export

  1. Navigate to Analytics page
  2. Set the desired date range
  3. Click the Export button (top-right)
  4. CSV file downloads automatically

Permission Required

ANALYTICS_EXPORT permission

API Endpoint

GET /api/analytics/export?type=subscriptions&format=csv&days=30


How It Works

  1. GoogleAnalytics component loads with analytics_storage: denied by default
  2. CookieConsent component shows a banner asking the reader to accept cookies
  3. If reader accepts, consent is stored in localStorage as hyphen_cookie_consent: accepted
  4. On subsequent visits, analytics_storage is set to granted based on stored consent
  5. If reader does not accept, GA4 events are still queued but not sent to Google

Impact on Analytics

  • Readers who decline cookies will NOT generate GA4 data
  • This means page views, scroll depth, and all custom events from those readers are invisible
  • Internal platform data (subscriptions, reading history, bookmarks) is NOT affected by cookie consent -- it's recorded via authenticated API calls

Privacy Compliance

  • Cookie consent follows GDPR principles
  • No tracking cookies set before consent
  • Consent status persisted only in localStorage (not server-side)

17. Scroll Depth & Reading Engagement Tracking

How Scroll Tracking Works

The observeScrollDepth() function in the Reader Portal:

  1. Attaches a passive scroll event listener when an article page mounts
  2. Calculates scroll percentage: (window.scrollY / (scrollHeight - windowHeight)) * 100
  3. Fires article_scroll_depth at each milestone (25%, 50%, 75%, 100%)
  4. Each milestone fires exactly once per page load
  5. At 100%, also fires article_read_complete with total read time in seconds

What the Admin Sees

In the Analytics Overview page, the Scroll Depth Distribution section shows estimated percentages:

  • % of readers who scrolled to 25%
  • % of readers who scrolled to 50%
  • % of readers who scrolled to 75%
  • % of readers who scrolled to 100% (completed reading)

Reading Progress (Internal Tracking)

Separately from GA4, the ReadingTracker component:

  • POSTs reading progress to /api/account/history/[articleId] at milestones (0/25/50/75/100%)
  • Tracks progress, scrollPosition, timeSpentSec
  • Records startedAt, lastReadAt, completedAt in the ReadingHistory table
  • This powers the reader's Reading History page and the Implicit Preference Learning system

18. Conversion Surface Analytics

See the dedicated Conversion Surfaces Feature Description for full details.

Summary of analytics integration:

  • 5 GA4 events: impression, click, dismiss, conversion, coupon_copied
  • Internal ConversionEvent table: every interaction recorded with reader context
  • Denormalized counters on each surface: impressionCount, clickCount, dismissCount, conversionCount
  • Admin stats dashboard: totals, rates, time-series, device breakdown, top pages, UTM source breakdown
  • UTM attribution: all CTA URLs auto-tagged for GA4 campaign tracking

19. User Stories

For Editors

IDAs a...I want to...So that...
US-01EditorSee which articles are most read this weekI can commission similar content
US-02EditorKnow what percentage of readers finish articlesI can assess if article length is appropriate
US-03EditorSee which sections have the most trafficI can allocate editorial resources accordingly

For Product Managers

IDAs a...I want to...So that...
US-04Product ManagerTrack the paywall conversion funnel end-to-endI can identify and fix friction points
US-05Product ManagerMonitor MRR and subscriber growth monthlyI can report business health to stakeholders
US-06Product ManagerSee the registration-to-subscription conversion rateI can measure the effectiveness of the onboarding flow
US-07Product ManagerCompare traffic between date rangesI can measure the impact of marketing campaigns

For Marketing

IDAs a...I want to...So that...
US-08Marketing ManagerSee which traffic sources drive the most subscribersI can allocate budget to the best channels
US-09Marketing ManagerTrack conversion surface performance (impressions, clicks, conversions)I can optimize promotional overlays
US-10Marketing ManagerKnow what percentage of traffic comes from social mediaI can justify social media investment
US-11Marketing ManagerExport analytics data as CSVI can create custom reports for stakeholders

For Sales / Customer Success

IDAs a...I want to...So that...
US-12Sales ManagerSee institutional subscription utilization ratesI can identify accounts at risk of churn
US-13Customer SuccessGenerate usage reports per institutionI can share data during renewal conversations

For QA

IDAs a...I want to...So that...
US-14QA EngineerVerify GA4 events fire correctly on the Reader PortalI can confirm the analytics pipeline is working
US-15QA EngineerConfirm the Admin Console displays real data when GA4 is configuredI can validate the full data flow
US-16QA EngineerVerify that declining cookie consent suppresses GA4 trackingI can confirm privacy compliance

20. Use Cases & Scenarios

Scenario 1: Monitoring a New Issue Launch

Context: New magazine issue published this week. Editor wants to measure reader response.

Steps:

  1. Open Dashboard -- check "Published (7d)" card for the new issue's articles
  2. Open Analytics -- set date range to "7d"
  3. Check Key Metrics -- expect a spike in Page Views and Unique Visitors
  4. Check Top Content -- new issue's articles should appear in the top 10
  5. Check Scroll Depth -- look for high completion rates (75-100%) indicating engaged readers
  6. Check Paywall Funnel -- if issue articles are premium, expect funnel activity

Scenario 2: Evaluating a Marketing Campaign

Context: Marketing ran a Facebook campaign to drive subscriptions.

Steps:

  1. Open Analytics -- set date range to cover the campaign period
  2. Check Traffic Sources -- "Social" percentage should be higher than baseline
  3. Open GA4 directly -- filter by utm_source=facebook to see campaign-specific metrics
  4. Check Subscription Metrics -- look for a spike in "New Subscribers"
  5. If conversion surfaces were used, check their stats for UTM attribution (utm_campaign=cs_subscribe_paid_*)

Scenario 3: Institutional Renewal Preparation

Context: Sales team preparing for an institutional subscription renewal meeting.

Steps:

  1. Open Analytics > Institutional Usage
  2. Find the institution by name
  3. Note: seats used vs total, utilization rate, most active users
  4. Export the data as CSV for the renewal proposal
  5. If utilization is low, recommend engagement strategies; if high, propose additional seats

Scenario 4: Diagnosing a Conversion Drop

Context: MRR has dropped this month. Need to diagnose why.

Steps:

  1. Open Analytics -- compare 30d vs previous 30d
  2. Check Subscription Metrics -- is churn rate up, or are new subscribers down?
  3. Check Paywall Funnel -- are fewer people seeing paywalls (traffic drop)? Or is the funnel leaking?
  4. Check Traffic Sources -- has any channel dropped significantly?
  5. Check Top Content -- is popular content shifting away from premium articles?
  6. Check Device Breakdown -- is a mobile issue causing bounce rate increases?

Internal — QA, Testing & Limitations
21. QA Test Scenarios — Comprehensive Checklist
A. GA4 Event Tracking (Reader Portal)
#ScenarioStepsExpected ResultPriority
A1page_view fires on navigationOpen any page on Reader Portal, check GA4 debugpage_view event with page_pathP0
A2article_view firesOpen an article pagearticle_view with article_slug, article_sectionP0
A3article_scroll_depth 25%Scroll to 25% of articlearticle_scroll_depth with scroll_depth: 25P0
A4article_scroll_depth 50%Scroll to 50%scroll_depth: 50P1
A5article_scroll_depth 75%Scroll to 75%scroll_depth: 75P1
A6article_scroll_depth 100% + read_completeScroll to bottomBoth article_scroll_depth (100) and article_read_complete with read_time_secondsP0
A7paywall_view firesVisit premium article as anonymouspaywall_view with article_slugP0
A8paywall_click_subscribe firesClick "Subscribe" on paywallpaywall_click_subscribe with article_slugP0
A9subscribe_start firesBegin checkoutsubscribe_start with plan_name, plan_priceP1
A10subscribe_complete firesComplete paymentsubscribe_complete with plan_name, payment_methodP1
A11shop_product_view firesOpen shop product pageshop_product_view with product detailsP1
A12shop_add_to_cart firesClick Add to Cartshop_add_to_cart with product and quantityP1
A13shop_checkout_start firesClick Checkoutshop_checkout_start with cart valueP1
A14newsletter_view firesOpen newsletter editionnewsletter_view with slugP2
A15newsletter_scroll_depth firesScroll newsletter to 50%newsletter_scroll_depth with depthP2
A16Conversion surface eventsTrigger a conversion surfaceimpression, click, dismiss, conversion events all fireP1
A17coupon_copied firesCopy coupon code from surfacecoupon_copied with codeP2
A18Scroll milestones fire once onlyScroll article up and down repeatedlyEach milestone (25/50/75/100) fires exactly onceP1
B. Cookie Consent & Privacy
#ScenarioStepsExpected ResultPriority
B1Cookie banner appearsVisit Reader Portal in incognitoCookie consent banner visibleP0
B2Accept cookiesClick "Accept" on cookie bannerhyphen_cookie_consent: accepted in localStorage, GA4 events fireP0
B3Decline cookiesClick "Decline" (if available)GA4 events NOT sent to GoogleP1
B4Consent persistsAccept cookies, close tab, reopenBanner does not reappear, GA4 tracking activeP1
B5GA4 script presentCheck page sourcegtag.js loaded with correct Measurement IDP0
C. Admin Dashboard
#ScenarioStepsExpected ResultPriority
C1Dashboard loadsLogin to Admin ConsoleWelcome card + 4 stat cards + status cardsP0
C2Stats show real dataVerify articles, subscribers, views, engagementNumbers match database countsP1
C3Clickable cards navigateClick "Pending Review" cardOpens Content page filtered to pending_reviewP1
C4Most Popular shows articlesCheck Most Popular columnTop articles by view count displayedP1
C5Social overview showsCheck Social Overview widgetScheduled/This Week/Failed countsP2
D. Analytics Overview Page
#ScenarioStepsExpected ResultPriority
D1Analytics page loadsClick Analytics in sidebarPage renders with all sectionsP0
D2Date range: 7dSelect 7d in date pickerAll metrics update for last 7 daysP0
D3Date range: 30dSelect 30d (default)All metrics for last 30 daysP0
D4Date range: customSelect custom datesMetrics update for selected rangeP1
D5Key metrics cards show dataCheck 4 top cardsPage Views, Unique Visitors, Sessions, Avg Duration with % change arrowsP0
D6Traffic chart rendersCheck line chartTime-series with toggleable linesP1
D7Traffic sources showCheck Traffic Sources cardPercentage bars for each channelP1
D8Subscription metricsCheck Subscription sectionTotal, New, Churn Rate, MRR visibleP0
D9Plan breakdownCheck By Plan sectionSubscriber distribution across plansP1
D10Top content tableCheck Top ContentRanked articles with views, time, shares, commentsP1
D11Paywall funnel rendersCheck Paywall Conversion Funnel4 stages with counts and conversion ratesP1
D12Scroll depth sectionCheck Content Engagement25/50/75/100% distribution barsP1
D13Device breakdownCheck Device BreakdownDesktop/Mobile/Tablet percentagesP1
D14Top countriesCheck Top CountriesCountry list with flags and percentagesP2
D15Refresh buttonClick Refresh iconAll data reloads, icon spins during loadingP2
E. Data Export
#ScenarioStepsExpected ResultPriority
E1CSV export worksClick Export on Analytics pageCSV file downloads with traffic + subscription dataP1
E2Export with date rangeSet 7d, then exportCSV contains only last 7 days of dataP1
E3Export permission requiredLogin as user without ANALYTICS_EXPORTExport button not visibleP2
F. GA4 Connection & Configuration
#ScenarioStepsExpected ResultPriority
F1GA4 not configuredNo GA4 env vars setAnalytics page shows placeholder/empty data, no errorsP0
F2GA4 configuredGA4 env vars set correctlyReal data appears from GA4P0
F3GA4 connection errorSet invalid GA4 credentialsGraceful fallback to empty data, no crashP1
F4Subscription data always worksGA4 down or unconfiguredSubscription metrics still show (from Prisma DB)P0
G. Permission Controls
#ScenarioStepsExpected ResultPriority
G1No analytics permissionLogin as user without analytics:read"Access Restricted" with lock iconP1
G2Read-only permissionLogin with analytics:read onlyPage visible, Export button hiddenP1
G3Full permissionLogin as adminAll features accessible including exportP1
G4Social analytics permissionLogin without social:analytics:readSocial Analytics page shows access deniedP2
H. Institutional Usage
#ScenarioStepsExpected ResultPriority
H1Institutional metrics loadNavigate to Institutional UsageList of institutions with utilization dataP1
H2Usage reflects real dataCheck seat counts and active usersMatches database recordsP2
I. Edge Cases
#ScenarioStepsExpected ResultPriority
I1Empty state (no data)Fresh install with no readers or contentAll sections show empty/zero state, no errorsP1
I2Large date range (12m)Select 12 monthsCharts render without performance issuesP2
I3GA4 partial dataGA4 has traffic data but not scroll eventsAvailable data shows, missing data shows "No data"P2
I4Multiple browser tabsOpen Analytics in 2 tabs simultaneouslyBoth tabs load correctlyP2

22. Known Limitations
LimitationDescriptionImpact
GA4 data delayGA4 Data API can have 24-48 hour lag for some metricsRecent data may not reflect the very latest activity
No real-time traffic dashboardReal-time monitoring shows placeholder dataUse GA4 real-time view directly for live monitoring
Cookie consent reduces dataReaders who decline cookies are invisible to GA4Traffic numbers may undercount actual visitors
Traffic trend chart not fully wiredfetchTrafficTrend() returns empty arrayTime-series chart may show flat or no data
Geo data not fully wiredfetchGeoData() returns empty arrayTop Countries may show limited data
PDF export is placeholdergeneratePDFReport() returns placeholder dataOnly CSV export is functional
No A/B test analyticsNo built-in A/B testing frameworkUse GA4's built-in experiments for A/B testing
Scroll depth is page-levelScroll tracking measures page scroll, not article content scrollFor very long pages with headers/footers, 100% may not mean "finished article"
Social analytics depends on API connectionsSocial data only appears when Meta/X APIs are connectedMust configure social integrations first
Some GA4 events not yet wired to all call sitesSee section 22.1 below for detailsCertain GA4 events will not fire until wiring is completed
22.1 GA4 Event Wiring Status

All GA4 tracking functions are defined in reader-portal/src/lib/analytics.ts. However, not all functions are called from every relevant component. The table below shows current wiring status:

EventFunction DefinedWired to ComponentsStatus
article_scroll_depthYesYes -- observeScrollDepth() used in article templatesFully wired
article_read_completeYesYes -- fires at 100% scroll milestoneFully wired
newsletter_viewYesYes -- NewsletterEditionDetail useEffectFully wired
newsletter_scroll_depthYesYes -- observeNewsletterScrollDepth() in NewsletterEditionDetailFully wired
newsletter_read_completeYesYes -- fires at 100% newsletter scrollFully wired
newsletter_shareYesYes -- NewsletterEditionDetail share handlerFully wired
newsletter_list_viewYesYes -- NewsletterEditionGrid useEffectFully wired
conversion_surface_impressionYesYes -- ConversionSurfaceRenderer + InlineEmbedSurfaceFully wired
conversion_surface_clickYesYes -- ConversionSurfaceProviderFully wired
conversion_surface_dismissYesYes -- ConversionSurfaceProviderFully wired
conversion_surface_conversionYesYes -- ConversionSurfaceProviderFully wired
coupon_copiedYesYes -- all 5 surface componentsFully wired
article_viewYesNot yet wired to article page templatesPending
paywall_viewYesNot yet wired to PaywallOverlay/ArticlePaywallGatePending
paywall_click_subscribeYesNot yet wired to paywall CTA handlersPending
subscribe_startYesNot yet wired to checkout page mountPending
subscribe_completeYesNot yet wired to payment verification successPending
registration_startYesNot yet wired to register pagePending
newsletter_signupYesNot yet wired to newsletter form submissionsPending
shop_product_viewYesNot yet wired to shop product pagePending
shop_add_to_cartYesNot yet wired to CartProvider addItemPending
shop_checkout_startYesNot yet wired to cart checkout redirectPending

Impact on admin analytics:

  • The Paywall Conversion Funnel (Section 7) depends on paywall_view, paywall_click_subscribe, subscribe_start, and subscribe_complete events. Until these are wired, the funnel will show zero counts.
  • Content Performance scroll depth data works correctly (fully wired via observeScrollDepth).
  • Newsletter analytics are fully functional.
  • Conversion surface analytics are fully functional.
  • Shop/e-commerce analytics will not populate until shop events are wired.

Note for QA: When testing the Paywall Funnel and subscription events, expect zero data until the pending events are wired. This is a known implementation gap, not a bug. The tracking functions exist and are correct — they just need to be called from the appropriate component lifecycle hooks.


23. Glossary
TermDefinition
ARRAnnual Recurring Revenue (MRR x 12)
ARPUAverage Revenue Per User (MRR / active subscribers)
Bounce Rate% of visitors who leave after viewing only one page
ChannelTraffic source category (Organic, Direct, Social, Referral, Email, Paid)
Churn Rate% of subscribers who cancel in a period
Conversion Rate% of visitors who complete a desired action
CTRClick-Through Rate (clicks / impressions x 100)
GA4Google Analytics 4 -- Google's analytics platform
GA4 Data APIServer-side API for querying GA4 data programmatically
gtag.jsGoogle's JavaScript tracking library loaded on the Reader Portal
KPIKey Performance Indicator -- a measurable value showing effectiveness
LTVLifetime Value -- estimated total revenue from one subscriber
Measurement IDGA4 property identifier (format: G-XXXXXXXXXX)
MRRMonthly Recurring Revenue -- predictable monthly subscription income
Scroll DepthHow far down a reader scrolled (measured at 25/50/75/100%)
SessionA group of interactions in a single visit (ends after 30min inactivity)
UTMUrchin Tracking Module -- URL parameters for campaign tracking
Utilization RateFor institutions: active users / total seats

On this page

1. What Is the Analytics & Reporting System?2. Business Objectives & KPIsPrimary KPIs TrackedBusiness Questions the System Answers3. System Architecture — Where Data Comes FromData Source Mapping4. GA4 Event Catalog — Every Event the Platform Fires4.1 Automatic Events (fired by gtag.js)4.2 Article Engagement Events4.3 Paywall Events4.4 Subscription Events4.5 E-Commerce / Shop Events4.6 Conversion Surface Events4.7 Newsletter Events4.8 Registration EventsEvent Flow Summary5. Admin Dashboard — Quick Daily SnapshotLocationWhat It Shows6. Analytics Overview Page — Deep MetricsLocationControlsSection Layout7. Paywall Conversion FunnelWhat It TracksHow to Read the FunnelData Source8. Registration FunnelWhat It TracksAPI Endpoint9. Subscription & Revenue MetricsMetrics DisplayedRevenue by Plan BreakdownRevenue TrendAPI Endpoint10. Content Performance AnalyticsMetrics Per ArticleTop Content TableAuthor StatisticsAPI Endpoint11. Traffic Source AnalysisChannels TrackedUTM Attribution from Conversion SurfacesAPI Endpoint12. Device & Browser AnalyticsDevice CategoriesBrowser DistributionOperating SystemsAPI Endpoint13. Institutional Usage ReportingWhat It TracksUse CaseAPI Endpoint14. Social Media AnalyticsLocationTabsMetrics15. Data Export & ReportingExport FormatsAvailable ExportsHow to ExportPermission RequiredAPI Endpoint16. Cookie Consent & PrivacyHow It WorksImpact on AnalyticsPrivacy Compliance17. Scroll Depth & Reading Engagement TrackingHow Scroll Tracking WorksWhat the Admin SeesReading Progress (Internal Tracking)18. Conversion Surface Analytics19. User StoriesFor EditorsFor Product ManagersFor MarketingFor Sales / Customer SuccessFor QA20. Use Cases & ScenariosScenario 1: Monitoring a New Issue LaunchScenario 2: Evaluating a Marketing CampaignScenario 3: Institutional Renewal PreparationScenario 4: Diagnosing a Conversion Drop