Skip to content

fix(onboarding): don't seed a demo flag into a project that has flags - #8217

Open
talissoncosta wants to merge 3 commits into
mainfrom
fix/onboarding-skip-flag-creation-existing-project
Open

fix(onboarding): don't seed a demo flag into a project that has flags#8217
talissoncosta wants to merge 3 commits into
mainfrom
fix/onboarding-skip-flag-creation-existing-project

Conversation

@talissoncosta

@talissoncosta talissoncosta commented Aug 4, 2026

Copy link
Copy Markdown
Contributor
  • I have read the Contributing Guide.
  • I have added information to docs/ if required so people know about the feature.
  • I have filled in the "Changes" section below.
  • I have filled in the "How did you test this code" section below.

Changes

Visiting /getting-started created show_demo_button in whichever project came back first, whether or not the customer had onboarded. Features are project-level, so it appeared in every environment of that project including production, next to a new Onboarding tag. The nav link is shown to everyone, so any customer could trigger it.

  • Seed only into a project with no flags. A project that already ran the tour still reuses its flag, matched by tag first, since renaming a flag deletes and recreates it.
  • The rule moved to onboardingFlag.ts as two pure functions with tests. It was inline in an async orchestrator that nothing could test.
  • With no flag to teach with, the page shows an "already set up" state linking to the project's own flags, and renders no header, since the header offers inline renames of the org and project.

The helpers are named after onboarding rather than "demo", because the lookup matches on the Onboarding tag, and because this flag lands in a real project rather than a throwaway one. The flag's own name stays show_demo_button, which the tour's snippet references.

Copy of the already-set-up state is provisional, and still calls it a demo flag.

Still open: creation happens on page load rather than on an explicit action, and there's no persisted "has onboarded" state (isGettingStarted is set at register, in memory, lost on refresh).

How did you test this code?

  • 7 unit tests on the seeding rule, checked by mutation: forcing shouldSeedOnboardingFlag to true fails the suite

  • test:unit (395) and lint clean, and no typecheck errors in the touched files

  • New account: seeds the flag, tags it, tour works end to end

  • Project with flags: nothing created, no Onboarding tag, already-set-up state shown

  • Project that already has the onboarding flag: reused, not duplicated

  • Empty project on an established account: still seeded

@vercel

vercel Bot commented Aug 4, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
flagsmith-frontend-preview Ready Ready Preview Aug 6, 2026 6:52pm
flagsmith-frontend-staging Ready Ready Preview Aug 6, 2026 6:52pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Ignored Ignored Preview Aug 6, 2026 6:52pm

Request Review

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

No new commits to review since the last review.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 170279c0-c2e3-4856-9d80-f2045ab15011

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The change adds shared onboarding-flag constants, lookup logic, and seeding rules. Bootstrap reuses existing flags, creates flags only for empty projects, and reports whether an onboarding flag exists. The resource hook exposes this state to OnboardingFlow. The flow renders an already-set-up screen with project navigation when no onboarding flag exists. A Promise-based organisation helper now wraps AccountStore events with timeout and cleanup handling. Tests cover onboarding-flag lookup and seeding.

Estimated code review effort: 3 (Moderate) | ~25 minutes


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 687db188-e702-4cea-8a87-bdf2abececc2

📥 Commits

Reviewing files that changed from the base of the PR and between fb78687 and 3f8c70c.

📒 Files selected for processing (7)
  • frontend/web/components/pages/onboarding/OnboardingFlow/OnboardingFlow.tsx
  • frontend/web/components/pages/onboarding/hooks/__tests__/demoFlag.test.ts
  • frontend/web/components/pages/onboarding/hooks/bootstrapOnboarding.ts
  • frontend/web/components/pages/onboarding/hooks/demoFlag.ts
  • frontend/web/components/pages/onboarding/hooks/useEnsureOnboardingResources.ts
  • frontend/web/components/pages/onboarding/onboarding-already-set-up/OnboardingAlreadySetUp.tsx
  • frontend/web/components/pages/onboarding/onboarding-already-set-up/index.ts

