Skip to content

Premium Analytics: normalize Stats time-series reports - #49779

Merged
kangzj merged 1 commit into
trunkfrom
split/stats-time-series-normalizers
Jun 24, 2026
Merged

Premium Analytics: normalize Stats time-series reports#49779
kangzj merged 1 commit into
trunkfrom
split/stats-time-series-normalizers

Conversation

@kangzj

@kangzj kangzj commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Fixes #

Proposed changes

  • Add split Stats normalizers for generic time-series reports, visits, email summary, and email breakdowns.
  • Keep endpoint-specific normalizers separate; this PR does not change the existing traffic endpoint normalizers from the earlier stack.
  • Normalize generic time-series payloads from matrix fields/data, object data, and scalar/object days shapes.
  • Normalize email summary and email breakdown payloads, including fieldless email all-time breakdown arrays for countries, clients/devices, and links.
  • Use date-fns helpers for week/month/year interval boundaries and validate ISO week labels before normalizing them.
  • Add focused fixtures and tests for visits/time-series payloads, email payloads, scalar days maps, month/year/leap-year boundaries, and invalid ISO week fallback.

Related product discussion/links

Does this pull request change what data or activity we track or use?

No. This only normalizes existing Stats API response shapes.

Testing instructions

  • Run pnpm --dir projects/packages/premium-analytics test --runInBand projects/packages/premium-analytics/packages/data/src/processing/stats.
  • Run pnpm --dir projects/packages/premium-analytics typecheck.
  • Run pnpm --dir projects/packages/premium-analytics test --runInBand.
  • Browser verification for the stack: the live Stats dashboard request capture confirmed the visits/time-series request pattern, and raw authenticated replays confirmed the non-summarized date, period, and days response shape expected by the normalizers.

Out of scope

  • This PR does not add a generic value field to existing endpoint normalizers. Consumers should choose the primary row metric in a follow-up adapter/row-contract change, tracked in WOOA7S-1585.

@kangzj kangzj added Enhancement Changes to an existing feature — removing, adding, or changing parts of it [Feature] Stats Data Feature that enables users to track their site's traffic and gain insights on popular content. [Status] Needs Review This PR is ready for review. [Package] Premium Analytics labels Jun 19, 2026
@kangzj kangzj self-assigned this Jun 19, 2026
@jp-launch-control

jp-launch-control Bot commented Jun 19, 2026

Copy link
Copy Markdown

Code Coverage Summary

This PR did not change code coverage!

That could be good or bad, depending on the situation. Everything covered before, and still is? Great! Nothing was covered before? Not so great. 🤷

Full summary · PHP report

@github-actions

Copy link
Copy Markdown
Contributor

Thank you for your PR!

When contributing to Jetpack, we have a few suggestions that can help us test and review your patch:

  • ✅ Include a description of your PR changes.
  • ✅ Add a "[Status]" label (In Progress, Needs Review, ...).
  • ✅ Add testing instructions.
  • ✅ Specify whether this PR includes any changes to data or privacy.
  • ✅ Add changelog entries to affected projects

This comment will be updated as you work on your PR and make changes. If you think that some of those checks are not needed for your PR, please explain why you think so. Thanks for cooperation 🤖


Follow this PR Review Process:

  1. Ensure all required checks appearing at the bottom of this PR are passing.
  2. Make sure to test your changes on all platforms that it applies to. You're responsible for the quality of the code you ship.
  3. You can use GitHub's Reviewers functionality to request a review.
  4. When it's reviewed and merged, you will be pinged in Slack to deploy the changes to WordPress.com simple once the build is done.

If you have questions about anything, reach out in #jetpack-developers for guidance!

@kangzj

This comment has been minimized.

@claude

This comment has been minimized.

@kangzj

This comment has been minimized.

This comment has been minimized.

