Skip to content

feat(brand-governance): replace /checks with /profile endpoint in BrandGovernanceClient#1667

Open
anagarwa wants to merge 2 commits into
mainfrom
feat/brand-governance-profile-api
Open

feat(brand-governance): replace /checks with /profile endpoint in BrandGovernanceClient#1667
anagarwa wants to merge 2 commits into
mainfrom
feat/brand-governance-profile-api

Conversation

@anagarwa

Copy link
Copy Markdown
Contributor

Summary

  • Replaces the paginated /checks?scope=COPY endpoint with the single /profile endpoint in BrandGovernanceClient.getBrandGuidelinesForUrl()
  • Returns the raw Brand Governance Agent profile response ({ data: { identity, voice_and_tone, language, messaging, editorial } }) directly to callers — no mapping needed server-side
  • Returns null on 404 from either /from-url or /profile, preserving the existing fallback contract for callers

Test plan

  • Replaced mockBrandChecks helper with mockBrandProfile in test suite
  • Updated success test to verify raw profile data is returned as-is
  • Added test for 404 from /profile endpoint (returns null)
  • Updated header verification test to assert against /profile endpoint
  • Updated fresh-token test to use /profile mock
  • All 37 tests passing, 100% line/branch/function coverage

🤖 Generated with Claude Code

@anagarwa anagarwa added the OrcaFix Raised by the OrcaFix skill label Jun 11, 2026

@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 @anagarwa,

Verdict: Request changes - the return type change is a breaking change that needs a major version signal and TypeScript declaration update.
Changes: Replaces paginated /checks endpoint with single /profile endpoint in BrandGovernanceClient, returning raw upstream response instead of mapped guidelines object (2 files).

Must fix before merge

  1. [Critical] Breaking change shipped under minor semver bump - consumers accessing .guidelines, .id will get undefined - brand-governance-client.js:153 (details inline)
  2. [Important] Method name getBrandGuidelinesForUrl no longer matches the profile data it returns - brand-governance-client.js:25 (details inline)
  3. [Important] TypeScript declaration (src/index.d.ts) still declares return type BrandGovernanceGuidelines with { id, name, imsOrgId, createdAt, updatedAt, guidelines } - now actively incorrect after this change. Update or replace the interface to reflect the actual /profile response shape.

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

guidelines,
};
}
return profileResponse.json();

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): This return statement changes the public API contract from { id, name, imsOrgId, createdAt, updatedAt, guidelines: [{name, text}] } to the raw upstream /profile response ({ data: { identity, voice_and_tone, ... }, meta }). Every consumer accessing .guidelines, .id, .name etc. will get undefined at runtime.

Since this is a shared library consumed by multiple services and semantic-release will produce a minor bump from the feat() prefix, consumers on ^ ranges will auto-upgrade and break silently.

Fix: Use feat!: or add a BREAKING CHANGE: footer to the commit message so semantic-release produces a major version bump. Coordinate downstream consumer updates before or alongside this release.

* Client for the Adobe Brand Governance Agent API.
* Resolves brand guidelines by site URL using COPY-scoped checks.
* Returns null when the brand is not registered — caller falls back to Brand Publish.
* Resolves brand profile by site URL using the /profile endpoint.

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 method is still named getBrandGuidelinesForUrl but now returns a brand profile (identity, voice_and_tone, language, editorial) - not guidelines. The JSDoc was updated to say "profile" but the method name was not.

Fix: Rename to getBrandProfileForUrl (breaking regardless, so bundle with the major bump). If backward compat is needed short-term, add the new name and deprecate the old.

@MysticatBot MysticatBot added the ai-reviewed Reviewed by AI label Jun 16, 2026

@duynguyen duynguyen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Review

Clean simplification — removing the pagination loop, CHECKS_PAGE_SIZE, and MAX_PAGES constants is a nice improvement. Tests are well-structured and the new 404-from-profile test is a good addition.

One nit: return profileResponse.json() on the last line — prefer return await profileResponse.json() for style consistency with the rest of the file and to keep the stack trace intact if .json() throws.

Heads up: this is a breaking contract change (return type goes from { id, name, imsOrgId, createdAt, updatedAt, guidelines } to the raw { data, meta } response). Make sure the consuming service PRs are merged alongside this one.

@anagarwa anagarwa left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@MysticatBot
Thanks for the thorough review! Addressing all three points:

1. Semver bump — no major needed
There are no existing consumers of BrandGovernanceClient.getBrandGuidelinesForUrl() in production today. This is the first integration — the companion PRs in spacecat-api-service and mystique are being merged alongside this one. Since no deployed service is currently reading .guidelines, .id, or .name from the return value, there is no consumer to silently break. A minor bump is appropriate here.

2. Method name — keeping getBrandGuidelinesForUrl
The method name reflects its role in the SpaceCat Brand Guidelines API, not the Brand Governance Agent's internal endpoint name. From the caller's perspective (spacecat-api-service /sites/:siteId/brand-guidelines), this method resolves brand guidelines for a URL — which is exactly what it does. Renaming it to getBrandProfileForUrl would leak the Brand Governance Agent's internal concept into our API surface. The method name stays.

3. TypeScript declaration — updated
Fixed in commit 9e42c012. Replaced the stale BrandGovernanceGuideline + BrandGovernanceGuidelines interfaces (which reflected the old /checks-based shape) with a minimal BrandGovernanceProfile { data: Record<string, unknown>; meta?: Record<string, unknown> }. Since the client is a raw passthrough of the /profile response, we keep the type intentionally loose rather than over-specifying every nested field.

@MysticatBot review again ?

@anagarwa anagarwa requested a review from MysticatBot June 23, 2026 17:00
@github-actions

Copy link
Copy Markdown

This PR will trigger a minor release when merged.

@anagarwa anagarwa dismissed MysticatBot’s stale review June 23, 2026 17:24

Answered all the questions and Also with 1 commits that covers the changes

anagarwa and others added 2 commits June 23, 2026 22:54
…ndGovernanceClient

Switches from the paginated /checks?scope=COPY endpoint to the single
/profile endpoint, returning the raw Brand Governance Agent profile
response to callers.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rnanceProfile shape

Replace stale BrandGovernanceGuidelines interface (from the old /checks-based
return shape) with BrandGovernanceProfile { data, meta } matching the raw
/profile response now returned by getBrandGuidelinesForUrl.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@anagarwa anagarwa force-pushed the feat/brand-governance-profile-api branch from 9e42c01 to 2a7a298 Compare June 23, 2026 17:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-reviewed Reviewed by AI OrcaFix Raised by the OrcaFix skill

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants