fix(LLMO-4176): skip brandalf check when onboardingMode is v1 in llmo-customer-analysis#2380
Merged
irenelagno merged 4 commits intomainfrom Apr 15, 2026
Merged
Conversation
…-customer-analysis For mixed-state orgs (brandalf=true flag but pre-Brandalf sites forcing v1 onboarding), the llmo-customer-analysis handler was checking isBrandalfEnabled and finding no v2 brand (none created in v1 path), then calling DRS without brand_id. DRS rejects this with 422 for brandalf-enabled orgs. Fix: short-circuit isBrandalfEnabled when auditContext.onboardingMode === 'v1' so the BP schedule is created without brand_id, matching v1 DRS expectations. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Contributor
Author
Related PRsapi-service safeguard (pairs with this fix): Why both PRs are needed
Without the api-service fix, mixed-state orgs would be onboarded as v2 (wrong). Without this fix, those orgs would fail brand-presence schedule creation with DRS 422. |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
|
This PR will trigger a patch release when merged. |
When resolving which brand to use for the brand presence schedule, prefer the brand whose baseSiteId (site_id column) matches the site over a brand_sites join match. The onboarding-created brand has the correct base URL, but Brandalf-created sub-brands may have sub-path URLs that fail DRS URL validation (422). Falls back to brand_sites match for backward compatibility with brands created before baseSiteId was set during onboarding. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
aniham
approved these changes
Apr 15, 2026
irenelagno
added a commit
to adobe/spacecat-api-service
that referenced
this pull request
Apr 15, 2026
…boarding mode resolution (#2171) ## Summary Implements [LLMO-4176](https://jira.corp.adobe.com/browse/LLMO-4176) (epic [LLMO-4054](https://jira.corp.adobe.com/browse/LLMO-4054)). Rewrites `resolveLlmoOnboardingMode` to follow an 8-row decision matrix based on 3 inputs: | # | Default version | Pre-cutoff sites | Brandalf flag | Onboarding version | Side effects | |---|---|---|---|---|---| | 1 | v1 | yes | yes | v1 | Reverts brandalf to false + logs warning | | 2 | v1 | yes | no | v1 | — | | 3 | v1 | no | yes | v2 | — | | 4 | v1 | no | no | v1 | — | | 5 | v2 | yes | yes | v2 | — | | 6 | v2 | yes | no | v1 | — | | 7 | v2 | no | yes | v2 | — | | 8 | v2 | no | no | v2 | Sets brandalf to true | **Priority order:** Brandalf flag (highest) → kill switch → legacy site check → default v2. **Temporary safeguard** — will be removed once all v1 customers are migrated to v2. ## Related PRs > **⚠️ Both PRs must be merged and deployed together.** | PR | Repo | What | |---|---|---| | **This PR (#2171)** | spacecat-api-service | Decision matrix + DRS baseUrl fix | | [adobe/spacecat-audit-worker#2380](adobe/spacecat-audit-worker#2380) | spacecat-audit-worker | Fixes brand resolution to prefer `baseSiteId` over `brand_sites` join | ### What changed **`src/support/llmo-onboarding-mode.js`** — Rewrites `resolveLlmoOnboardingMode` with 4-step logic: 1. Read brandalf flag — if `true`: check for Row 1 condition (kill switch + pre-cutoff → revert flag to false, return v1), otherwise return v2 2. If brandalf false/missing + kill switch `LLMO_ONBOARDING_DEFAULT_VERSION=v1` → v1 3. Legacy check: org has pre-cutoff sites → v1 4. Default → v2 New exports (all TEMPORARY): - `LLMO_BRANDALF_GA_CUTOFF_MS_DEFAULT` — epoch-ms constant (`2026-04-01T00:00:00Z`) - `resolveBrandalfCutoffMs(context)` — reads cutoff from `LLMO_BRANDALF_GA_CUTOFF_MS` env var - `hasPreBrandalfSites(organizationId, context)` — returns `true` if org has any site created before cutoff **`src/controllers/llmo/llmo-onboarding.js`** — Fixes DRS baseUrl bug (NASCAR issue): passes `overrideBaseURL` to DRS prompt generation job when available. ### Files changed | File | What | |---|---| | `src/support/llmo-onboarding-mode.js` | Decision matrix logic + Row 1 revert | | `src/controllers/llmo/llmo-onboarding.js` | DRS baseUrl fix (`overrideBaseURL`) | | `src/support/customer-config-mapper.js` | Minor fix | | `test/support/llmo-onboarding-mode.test.js` | Rewritten unit tests (45 cases covering all 8 matrix rows) | | `test/controllers/llmo/llmo-onboarding.test.js` | Updated mocks for new logic | | `test/support/slack/actions/onboard-llmo-modal.test.js` | Updated mocks | | `test/it/shared/tests/llmo-onboarding.js` | IT tests for `hasPreBrandalfSites` + `resolveLlmoOnboardingMode` | | `test/it/postgres/llmo-onboarding.test.js` | Wire PostgREST client into IT tests | | `test/it/postgres/seed-data/organizations.js` | Add legacy + new LLMO test orgs | | `test/it/postgres/seed-data/sites.js` | Add sites with explicit `created_at` | | `test/it/shared/seed-ids.js` | Add IDs for new test orgs/sites | | `docs/llmo-brandalf-apis/v1-v2-onboarding-consistency-safeguard.md` | Design doc with decision matrix | ## Test plan ### Unit tests (automated — run in CI) ```bash npx mocha test/support/llmo-onboarding-mode.test.js # 45 tests — all 8 matrix rows, edge cases, error handling npx mocha test/controllers/llmo/llmo-onboarding.test.js # 79 tests — full performLlmoOnboarding suite ``` ### Integration tests (automated — require Docker) ```bash npx mocha --require test/it/postgres/harness.js --timeout 30000 \ test/it/postgres/llmo-onboarding.test.js ``` Covers: - `hasPreBrandalfSites` → `true` for org with pre-cutoff site - `hasPreBrandalfSites` → `false` for org with post-cutoff site - `hasPreBrandalfSites` → `false` for org with no sites - `resolveLlmoOnboardingMode` → `v1` for legacy org - `resolveLlmoOnboardingMode` → `v2` for new org - `resolveLlmoOnboardingMode` → `v1` when kill switch active ### E2E validation (manual — completed on dev) Validated on dev environment (`spacecat.experiencecloud.live/api/ci`) with two test orgs. Results documented in `docs/llmo-brandalf-apis/e2e-test-results.md`. | Test | Row | Result | |------|-----|--------| | Row 7: default=v2, no pre-cutoff, brandalf=true → v2 | PASS | | Row 8: default=v2, no pre-cutoff, no brandalf → v2 + sets flag | PASS | | Row 5: default=v2, pre-cutoff, brandalf=true → v2 | PASS | | Row 6: default=v2, pre-cutoff, no brandalf → v1 | PASS | 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
solaris007
pushed a commit
that referenced
this pull request
Apr 15, 2026
## [1.415.1](v1.415.0...v1.415.1) (2026-04-15) ### Bug Fixes * **LLMO-4176:** skip brandalf check when onboardingMode is v1 in llmo-customer-analysis ([#2380](#2380)) ([86e396a](86e396a))
Member
|
🎉 This PR is included in version 1.415.1 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
brandalf=truefeature flag but pre-Brandalf sites that force v1 onboarding viahasPreBrandalfSites), thellmo-customer-analysishandler was callingisBrandalfEnabledindependently of the actual onboarding path. It found no v2 customer config brand (none created during v1 onboarding) and called DRS withoutbrand_id. DRS rejects this with422 - brand_id is required for v2 (brandalf-enabled) sites.isBrandalfEnabledwhenauditContext.onboardingMode === 'v1'. TheonboardingModeis set byspacecat-api-servicebased onresolveLlmoOnboardingModeand propagated throughdrs-prompt-generation→llmo-customer-analysis. When it's explicitly'v1', we skip v2 brand resolution and create the BP schedule withoutbrand_id.brand_id/spacecat_org_id.Behaviour
'v2'brand_idin schedule'v1'(explicit)brand_idisBrandalfEnabled(backward compat)brand_idRelated
Test plan
npm test)4483e763-a918-431d-8b7a-ec8d4f3bf9d9) — confirm brand-presence schedule created successfully in CloudWatch logs🤖 Generated with Claude Code