Comment thread frontend/web/components/pages/onboarding/bootstrap/__tests__/demoFlag.test.ts Outdated
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f2bc4afd-cc1d-4693-947a-0bd91c472a61

📥 Commits

Reviewing files that changed from the base of the PR and between 3a496c3 and 1b1d836.

📒 Files selected for processing (5)
  • frontend/web/components/pages/onboarding/OnboardingFlow/OnboardingFlow.tsx
  • frontend/web/components/pages/onboarding/hooks/__tests__/demoFlag.test.ts
  • frontend/web/components/pages/onboarding/hooks/bootstrapOnboarding.ts
  • frontend/web/components/pages/onboarding/hooks/demoFlag.ts
  • frontend/web/components/pages/onboarding/hooks/useEnsureOnboardingResources.ts

Comment thread frontend/web/components/pages/onboarding/bootstrap/bootstrapOnboarding.ts Outdated
@github-actions github-actions Bot added the fix label Aug 5, 2026
talissoncosta and others added 2 commits August 5, 2026 22:36
Visiting /getting-started created show_demo_button in whichever project came
back first, whether or not the customer had ever onboarded. Features are
project-level, so it appeared in every environment of that project, including
production, alongside a new Onboarding tag. The Getting Started nav link is
ungated, so any customer could trigger this by clicking it.

ensureFlag already computed isFirstFeature for analytics; it now also decides
whether to create anything. An empty project still gets the demo flag, an
established one gets nothing.

That leaves the tour with no flag to teach with, so the page says so and points
at the project's own flags instead of walking someone through connecting a
project that is already connected.

Copy and treatment of that state are provisional.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
bootstrapOnboarding and createOrganisationViaAccountStore are plain
functions, so hooks/ described three of its nine files wrongly. Both
belong to the provisioning that runs before the tour, which is what the
new bootstrap/ folder holds.

Paths and one comment only; no logic changes.
@talissoncosta
talissoncosta force-pushed the fix/onboarding-skip-flag-creation-existing-project branch from 44b9d75 to 8c41def Compare August 6, 2026 01:53
@github-actions github-actions Bot added fix and removed fix labels Aug 6, 2026
@talissoncosta
talissoncosta marked this pull request as ready for review August 6, 2026 18:46
@talissoncosta
talissoncosta requested a review from a team as a code owner August 6, 2026 18:46
@talissoncosta
talissoncosta requested review from kyle-ssg and removed request for a team August 6, 2026 18:46
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 4bbc3d97-5922-410b-b554-ee151a4fab97

📥 Commits

Reviewing files that changed from the base of the PR and between 3a496c3 and 8c41def.

📒 Files selected for processing (6)
  • frontend/web/components/pages/onboarding/OnboardingFlow/OnboardingFlow.tsx
  • frontend/web/components/pages/onboarding/bootstrap/__tests__/demoFlag.test.ts
  • frontend/web/components/pages/onboarding/bootstrap/bootstrapOnboarding.ts
  • frontend/web/components/pages/onboarding/bootstrap/createOrganisationViaAccountStore.ts
  • frontend/web/components/pages/onboarding/bootstrap/demoFlag.ts
  • frontend/web/components/pages/onboarding/hooks/useEnsureOnboardingResources.ts

@coderabbitai coderabbitai Bot 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.

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 4bbc3d97-5922-410b-b554-ee151a4fab97

📥 Commits

Reviewing files that changed from the base of the PR and between 3a496c3 and 8c41def.

📒 Files selected for processing (6)
  • frontend/web/components/pages/onboarding/OnboardingFlow/OnboardingFlow.tsx
  • frontend/web/components/pages/onboarding/bootstrap/__tests__/demoFlag.test.ts
  • frontend/web/components/pages/onboarding/bootstrap/bootstrapOnboarding.ts
  • frontend/web/components/pages/onboarding/bootstrap/createOrganisationViaAccountStore.ts
  • frontend/web/components/pages/onboarding/bootstrap/demoFlag.ts
  • frontend/web/components/pages/onboarding/hooks/useEnsureOnboardingResources.ts
🛑 Comments failed to post (1)
frontend/web/components/pages/onboarding/bootstrap/createOrganisationViaAccountStore.ts (1)

15-40: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

store_file="$(fd -t f 'account-store\.(ts|tsx|js|jsx)$' frontend | head -n 1)"
test -n "$store_file"

echo "== AccountStore event declarations and emissions =="
rg -n -C 5 "['\"](saved|problem)['\"]|\.emit\(|\.trigger\(" "$store_file"

echo "== AccountStore consumers and emitters =="
rg -n -C 4 "AccountStore\.(on|off|emit|trigger)\(['\"](saved|problem)['\"]" frontend

Repository: Flagsmith/flagsmith

Length of output: 3897


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== candidate files =="
fd -t f 'account-store\.(ts|tsx|js|jsx)$|app-actions\.(ts|tsx|js|jsx)$|accountActions\.(ts|tsx|js|jsx)$|actions' frontend | head -n 50

echo "== AccountStore source outline and relevant sections =="
store_file="$(fd -t f 'account-store\.(ts|tsx|js|jsx)$' frontend | head -n 1)"
test -n "$store_file"
wc -l "$store_file"
sed -n '1,220p' "$store_file" | cat -n
sed -n '350,430p' "$store_file" | cat -n

echo "== createOrganisation references =="
rg -n -C 6 "createOrganisation|savedId|Problem|problem|saving|API\.|fetch\(|request" frontend -g '*.ts' -g '*.tsx' -g '*.js' -g '*.jsx'

Repository: Flagsmith/flagsmith

Length of output: 50376


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== AccountStore files =="
fd -t f 'account-store\.(ts|tsx|js|jsx)$' frontend

echo "== createOrganisation event consumers =="
rg -n -C 8 "createOrganisation|saved|savedId|problem|AccountStore\.on\(['\"](saved|problem)" frontend/web/components/pages/frontend/web/components/pages/onboarding/bootstrap frontend/web/components/pages/CreateOrganisationPage.tsx frontend/web/components/pages/onboarding/bootstrap/createOrganisationViaAccountStore.ts 2>/dev/null || true

api_file="$(fd -t f 'API\.(ts|js)$' frontend/common frontend | head -n 1)"
if [ -n "$api_file" ]; then
  echo "== API file: $api_file =="
  wc -l "$api_file"
  sed -n '1,240p' "$api_file" | cat -n
fi

echo "== AppActions likely files =="
fd -t f '.*actions.*\.(ts|js)$' frontend | rg -i 'app|action' | head -n 50

Repository: Flagsmith/flagsmith

Length of output: 9869


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== account-store.js outline/sections =="
wc -l frontend/common/stores/account-store.js
sed -n '1,220p' frontend/common/stores/account-store.js | cat -n
sed -n '220,360p' frontend/common/stores/account-store.js | cat -n

echo "== app-actions.js and related sections =="
for f in frontend/common/dispatcher/app-actions.js frontend/common/dispatcher/base/_app-actions.js; do
  [ -f "$f" ] || continue
  echo "--- $f ($(wc -l < "$f") lines) ---"
  rg -n -C 10 "createOrganisation|fetch|API|isSaving|savedId|trigger|emit|saved|problem" "$f"
done

echo "== precise AccountStore saved/problem references =="
rg -n -C 4 "savedId|'saved'|\"saved\"|'problem'|\"problem\"|trigger\(['\"](saved|problem)" frontend/common/stores/account-store.js frontend/common/dispatcher/app-actions.js frontend/common/dispatcher/base/_app-actions.js frontend 2>/dev/null | head -n 220

Repository: Flagsmith/flagsmith

Length of output: 14785


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== dispatchers =="
fd -t f 'dispatcher\.(js|ts)$|_dispatcher\.(js|ts)$' frontend/common/dispatcher frontend
for f in frontend/common/dispatcher/dispatcher.js frontend/common/dispatcher/base/_dispatcher.js frontend/common/dispatcher/app-actions.js frontend/common/dispatcher/base/_app-actions.js frontend/common/dispatcher/account-actions.js frontend/common/dispatcher/base/account-actions.js frontend/common/stores/account-store.js; do
  [ -f "$f" ] || continue
  echo "--- $f ($(wc -l < "$f") lines) ---"
  rg -n -C 8 "CREATE_ORGANISATION|CREATE.*ORG|saved|problem|save|trigger|isSaving|error" "$f" || true
done

echo "== store helper methods around saved/problem =="
rg -n -C 6 "saved\(|problem\(|issue\(|changing\(|savedId|isSaving|trigger\(" frontend/common/stores/account-store.js frontend/common/stores/base/_store.js frontend/common/dispatcher/account-actions.js | head -n 240

echo "== all AccountStore saved/event consumers by file =="
rg -n "AccountStore\.(on|off)\(['\"](saved|problem|change)" frontend/web -g '*.tsx' -g '*.ts' <(printf "frontend/web/components/pages/CreateOrganisationPage.tsx\nfrontend/web/components/pages/onboarding/bootstrap/createOrganisationViaAccountStore.ts\n")

Repository: Flagsmith/flagsmith

Length of output: 23457


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== _store.js full contents =="
cat -n frontend/common/stores/base/_store.js

echo "== dispatcher and store event binding sections =="
cat -n frontend/common/dispatcher/dispatcher.js | sed -n '1,80p'
rg -n -C 5 "_emit|DEFAULT_SAVED_EVENT|DEFAULT_ERROR_EVENT|registerWith|saved|problem\(|error" frontend/common/stores/account-store.js frontend/common/stores/base/_store.js frontend/common/dispatcher/dispatcher.js

echo "== precise consumers =="
python3 - <<'PY'
from pathlib import Path
import re
paths=[Path("frontend/web/components/pages/CreateOrganisationPage.tsx"),Path("frontend/web/components/pages/onboarding/bootstrap/createOrganisationViaAccountStore.ts")]
for p in paths:
    print(f"\n--- {p} ---")
    text=p.read_text()
    for i,line in enumerate(text.splitlines(),1):
        if re.search(r"AccountStore\.(on|off)\(['\"](saved|problem|change)", line):
            print(f"{i}: {line.strip()}")
PY

Repository: Flagsmith/flagsmith

Length of output: 14284


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== account store registration =="
rg -n -C 8 "AccountStore|registerWith|emit|trigger|saved\(|problem\(|goneABitWest" frontend/common/stores/account-store.js | sed -n '1,180p'

echo "== account store exports and event constants =="
sed -n '560,620p' frontend/common/stores/account-store.js | cat -n
rg -n -C 3 "DEFAULT_SAVED_EVENT|DEFAULT_ERROR_EVENT|constants|Actions\." frontend/common/stores/account-store.js frontend/common/dispatcher baseline 2>/dev/null || true

Repository: Flagsmith/flagsmith

Length of output: 33828


Use a request-scoped AccountStore completion callback.

This helper waits on the generic saved and problem events, but AccountStore emits the same events from other operations such as 2FA and password reset. Pass a callback from createOrganisationViaAccountStore into AppActions.createOrganisation so only the organisation creation result resolves/rejects the flow.

The flag is found by its Onboarding tag, falling back to the name only
because renaming a flag is a delete and recreate, so "onboarding flag"
is what the lookup actually means.

"Demo" also read as throwaway, which is the opposite of the problem
being fixed here: this flag lands in a real project and shows up in
every environment, production included.

The flag's own name stays show_demo_button, since the tour's snippet
references it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
⚠️ Action not completed

Already reviewed.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fix front-end Issue related to the React Front End Dashboard

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant