feat(rum): scope latest-metrics RUM to locale path prefix#1707
feat(rum): scope latest-metrics RUM to locale path prefix#1707alinarublea wants to merge 2 commits into
Conversation
Locale-specific sites (e.g. https://example.com/de) have no RUM domain key of their own — keys exist only for the main domain. Today the totalMetrics query resolves the bare hostname and aggregates RUM for the entire parent domain, so locale sites report domain-wide numbers instead of their own subtree. Add result-level path scoping: - spacecat-shared-utils: getBaseURLPathPrefix(baseURL) extracts the locale path (e.g. '/de'), or null at the domain root. - spacecat-shared-rum-api-client: the totalMetrics handler now reads opts.pathPrefix and filters bundles to that subtree before aggregating, with boundary-safe matching ('/de' does not match '/design'). Opt-in: with no pathPrefix the handler behaves exactly as before. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Hey @alinarublea,
⚠ Degraded review - no spec document was found for this change (searched the PR links, the touched repos' docs, the architecture/guidelines docs, and linked Jira). This review covers code-level quality but could not validate the change against an agreed design, so confidence is reduced. Add a spec link (PR template section 4) and re-request review for a full-confidence pass.
Verdict: Approve - clean, well-scoped feature with solid test coverage.
Complexity: LOW - small diff, single package surface.
Changes: Adds opt-in locale path-prefix filtering to the totalMetrics RUM handler plus a getBaseURLPathPrefix utility for extracting the path prefix from a site's baseURL (6 files).
Non-blocking (3): minor issues and suggestions
- nit:
matchesPathPrefixdoes not normalizeprefix- if a caller passes/de/(trailing slash), the boundary checkpath.startsWith('/de//')silently fails to match nested paths. A defensiveprefix.replace(/\/+$/, '')would make this robust against future callers that skip normalization -packages/spacecat-shared-rum-api-client/src/functions/total-metrics.js:22 - nit: Silent catch blocks in both
matchesPathPrefixandgetBaseURLPathPrefixprovide no observability signal when bundles or URLs are dropped due to parse failure. For a data-aggregation pipeline, systematically malformed URLs would silently degrade metrics with no alert -packages/spacecat-shared-rum-api-client/src/functions/total-metrics.js:23 - suggestion: Add a test for empty-string
pathPrefixto lock in the falsy-means-no-filter contract, since''could arrive from upstream coercion of a null return -packages/spacecat-shared-rum-api-client/test/total-metrics.test.js:79
Skill: pr-review | Model: us.anthropic.claude-opus-4-6-v1[1m] | Duration: 8m 37s | Cost: $3.58 | Commit: 851176e272acc7e92d556b4533e2a1a80791e94a
If this code review was useful, please react with 👍. Otherwise, react with 👎.
|
This PR will trigger a minor release when merged. |
Why
Locale-specific sites (e.g.
https://example.com/de) have no RUM domain key of their own — domain keys exist only for the main domain. TodaywwwUrlResolverstrips the path and thetotalMetricsquery aggregates RUM for the entire parent domain, so a locale site'slatest-metricsreports domain-wide numbers rather than its own subtree.What
Result-level path scoping for
totalMetrics, opt-in via a newpathPrefixoption:spacecat-shared-utils— newgetBaseURLPathPrefix(baseURL)helper: extracts the locale path (https://example.com/de→/de), returnsnullat the domain root or for unparseable input.spacecat-shared-rum-api-client— thetotalMetricshandler now readsopts.pathPrefixand filters bundles to that subtree before aggregating. Matching is boundary-safe:/dematches/deand/de/...but not/design.With no
pathPrefix, behavior is byte-for-byte identical to today — no existing caller is affected.How it fits together
domainstays the bare hostname (required by the bundler URL and for domain-key resolution on the main domain). The locale scoping happens purely at the result level. The consuming side —spacecat-api-service'sgetLatestSiteMetricsextracting the prefix fromsite.getBaseURL()and passing it through — lands in a follow-up PR in that repo (this shared release must publish first).The prefix-matching logic is intentionally kept self-contained in
rum-api-clientrather than importing the new util, to avoid a cross-package version bump (rum-api-clientpins an exactspacecat-shared-utilsversion).Out of scope
Subdomain-based locales (
de.example.com) —wwwUrlResolverreturns the full subdomain host, a separate case to be addressed independently.Tests
getBaseURLPathPrefix: root → null, trailing slash, single/multi-segment, schema-less, unparseable, null/undefined.url-helpers.jsat 100% coverage.totalMetrics: aggregates all withoutpathPrefix(regression guard); scopes to subtree with it; rejects look-alike sibling paths; drops bundles with missing/invalid URLs.🤖 Generated with Claude Code