@kangzj kangzj added [Status] Needs Team Review Obsolete. Use Needs Review instead. and removed [Status] Needs Review This PR is ready for review. labels Jun 19, 2026
@kangzj
kangzj force-pushed the split/stats-core-hooks branch from 2ee039e to 87426da Compare June 19, 2026 04:44
@kangzj
kangzj force-pushed the split/stats-time-series-normalizers branch from a8bab25 to 5893252 Compare June 19, 2026 04:46
@kangzj
kangzj force-pushed the split/stats-core-hooks branch from 87426da to ab39774 Compare June 19, 2026 04:49
@kangzj
kangzj force-pushed the split/stats-time-series-normalizers branch from 5893252 to 48d0ccd Compare June 19, 2026 04:49
@kangzj

This comment has been minimized.

@kangzj

This comment has been minimized.

@claude

This comment has been minimized.

This comment has been minimized.

@kangzj
kangzj force-pushed the split/stats-core-hooks branch from ab39774 to 92cbcd5 Compare June 19, 2026 05:10
@kangzj
kangzj force-pushed the split/stats-time-series-normalizers branch from a39be3f to bf4d0bb Compare June 19, 2026 05:10
@kangzj

This comment has been minimized.

@kangzj
kangzj force-pushed the split/stats-time-series-normalizers branch from 3182cdc to 34c4485 Compare June 23, 2026 02:24
@kangzj
kangzj changed the base branch from split/stats-core-hooks to trunk June 23, 2026 02:25
@kangzj
kangzj changed the base branch from trunk to split/stats-core-hooks June 23, 2026 02:26
Base automatically changed from split/stats-core-hooks to trunk June 23, 2026 02:58
@kangzj
kangzj force-pushed the split/stats-time-series-normalizers branch 4 times, most recently from a34d9c3 to 4af76c8 Compare June 23, 2026 03:55
@kangzj

This comment was marked as outdated.

@claude

This comment was marked as outdated.

@kangzj
kangzj force-pushed the split/stats-time-series-normalizers branch 2 times, most recently from e966077 to 8160906 Compare June 23, 2026 04:54
@kangzj

kangzj commented Jun 23, 2026

Copy link
Copy Markdown
Contributor Author

Addressed Claude review feedback from #4775464752 in 8160906483.

Changes:

  • Replaced new Date( 0 ) with new Date( 2001, 0, 1 ) so date-fns parsing has a timezone-safe local day/month reference.
  • Added a comment documenting that value uses the first numeric metric in API field/object order.
  • Added coverage for top-level data[] object rows and isStatsTimeSeriesPayload.
  • Added fallback/empty tests for email breakdown and email summary.

Verification:

  • TZ=America/New_York pnpm --dir projects/packages/premium-analytics test --runInBand projects/packages/premium-analytics/packages/data/src/processing/stats/__tests__/time-series.test.ts
  • pnpm --dir projects/packages/premium-analytics test --runInBand projects/packages/premium-analytics/packages/data/src/processing/stats
  • pnpm --dir projects/packages/premium-analytics typecheck
  • pnpm --dir projects/packages/premium-analytics test --runInBand

@kangzj
kangzj force-pushed the split/stats-time-series-normalizers branch 2 times, most recently from 3cc3dcd to 65eb9da Compare June 24, 2026 01:27
@kangzj

kangzj commented Jun 24, 2026

Copy link
Copy Markdown
Contributor Author

@claude review plz

@claude

This comment was marked as outdated.

@kangzj
kangzj force-pushed the split/stats-time-series-normalizers branch from 65eb9da to 53fb0cf Compare June 24, 2026 01:53
@kangzj

kangzj commented Jun 24, 2026

Copy link
Copy Markdown
Contributor Author

Addressed the email breakdown summary observation in 53fb0cf494.

Changes:

  • The empty/no-metric email breakdown path now keeps only numeric scalar summary values instead of passing the whole raw response through summary.
  • Added a regression case with nested empty countries / countries-info payload data to verify those raw objects do not leak into summary.

I left the time-series summary.value asymmetry as a conscious follow-up for the row-contract work tracked in WOOA7S-1585.

Verified:

  • pnpm --dir projects/packages/premium-analytics test --runInBand projects/packages/premium-analytics/packages/data/src/processing/stats/__tests__/email-breakdown.test.ts
  • pnpm --dir projects/packages/premium-analytics test --runInBand projects/packages/premium-analytics/packages/data/src/processing/stats
  • pnpm --dir projects/packages/premium-analytics typecheck
  • pnpm --dir projects/packages/premium-analytics test --runInBand

@kangzj

This comment was marked as outdated.

@claude

This comment was marked as outdated.

@kangzj
kangzj force-pushed the split/stats-time-series-normalizers branch from 53fb0cf to 44f6365 Compare June 24, 2026 02:02
@kangzj

kangzj commented Jun 24, 2026

Copy link
Copy Markdown
Contributor Author

Addressed in 44f6365e91.

Changes:

  • Added a note documenting that matrix email-link payloads intentionally keep API labels while fieldless all-time link payloads map known link types to display labels.
  • Fixed the CI ESLint/Prettier failure in email-breakdown.ts.

Verified locally:

  • pnpm run lint-file projects/packages/premium-analytics/packages/data/src/processing/stats/email-breakdown.ts --max-warnings=0
  • pnpm --dir projects/packages/premium-analytics test --runInBand projects/packages/premium-analytics/packages/data/src/processing/stats
  • pnpm --dir projects/packages/premium-analytics typecheck
  • pnpm --dir projects/packages/premium-analytics test --runInBand

@kangzj

This comment was marked as outdated.

@claude

claude Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kangzj's task in 1m 22s —— View job


Re-review — current head 44f6365e

Read the full layer again (time-series.ts, visits.ts, email-summary.ts, email-breakdown.ts, utils.ts, types.ts, index.ts, fixtures + tests). Everything from the four prior rounds is resolved and the new label-asymmetry note landed cleanly. ✅ to merge from my side — no blockers.

Confirmed resolved

Prior item Status
TZ-dependent month/year parse referenceDate = new Date( 2001, 0, 1 ) (time-series.ts:24) — local day-of-month is 1 everywhere, so the yyyy-MM/yyyy round-trip guards hold
Implicit first-numeric-field value contract ✅ comment at time-series.ts:84
data[] object-row path + isStatsTimeSeriesPayload untested objectRowsTimeSeriesFixture + detection test incl. negative case (time-series.test.ts:39, :134)
Email breakdown empty path leaking raw objects ✅ scalar-only summary (email-breakdown.ts:204-215) with nested-empty countries/countries-info regression (email-breakdown.test.ts:26)
Matrix vs fieldless email-link label asymmetry ✅ documented at email-breakdown.ts:186-188

Spot checks this pass

  • Leap-year boundaries (2024-02-29, 2024-12-31) and invalid-ISO-week fallbacks (2026-W54, 2025-W53) are explicit and correct — the format() round-trip rejects overflowed weeks/months before they reach startOf/endOf*.
  • index.ts exports (sanitizeStatsTimeSeriesResponse, Visits, EmailSummary, EmailBreakdown + the two item types) and the StatsNormalizedItem union additions in types.ts line up — no dangling exports.
  • sortEmailBreakdownItems keeps Other last regardless of value (email-breakdown.ts:36-48); the link test (Post URL 7 → url 4 → url 2 → Like 1 → Other 3) confirms the ordering contract.
  • email-summary.ts correctly emits data: [] on the empty-posts path while still returning a zeroed summary — consistent with the breakdown empty path.

Still a conscious deferral (non-blocking)

  • summary.value asymmetry in time-series.ts — present only on the scalar-days path, absent on matrix/object paths. Already flagged for the row-contract follow-up (WOOA7S-1585); leaving it stays consistent with that plan.

Note: the Jest command is blocked in this review sandbox, so the above is static-only — your posted local + TZ=America/New_York runs cover execution.
· split/stats-time-series-normalizers

@kangzj
kangzj merged commit 56a2528 into trunk Jun 24, 2026
72 checks passed
@kangzj
kangzj deleted the split/stats-time-series-normalizers branch June 24, 2026 02:26
@github-actions github-actions Bot removed the [Status] Needs Team Review Obsolete. Use Needs Review instead. label Jun 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Enhancement Changes to an existing feature — removing, adding, or changing parts of it [Feature] Stats Data Feature that enables users to track their site's traffic and gain insights on popular content. [Package] Premium Analytics

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants