Skip to content

feat(onboarding): add a personalize onboarding section#2781

Open
jul-dan wants to merge 22 commits into
stagingfrom
feat/onboarding-section
Open

feat(onboarding): add a personalize onboarding section#2781
jul-dan wants to merge 22 commits into
stagingfrom
feat/onboarding-section

Conversation

@jul-dan

@jul-dan jul-dan commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Summary

JIRA ticket: QOV-2052

Adds a Getting Started onboarding checklist on the organization overview page, guiding new users through their first deployment on Qovery.

What's new

Onboarding checklist (SectionOnboarding) displayed at the top of the org overview with:

  • 4 required steps: workspace setup (auto-done), cluster deploy, environment creation, first service deploy
  • 2 optional steps based on selected use cases: preview environments (ephemeral-environments) and AI Builder Portal (rde)
  • Progress bar (% completed)
  • Contextual CTAs per step with live status (deploying / queued / failed / stopped)
  • MCP skills suggestion card visible until all steps are done
  • "You're all set!" completion screen with links relevant to the user's use cases

API integration

  • New GET/POST /organization/{organizationId}/onboarding endpoints consumed via qovery-typescript-axios@1.1.919
  • Dismiss (DISMISSED) and complete (COMPLETED) persisted server-side + localStorage

Key behaviors

  • Hidden for existing orgs (no use_cases set)
  • Cluster step: only marked done when status === DEPLOYED && is_deployed (avoids false positive on unavailable clusters)
  • Service step: only marked do
  • Deployment failure links to onId), not service logs
  • Stopped service shows a dedicated "Service stopped" link

Screenshots / Recordings

https://www.loom.com/share/72fa2c62139040649152b8036edf9e65

Testing

  • Changes tested locally in the relevant Console's pages and Storybooks
  • yarn test or yarn test -u (if you need to regenerate snapshots)
  • yarn format
  • yarn lint

PR Checklist

  • I followed naming, styling, and TypeScript rules (see .cursor/rules)
  • I performed a self-review (diff inspected, dead code removed)
  • I titled the PR using Conventional Commits with a scope when possible (e.g. feat(service): add new Terraform service) - required for semantic-release
  • I only kept necessary comments, written in English (watch for useless AI comments)
  • I involved a designer to validate UI changes if I am not a designer
  • I covered new business logic with tests (unit)
  • I confirmed CI is green (Codecov red can be accepted)
  • I reviewed and executed locally any AI-assisted code

jul-dan and others added 14 commits June 24, 2026 17:23
- Add SectionOnboarding component with 4-step checklist (workspace, cluster, environment, service)
- Fetch onboarding status from new GET /organization/{id}/onboarding endpoint
- Persist dismiss via POST /organization/{id}/onboarding with status DISMISSED
- Hide section for existing orgs (null status) and invited members
- Show animated deploying/failed states with cluster and service log links
- Add McpSuggestionCard when no cluster exists
- Add dev-only reset button to clear dismissed state
- Simplify section-production-health (cluster creation moved to onboarding)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ent_status for service step

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Cluster: require both status===DEPLOYED and is_deployed to avoid
  showing as done when cluster is unavailable (stale status field)
- Service: use state===DEPLOYED for running check; add isServiceStopped
  visual state showing "Service stopped" link when no service is running
- Remove unused ServiceDeploymentStatusEnum import

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Old orgs have no onboarding record or use_cases=null — only show the
section when use_cases is set (new orgs that went through the wizard).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Preview environments link only if ephemeral-environments was selected,
AI Builder Portal only if rde was selected. Invite teammates always shown.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@jul-dan

jul-dan commented Jun 29, 2026

Copy link
Copy Markdown
Contributor Author

@copilot resolve the merge conflicts in this pull request

…ction

# Conflicts:
#	package.json
#	yarn.lock

Copilot AI commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

@copilot resolve the merge conflicts in this pull request

Merge conflicts resolved in commit 91ff1e6. The only conflict was qovery-typescript-axios version in package.json and yarn.lock — kept our branch's version (1.1.919) over staging's (1.1.913).

@jul-dan jul-dan changed the title Feat/onboarding section feat(onboarding): add a personalize onboarding section Jun 29, 2026
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@jul-dan jul-dan marked this pull request as ready for review June 29, 2026 12:22
…ons moved to onboarding

Cluster option cards (Qovery managed, BYOC, Local machine) and MCP skills
card were moved to SectionOnboarding. Tests now reflect the simplified
EmptyState with a single "Create cluster" CTA.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@codecov

codecov Bot commented Jun 29, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 64.28571% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 46.77%. Comparing base (640bcb7) to head (0e25618).
⚠️ Report is 3 commits behind head on staging.

Files with missing lines Patch % Lines
...vironment-modal/create-clone-environment-modal.tsx 33.33% 2 Missing and 2 partials ⚠️
libs/shared/auth/src/lib/use-auth/use-auth.tsx 50.00% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           staging    #2781      +/-   ##
===========================================
- Coverage    47.44%   46.77%   -0.67%     
===========================================
  Files         1267     1248      -19     
  Lines        26812    26687     -125     
  Branches      7913     7788     -125     
===========================================
- Hits         12721    12483     -238     
- Misses       11892    12052     +160     
+ Partials      2199     2152      -47     
Flag Coverage Δ
unittests 46.77% <64.28%> (-0.67%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copilot AI 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.

Pull request overview

Adds a “Getting started” onboarding checklist to the organization overview page, backed by new organization onboarding API endpoints, to guide new users through initial setup and first deployment.

Changes:

  • Bump qovery-typescript-axios to consume the new organization onboarding endpoints.
  • Add organization onboarding query/mutation (and unit tests) and a new SectionOnboarding UI rendered on the org overview page.
  • Simplify the org overview “Production health” empty state and add an onSuccess escape hatch to the clone/create environment modal.

Reviewed changes

Copilot reviewed 13 out of 14 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
yarn.lock Locks qovery-typescript-axios to 1.1.919.
package.json Bumps qovery-typescript-axios to 1.1.919.
libs/shared/auth/src/lib/use-auth/use-auth.tsx Clears React Query cache on logout.
libs/domains/organizations/data-access/src/lib/domains-organizations-data-access.ts Adds onboarding query key + update mutation calling new endpoints.
libs/domains/organizations/data-access/src/lib/domains-organizations-data-access.spec.ts Adds unit tests for onboarding query and update mutation.
libs/domains/environments/feature/src/lib/create-clone-environment-modal/create-clone-environment-modal.tsx Adds optional onSuccess(environmentId) callback to override default navigation.
libs/domains/clusters/feature/src/lib/section-production-health/section-production-health.tsx Removes the previous “cluster options” onboarding-like UI, leaving a simpler empty state CTA.
libs/domains/clusters/feature/src/lib/section-production-health/section-production-health.spec.tsx Updates tests to match the simplified empty state behavior.
apps/console/src/routes/_authenticated/organization/$organizationId/overview.tsx Renders the new onboarding section above production health.
apps/console/src/app/components/section-onboarding/use-update-user-signup.ts Introduces a user signup mutation hook (currently unused).
apps/console/src/app/components/section-onboarding/use-rde-access.ts Introduces an RDE access query hook (currently unused).
apps/console/src/app/components/section-onboarding/use-organization-onboarding.ts Adds onboarding query + update-status mutation hooks.
apps/console/src/app/components/section-onboarding/section-onboarding.tsx Implements the onboarding checklist UI, progress calculation, and completion modal flow.
apps/console/src/app/components/header/user-menu/user-menu.tsx Changes displayed email to userToken?.email only (drops communication_email fallback).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apps/console/src/app/components/section-onboarding/section-onboarding.tsx Outdated
Comment thread apps/console/src/app/components/header/user-menu/user-menu.tsx
Comment on lines +33 to +97
const COMPLETION_ILLUSTRATION_ROW_TONES = [
'366333336963333366366333336963333366366333336963333366',
'369633333663366333336963333366336633333696333336633663333',
'366336633333696333366336633333696333366336633333696333',
'333336963333366336633333696333336633663333369633333663366',
'333336633663333369333336633663333369333336633663333369',
'336633333636333336633663333363633333663366333336363333366',
'366333336963333366336633333696333336633663333369633333663',
'696333336633663333696333336633663333696333336633663333',
'366336633333696333333663366333336963333336633663333369633333',
'333369633333663366333336963333366336633333696333336633663',
'333336633663333369633333366336633333696333333663366333336963',
'366333336963333366366333336963333366366333336963333366',
'369633333663366333336963333366336633333696333336633663333',
'366336633333696333366336633333696333366336633333696333',
'333336963333366336633333696333336633663333369633333663366',
'333336633663333369333336633663333369333336633663333369',
'336633333636333336633663333363633333663366333336363333366',
] as const

const COMPLETION_ILLUSTRATION_HEX_FILL = {
3: 'var(--positive-3)',
6: 'var(--positive-6)',
9: 'var(--positive-9)',
} as const

type CompletionIllustrationHexTone = keyof typeof COMPLETION_ILLUSTRATION_HEX_FILL

const COMPLETION_ILLUSTRATION_HEX_GAP = 10.5
const COMPLETION_ILLUSTRATION_HEX_PATH = 'M0 0L3.89711 2.25V6.75L0 9L-3.89711 6.75V2.25L0 0Z'
const COMPLETION_ILLUSTRATION_HEX_COLUMN_COUNT = 50
const COMPLETION_ILLUSTRATION_HEX_HALF_WIDTH = 3.89711
const COMPLETION_ILLUSTRATION_HEX_HEIGHT = 9
const COMPLETION_ILLUSTRATION_ROW_START_Y = -5
const COMPLETION_ILLUSTRATION_ROW_GAP = 9
const COMPLETION_ILLUSTRATION_ROW_OFFSET = {
even: -13.25,
odd: -8,
} as const

const COMPLETION_ILLUSTRATION_PATTERN_MIN_X = Math.floor(
Math.min(COMPLETION_ILLUSTRATION_ROW_OFFSET.even, COMPLETION_ILLUSTRATION_ROW_OFFSET.odd) -
COMPLETION_ILLUSTRATION_HEX_HALF_WIDTH
)
const COMPLETION_ILLUSTRATION_PATTERN_MAX_X = Math.ceil(
Math.max(COMPLETION_ILLUSTRATION_ROW_OFFSET.even, COMPLETION_ILLUSTRATION_ROW_OFFSET.odd) +
(COMPLETION_ILLUSTRATION_HEX_COLUMN_COUNT - 1) * COMPLETION_ILLUSTRATION_HEX_GAP +
COMPLETION_ILLUSTRATION_HEX_HALF_WIDTH
)
const COMPLETION_ILLUSTRATION_PATTERN_MAX_Y =
COMPLETION_ILLUSTRATION_ROW_START_Y +
(COMPLETION_ILLUSTRATION_ROW_TONES.length - 1) * COMPLETION_ILLUSTRATION_ROW_GAP +
COMPLETION_ILLUSTRATION_HEX_HEIGHT
const COMPLETION_ILLUSTRATION_PATTERN_BOUNDS = {
x: COMPLETION_ILLUSTRATION_PATTERN_MIN_X,
y: COMPLETION_ILLUSTRATION_ROW_START_Y,
width: COMPLETION_ILLUSTRATION_PATTERN_MAX_X - COMPLETION_ILLUSTRATION_PATTERN_MIN_X,
height: COMPLETION_ILLUSTRATION_PATTERN_MAX_Y - COMPLETION_ILLUSTRATION_ROW_START_Y,
} as const

const COMPLETION_ILLUSTRATION_ROWS = COMPLETION_ILLUSTRATION_ROW_TONES.map((tones, index) => ({
x: index % 2 === 0 ? COMPLETION_ILLUSTRATION_ROW_OFFSET.even : COMPLETION_ILLUSTRATION_ROW_OFFSET.odd,
y: COMPLETION_ILLUSTRATION_ROW_START_Y + index * COMPLETION_ILLUSTRATION_ROW_GAP,
tones,
}))

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.

What is all that?

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.

cc @TheoGrandin74 this one is for you

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.

Oops this one is on my it's for the final illustration 😁
Will try to put it in a svg 👍

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.

@rmnbrd I've put the illustration in a specific file, it's a pattern which requires the design token to work in light and dark so I did it this way. Other option would be to duplicate the asset for dark/light and call it as an image in background, you tell me if you prefer that I do it this way!

Comment thread apps/console/src/app/components/section-onboarding/section-onboarding.tsx Outdated
* Authentification logout
*/
const authLogout = useCallback(async () => {
queryClient.clear()

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.

Why do we need that?

TheoGrandin74 and others added 2 commits July 3, 2026 11:15
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
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.

5 participants