Skip to content

feat: add content types in SR URL Inspector Filters response#2884

Open
vivesing wants to merge 1 commit into
mainfrom
feat/sr-url-inspector-filters
Open

feat: add content types in SR URL Inspector Filters response#2884
vivesing wants to merge 1 commit into
mainfrom
feat/sr-url-inspector-filters

Conversation

@vivesing

Copy link
Copy Markdown
Contributor

Summary: Add content_types filter dimension to URL Inspector

Context

GET /v2/orgs/:orgId/brands/:brandId/serenity/brand-presence/url-inspector/filter-dimensions
previously fetched 3 Semrush elements (TOPICS, BRANDS, MARKETS) and returned brands,
regions, topics, categories, page_intents, origins, plus dynamic tag groups. A new
Semrush element (d1f9e6ec-9128-4b1b-b767-d86f93f54237) exposes domain_type values
(Owned/Other/Social/Earned/Benchmark Competitors) and is now wired in as a
content_types dimension.

Files changed

File Change
src/support/elements/element-ids.js Added ELEMENT_IDS.CONTENT_TYPES UUID constant
src/support/elements/definitions/content-types.js New. buildContentTypesPayload() (CBF_model + CBF_date range, default rolling 28-day window) and transformContentTypesToFilterDimensions() (maps each label → { id: slugified label, label })
src/support/elements/definitions/index.js Re-exports the two new functions
src/support/elements/elements-service.js Added a 4th parallel fetchElement call for CONTENT_TYPES; added content_types key to getUrlInspectorFilterDimensions result
src/controllers/elements.js Updated JSDoc listing returned dimensions

Behavior

  • id is derived from the Semrush label (lowercased, spaces → underscores) — no hardcoded
    lookup table needed:
    • Ownedowned, Otherother, Socialsocial, Earnedearned,
      Benchmark Competitorsbenchmark_competitors
  • Order in the response follows Semrush's own element order (not re-sorted), consistent with
    how every other dimension in this endpoint behaves.
  • Uses the same startDate/endDate/model/platform query params already accepted by the
    endpoint.

Tests added

File Coverage
test/support/elements/definitions/content-types.test.js (new) buildContentTypesPayload: default/known/unknown model, platform alias, explicit dates, default 28-day window, payload shape (union, and, empty simple). transformContentTypesToFilterDimensions: null/empty
input, single- and multi-word label→id, filtering blank v
test/support/elements/elements-service.test.js Added RAW_CONTENT_TYPES fixture + ELEMENT_IDS.CONTENT_TYPES stub; bumped
fetch-call-count assertions to 4; added content_types tded dedicated assertion on the transformed content_types array
test/controllers/elements.test.js No changes needed — mocks the service boundary, agnostic to the new dimension

Result: 150/150 tests passing across the touched suites, lint clean.

image

@vivesing
vivesing requested a review from MysticatBot July 22, 2026 09:12

@MysticatBot MysticatBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @vivesing,

⚠ 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: Request changes - OpenAPI schema must be updated to reflect the new content_types response field.
Complexity: HIGH - medium diff; API surface change.
Changes: Adds a content_types filter dimension to the URL Inspector endpoint by wiring a new Semrush element fetch in parallel with the existing ones (7 files).

Must fix before merge

  1. [Important] OpenAPI schema SerenityUrlInspectorFilterDimensions in docs/openapi/schemas.yaml does not include the new content_types property - src/support/elements/elements-service.js:103 (details inline)
Non-blocking (4): minor issues and suggestions
  • nit: id derivation from Semrush label (label.toLowerCase().replace(/\s+/g, '_')) means upstream label changes silently change IDs that consumers may persist. Consider a static mapping for known values with fallback derivation for unknowns - src/support/elements/definitions/content-types.js:98
  • suggestion: Use sinon.useFakeTimers in the "defaults to a rolling 28-day window" test to prevent rare flakiness near day/month boundaries - test/support/elements/definitions/content-types.test.js:56
  • nit: DEFAULT_WINDOW_DAYS = 28 duplicates a constant from llmo-brand-presence.js / cited-domains.js; shared extraction would prevent drift - src/support/elements/definitions/content-types.js:18
  • suggestion: Add a test for buildContentTypesPayload({ model: 'perplexity', platform: 'openai' }) to document that model takes precedence over platform - test/support/elements/definitions/content-types.test.js

Skill: pr-review | Model: us.anthropic.claude-opus-4-6-v1[1m] | Duration: 4m 53s | Cost: $5.51 | Commit: 42a15fbe3d46d62b87ec9ced927c0ecbd34acabb
If this code review was useful, please react with 👍. Otherwise, react with 👎.

categories: transformCategoriesToFilterDimensions(rawTopics),
page_intents: transformIntentsToFilterDimensions(rawTopics),
origins: transformOriginsToFilterDimensions(rawTopics),
content_types: transformContentTypesToFilterDimensions(rawContentTypes),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (blocking): The CLAUDE.md rule "Specification Sync: Keep OpenAPI specs and implementation in sync" requires that this response-shape change be reflected in the OpenAPI schema.

The SerenityUrlInspectorFilterDimensions schema in docs/openapi/schemas.yaml lists required: [brands, regions, topics, categories, page_intents, origins, tags] and its properties block does not include content_types. After this PR, the implementation returns a field the spec does not declare.

Fix: Add content_types to both the required array and the properties section of SerenityUrlInspectorFilterDimensions in docs/openapi/schemas.yaml, following the same type: array, items: object pattern as the sibling dimensions. Then run npm run docs:build to regenerate.

@MysticatBot MysticatBot added ai-reviewed Reviewed by AI complexity:high AI-assessed PR complexity: HIGH labels Jul 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-reviewed Reviewed by AI complexity:high AI-assessed PR complexity: HIGH

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants