Skip to content

feat(elements): add brand-presence market-tracking-trends endpoint#2827

Open
jjenscodee wants to merge 1 commit into
mainfrom
feat/semrush-market
Open

feat(elements): add brand-presence market-tracking-trends endpoint#2827
jjenscodee wants to merge 1 commit into
mainfrom
feat/semrush-market

Conversation

@jjenscodee

Copy link
Copy Markdown
Contributor

New endpoint: GET /v2/orgs/:spaceCatId/brands/:brandId/serenity/brand-presence/market-tracking-trends

Summary

Adds a Semrush Elements-backed endpoint returning weekly per-competitor mentions + citations for the tracked brand and its competitors — the data behind the Competitor Comparison chart (CitationsMentionsTrendChart) on the brand-presence-sr-ui dashboard.

Full design notes, the confirmed Semrush payload/response shapes, and resolved decisions are in docs/elements/market-tracking-trends-plan.md (modeled on brand-presence-stats-plan.md from #2823). All brand names and metrics in the docs/tests are synthetic.

The element mapping was verified by observing the Brand Presence MFE's "Market Tracking" chart request/response shapes (Mentions and Citations tabs) — not inferred from the migration wiki, whose documented citations trend element (b81af644, domain-level) is not what this chart uses.

Element mapping

Both are type: "line", auto_bucketing: "week", no brand filter (so competitors come back natively as tracked-benchmark legends):

Chart metric Element Constant Project filter col Value field
Mentions b5281393 TRENDS_MV (existing) CBF_project (singular) y__mentions
Citations 2e5a6f4e MARKET_CITATIONS_TREND (new) CBF_projects (plural) y__mentions

⚠️ Both elements expose the value under the key y__mentions; in the citations element that number is the citation count (Semrush reuses the generic key). The transform maps each to the right metric.

What changed

  • Route + auth scaffold (routes/index.js, routes/facs-capabilities.jsllmo/can_view, routes/required-capabilities.jsbrand:read): registers the route under the existing brand-scoped authorizeOrg pattern; brandId reuses the existing LLMO FACS brand alias.
  • Controller getMarketTrackingTrends (controllers/elements.js): mirrors the URL-inspector handlers — authorizeOrg, siteId cross-check, optional dates with a 28-day trailing default + validation, region→projectId resolution (else aggregate across all the brand's projects), cachedOk.
  • Definitions (support/elements/definitions/market-tracking-trends.js, new): weekly payload builders (CBF_project vs CBF_projects, no brand filter, no comparison_data_formatting) + transformMarketTrackingTrends — groups both blocks.lines[] by ISO week, splits the brand line from competitor lines, defaults a missing metric to 0.
  • Service getMarketTrackingTrends (support/elements/elements-service.js): fetches the two elements in parallel; no per-week fan-out (elements are pre-bucketed) and no per-competitor fan-out (legend carries them). projectId (single region) takes precedence over projectIds (aggregate).
  • Element id (support/elements/element-ids.js): new MARKET_CITATIONS_TREND.
  • Design doc (docs/elements/market-tracking-trends-plan.md, new).

Response shape

{
  "weeklyTrends": [
    {
      "week": "2026-07-05", "weekNumber": 27, "year": 2026,
      "mentions": 900, "citations": 5000,
      "competitors": [ { "name": "Rival One", "mentions": 150, "citations": 300 } ]
    }
  ]
}

Testing

  • New/added unit suites: definitions (payload builders + transform), service (getMarketTrackingTrends), controller (auth, date defaulting/validation, region resolution + 404, siteId cross-check, error mapping), and route registration.
  • Route-param FACS classification + required-capabilities drift suites pass.
  • Weekly-only bucketing for now; visibility intentionally excluded (out of scope for this chart).

Out of scope

UI wiring (DAL service + hook + SRCompetitorComparisonSection); Competitor Summary / Share of Voice / Sentiment endpoints; day/month bucketing.

🤖 Generated with Claude Code

Add GET /v2/orgs/:spaceCatId/brands/:brandId/serenity/brand-presence/market-tracking-trends,
a Semrush Elements wrapper returning weekly per-competitor mentions + citations for the
brand-presence-sr-ui Competitor Comparison chart (CitationsMentionsTrendChart).

Mentions come from TRENDS_MV (b5281393); citations from the market-tracking citations
element (2e5a6f4e, new MARKET_CITATIONS_TREND constant). Both are weekly line elements
that return one series per market participant keyed by legend=name, so competitors arrive
natively as tracked benchmarks with no fan-out. The contract was ground-truthed against
the live Brand Presence MFE. See docs/elements/market-tracking-trends-plan.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

This PR will trigger a minor release when merged.

@codecov

codecov Bot commented Jul 15, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 99.39577% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/controllers/elements.js 98.05% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

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.

1 participant