# Onboarding and account settings

URL: https://ship-and-scale.vercel.app/docs/core/onboarding-settings

Customize the survey and account controls without changing workspace creation or deletion protections.

## Account onboarding [#account-onboarding]

After confirmed authentication, users see three skippable steps: preferred name, intended use and initial interests. The answers belong to the account, not the selected workspace. Back and Continue save visible answers and the destination step; Get started records completion. Skip for now saves partial answers and permanently records the skip.

Unsaved text is not automatically persisted. A reload resumes the last saved step. Completed or skipped accounts do not repeat onboarding, even after workspace changes. A failed save keeps the form visible with retry feedback. The survey does not create workspaces, rename profiles, send invitations or perform the selected activities.

## Change labels without changing stored values [#change-labels-without-changing-stored-values]

Options and validation live in `lib/onboarding.ts`; UI copy/layout lives in `components/onboarding/onboarding-form.tsx`. To rename the visible Work choice while preserving existing answers, change its label only:

```ts
{ value: 'work', label: 'My business' }
```

The saved `use_case` still equals `work`, so no data migration is needed for that label edit. Check the question, selected state, summary and narrow-screen layout. Keep other entries in the existing array; this is a one-entry change, not a replacement for the full file.

## Change stored values or steps [#change-stored-values-or-steps]

Adding `agency` as a new stored choice requires coordinated changes: the option array, Zod enum, database validation constraint and any readers of existing answers. Add a new migration with an intentional mapping/backfill policy. Do not edit the already-applied onboarding migration or drop historical values before migrating them.

`public.onboarding` stores `user_id`, `display_name`, `use_case`, `interests`, `current_step`, `status` and timestamps. The update trigger preserves terminal status and timestamps; grants prevent client insertion/deletion, owner reassignment and timestamp rewriting. A stale form must not turn completed onboarding back into in-progress state.

The AI interest is hidden when AI is disabled. Removing the AI module does not require deleting historical survey answers. Those answers are interests, not active provider configuration.

## Install and verify onboarding changes [#install-and-verify-onboarding-changes]

Ordinary kickstart discovers the versioned migration. Existing managed installations can use the scoped installer:

```sh
npm run kickstart:onboarding -- --check
npm run kickstart:onboarding
```

This verifies the configured target and migration ledger and applies onboarding without changing the active Auth/email origin. Read-only checks cannot prove DDL permission. Test Back/Continue, reload, failed-save recovery, skip with unanswered fields and competing finish/skip tabs on an authorized hosted test installation.

## Profile and security settings [#profile-and-security-settings]

`/dashboard/account` contains General, Security, Notifications and Billing. Profile changes update the name and avatar shown in the shell. Email remains read-only; the starter does not implement a completed email-change confirmation workflow.

Password changes require the current password, a different new password of 12–128 characters and matching confirmation. An isolated client checks the current password; the signed-in user client performs the update. Success clears/collapses the form. Recovery is a separate email flow. Social/link users can establish a password through **Set a password by email** before password-confirmed operations.

Personal photos accept JPG, PNG or WebP up to 2 MB, normalize to 256 × 256 WebP and use private Storage. Read [upload and access](/docs/storage/files) before changing validation or cleanup.

## Notification settings [#notification-settings]

Email and in-app notifications default on. Each switch saves independently for the authenticated account; no user ID from the form chooses the recipient. Settings survive reload and workspace switches. A failed save retains the persisted value and offers retry feedback.

Turning off in-app notifications prevents new rows but keeps the current inbox. Welcome and invitation email attempts check email preference; verification/recovery remain available. These preferences do not define a general-purpose marketing subscription platform. [Notifications and feedback](/docs/core/notifications-feedback) covers insertion and audience boundaries.

## Guarded account deletion [#guarded-account-deletion]

Deletion requires current-password verification and typing `DELETE`. The dialog identifies personal workspaces that would be removed. Shared workspace ownership must first be transferred. A pending Checkout or nonterminal subscription for a workspace that would be deleted blocks the operation.

The server removes the avatar through Storage and then invokes Admin Auth deletion for the verified signed-in account. Database triggers coordinate membership/workspace cleanup. Shared/transferred workspaces survive; account-scoped data and created credentials are removed or revoked according to their foreign keys and lifecycle rules.

Storage cleanup can succeed before Auth deletion fails. The account then remains retryable but its photo may already be gone. Do not tell the user “nothing changed” after a partial cleanup. Additional storage buckets need explicit deletion handling before extending this flow.

## Permission and persistence checks [#permission-and-persistence-checks]

Test two users in the same workspace: neither may read or update the other's onboarding or preferences. Test anonymous/unverified access, forged user IDs, profile-path reassignment and a deleted account's stale token. UI tests should cover keyboard tabs, mobile forms and a failed save without losing the user's intended value.

A mocked settings screen is insufficient for deletion, password or persistence acceptance. The manual's build does not establish a successful real Auth deletion or emailed password setup. Preserve existing guards and run the appropriate dedicated hosted/browser checks for your release.