Skip to content

feat(seo-gap-analysis): add public SEO competitor gap analysis endpoint - #3262

Draft
shrotia wants to merge 2 commits into
mainfrom
feat/seo-gap-analysis
Draft

feat(seo-gap-analysis): add public SEO competitor gap analysis endpoint#3262
shrotia wants to merge 2 commits into
mainfrom
feat/seo-gap-analysis

Conversation

@shrotia

@shrotia shrotia commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Adds the public async HTTP surface for the SEO/GEO/AEO competitor gap analysis feature:

  • POST /seo-gap-analysis: validates { keyword, targetUrl, filterDomains?, currentRanking?, locale? }, creates an AsyncJob (jobType seo-gap-analysis), enqueues a message on AUDIT_JOBS_QUEUE_URL for the audit worker, and returns 202 + { jobId, pollUrl }. Modeled on the site-detection async controller.
  • GET /seo-gap-analysis/jobs/:jobId: returns status + gap report, scoped to the seo-gap-analysis jobType via loadJobScopedToCaller (IDOR-safe).
  • Route wiring in routes/index.js + controller instantiation in index.js.
  • IMS + entitlement enforced declaratively: classified in required-capabilities (site:write / site:read) and facs-capabilities (llmo + aso, can_configure / can_view). jobId already lives in FACS_NON_RESOURCE_PARAMS.
  • OpenAPI: docs/openapi/seo-gap-analysis-api.yaml + registration in api.yaml.
  • Unit tests: 100% coverage on the controller (20 tests); all 3585 route drift tests pass with the new entries.

Companion branches of the same name in spacecat-audit-worker (SERP + scrape + diff handlers) and spacecat-content-scraper (seo-comparison scrape handler). Follow-up: integration tests under test/it/ (Docker/postgres seed harness).

Please ensure your pull request adheres to the following guidelines:

  • make sure to link the related issues in this description. Or if there's no issue created, make sure you
    describe here the problem you're solving.
  • when merging / squashing, make sure the fixed issue references are visible in the commits, for easy compilation of release notes

If the PR is changing the API specification:

  • make sure you add a "Not implemented yet" note the endpoint description, if the implementation is not ready
    yet. Ideally, return a 501 status code with a message explaining the feature is not implemented yet.
  • make sure you add at least one example of the request and response.

If the PR is changing the API implementation or an entity exposed through the API:

  • make sure you update the API specification and the examples to reflect the changes.

If the PR is introducing a new audit type:

  • make sure you update the API specification with the type, schema of the audit result and an example

Related Issues

Thanks for contributing!

@shrotia
shrotia marked this pull request as draft September 11, 2026 11:42
@github-actions

Copy link
Copy Markdown

This PR will trigger a minor release when merged.

@codecov

codecov Bot commented Sep 11, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@shrotia
shrotia deployed to dev-branches September 11, 2026 12:23 — with GitHub Actions Active
shrotia and others added 2 commits September 11, 2026 18:31
Adds the public async HTTP surface for the SEO/GEO/AEO competitor gap
analysis feature:

- POST /seo-gap-analysis: validates { keyword, targetUrl, filterDomains?,
  currentRanking?, locale? }, creates an AsyncJob (jobType seo-gap-analysis),
  enqueues a message on AUDIT_JOBS_QUEUE_URL for the audit worker, and returns
  202 + { jobId, pollUrl }. Modeled on the site-detection async controller.
- GET /seo-gap-analysis/jobs/:jobId: returns status + gap report, scoped to
  the seo-gap-analysis jobType via loadJobScopedToCaller (IDOR-safe).
- Route wiring in routes/index.js + controller instantiation in index.js.
- IMS + entitlement enforced declaratively: classified in required-capabilities
  (site:write / site:read) and facs-capabilities (llmo + aso, can_configure /
  can_view). jobId already lives in FACS_NON_RESOURCE_PARAMS.
- OpenAPI: docs/openapi/seo-gap-analysis-api.yaml + registration in api.yaml.
- Unit tests: 100% coverage on the controller (20 tests); all 3585 route
  drift tests pass with the new entries.

Companion branches of the same name in spacecat-audit-worker (SERP + scrape +
diff handlers) and spacecat-content-scraper (seo-comparison scrape handler).
Follow-up: integration tests under test/it/ (Docker/postgres seed harness).

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

getRouteHandlers is called positionally; adding the seoGapAnalysisController
parameter shifted every subsequent controller in the route-segregation test,
which passed controllers by position. Add the mock controller in the matching
position and register the two new routes in the expected static/dynamic sets.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@shrotia
shrotia force-pushed the feat/seo-gap-analysis branch from 8b52474 to 082b117 Compare September 11, 2026 13:04
@shrotia
shrotia deployed to dev-branches September 11, 2026 13:13 — with GitHub Actions Active
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