Kulcare Docs
DeveloperConnect

Connect onboarding by role

Audience: support, product, QA and engineers who must know what a user sees in Connect onboarding, what each step saves, and where a user lands when they stop part way.

TL;DR: each role walks its own list of steps. The answers go to one onboarding document on the user, and they save as the user types. Only a few steps also write to a real record. The Facility track and the vendor flow make the practice at Review, and not before. A user who stops part way comes back to their next open step. A user who finished, but skipped steps, gets the dashboard and a "Continue setup" card.

Source: PR #2636 (Connect practice phase 2). Code in frontend/apps/connect/src/onboarding/, frontend/apps/connect/src/pages/onboarding/, frontend/apps/connect/src/components/onboarding/ and frontend/packages/shared-services/src/domains/connect/onboarding.*.ts.

Related: Onboarding and facility setup · Profile completeness

How every flow works

These rules are the same for every role.

Where the answers go

The answers go to one document on the user: user.onboarding_data.step_data.connect. The client reads it with GET /identity/users/:id/onboarding and writes it with POST /identity/users/:id/onboarding. The document is on the user, not on the device. A user who starts on a phone can continue on a laptop.

  • Autosave. A change saves when the field loses focus, or 2 seconds after the last keystroke.
  • Every exit saves first. Continue, Skip for now, Do this later, Back, a jump on the step rail and Change role all save the open step before they leave it.
  • Continue moves only on a saved answer. When the save fails, the step stays open and shows Retry.
  • Offline. A change made offline waits in a queue and goes when the connection comes back.
  • Local draft. A change that did not reach the server stays in browser storage, under a key with the user id. It survives a session that expires part way. Another user on the same browser never sees it.
  • Two tabs. A save from an old tab is refused with "This was changed in another tab". The user must reload. The check is on the client only, so two saves in the same moment can still overwrite each other.

POST replaces the whole document. So the client reads the document, applies the change, and sends the full document back (onboarding.repository.ts).

Step status

Each step has one status: not_started, in_progress, skipped or completed.

  • Continue marks the step completed. Skip for now marks it skipped. Only some steps show Skip for now (see the role tables).
  • A step opens only when every step before it is completed or skipped. A link to a later step opens the user's next open step instead.
  • The user can go back to any earlier step. Continue from an earlier step goes back to where the user was, not through each step again.
  • Do this later saves the step and opens the Connect dashboard. It does not change the status.
  • Back on the first step opens the role picker (/connect/welcome?pick=1). On an "Add a facility" run, it opens the dashboard.

When onboarding is finished

The user's own flow is finished when every one of its steps is completed or skipped. The first save that sees this records onboarding.completed_at, and the date stays. Connect does not read the global user.onboarding_completed flag, because the old shell modal also sets it.

The client sends current_step equal to total_steps only when every step is settled. The server then sets user.onboarding_completed (SaveOnboardingService#check_completion_status).

Steps that also write to a record

Most answers stay in the onboarding document only. These writes go to a real record:

StepRoleWhat it writesWhen
Facility (details)Owner who ticks "I also see patients here"Practitioner record, POST /identity/my/practitionerWhen the owner leaves the step. A failure on Continue keeps the owner on the step.
PracticePractitioner, and an owner who sees patientsBio, PATCH /identity/my/practitioner. Primary specialty and years, POST /connect/specializations (a delete and an add for a change). Registration number and council, POST /identity/my/registrations.When the user leaves the step. Only fields the user changed in this flow go. The step makes the practitioner record first when there is none.
VerifyAll roles that see itDocuments, one multipart POST /identity/my/verificationWhen the user leaves the step. A failed send on Continue keeps the user on the step.
FacilitiesPractitionerAn accepted invite, POST /identity/my/invites/:id/acceptWhen the user presses Accept. A facility the user picks from search is a note only.
Facility (join)StaffAn accepted invite, POST /identity/my/invites/:id/acceptWhen the user presses Accept
ReviewOwner and "Add a facility"Practice or facility, POST /identity/my/facility_setupOn the primary button only
ReviewVendorVendor record (POST /identity/vendors), one offering per row (POST /identity/vendor_packages), intro and category (PATCH /identity/vendors/:id)On the primary button ("Open my dashboard") only
ReviewStaffLanguages, PATCH /identity/my/staffOn the primary button ("Open my dashboard") only. A user with no staff row yet gets a skip, not an error.
Last stepVendor, first finish only"Show in search", POST /connect/professional_profiles/:id/publish or /unpublishAfter Review saves

Review writes run only on the primary button. Not now, Do this later, Back and a rail jump on Review make nothing.

The flow never writes verification status verified. Only a Kulcare admin in the review queue does.

Deploy step: the medical council list

The Practice step and POST /identity/my/registrations read the councils from reference.medical_councils. When that table is empty, the step has no council to offer, and the user cannot save a registration. db:seed does not run outside development and test, so it does not fill the table on a server.

Run this task on staging and on production, once on each new environment and after each deploy that changes backend/lib/data/reference/medical_councils.json:

cd backend && bundle exec rake reference:seed_medical_councils

The task adds the councils that are not in the table and updates the others (Reference::MedicalCouncilSeeder). You can run it again with no risk. It prints the number of councils it made and updated.

Step names

The step rail uses the labels in STEP_META (onboarding/stepContent.ts). The dashboard "Continue with ..." button and the Resume screen use STEP_LABELS (onboarding/stepLabels.ts). Three labels differ:

Step idRail labelButton and Resume label
paymentsGet paidPayments ("Continue with payments")
facility (staff)FacilityYour facility ("Continue with your facility")
facility-detailsFacilityFacility

Sign up and the role picker

Sign-in ends on next when it is a safe path, otherwise on /connect (signInTarget in apps/shell/src/services/identity/postAuth.ts). /connect then opens the next open step of an unfinished user.

The role comes from user.signed_up_as:

signed_up_asOnboarding roleSignup card
practitioner, doctorPractitionerDoctor / consultant
facility, ownerOwnerFacility owner
staff, facility_staffStaffFacility staff / front desk
vendor, lamazeVendorWellness and care provider
anything elsenoneThe user picks a role on Welcome

A user with a known role never sees Welcome (/connect/welcome), unless they press Change role or Back on the first step. A pick saves the role in the onboarding document and marks the first step in_progress. A finished user who opens Welcome goes to the dashboard. Welcome shows "Continue where you left off" only when the user has started.

A Facility owner signup makes no practice. The practice is made at Review.

Steps by role

The number is the step's position for that role. A dash means the role never sees the step. "Must" means the step has no Skip for now.

Step (rail label)IdPractitionerOwnerStaffVendorAdd a facilitySkip
About youabout1111—Must
Facilityfacility-details—2——1Must
Practicepractice23 (if sees patients)———Can skip
Verifyverify34 (if sees patients)32—Can skip
Facilitiesfacilities4————Can skip
Addressfacility-address—5 (not for virtual-only)——2 (not for virtual-only)Can skip
Teamfacility-team—6——3Can skip
Operationsfacility-operations—7——4Can skip
Planplan—8——5Must
Facility (join)facility——2——Can skip
Offeringsclasses———3—Must
Scheduleschedule———4—Can skip
Policiespolicies———5—Can skip
Get paidpayments———6—Can skip
Listinglisting———7—Can skip
Reachreach5——8—Can skip
Your deskdesk——4——Must
Goalsgoals6——9—Must
Reviewreview795106Must

The owner numbers are for a new owner who sees patients and has an in-person facility. Fewer steps show when a step drops out. The order is ROLE_STEPS, and stepsFor removes the conditional steps (onboarding.types.ts).

Practitioner (Doctor / consultant)

#StepRequired to continueWhat it saves
1About youFirst nameOnboarding document only. Name, mobile, photo and languages show from the account and the practitioner record.
2PracticeA council when a registration number is givenBio, primary specialty and years, registration (see the table above). Practitioner type and highest qualification stay in the onboarding document.
3VerifyNothingDocuments go to the review queue when the user leaves the step. Documents already sent show as "Already sent".
4FacilitiesNothingA picked facility is a note only, and nobody gets a message. Pending invites show here and can be accepted.
5ReachNothingOnboarding document only (city, radius, localities, international offer)
6GoalsAt least one goalOnboarding document only. The dashboard reads it.
7ReviewNothingMakes nothing. The button is "Open my dashboard".

At the end, the dashboard opens with the "What just happened" card.

"Show in search" for a practitioner is set on My profile. Practitioner Review does not change it.

Facility owner

#StepShown whenRequired to continueWhat it saves
1About youAlwaysFirst nameOnboarding document only
2FacilityAlwaysFacility name and typeOnboarding document. With "I also see patients here" on, it also makes the owner's practitioner record when the owner leaves the step.
3Practice"I also see patients here" is onA council when a registration number is givenAs for a practitioner
4Verify"I also see patients here" is onNothingAs for a practitioner
5AddressThe type is not virtual-onlyNothingOnboarding document only (address, area, city, PIN code, State)
6TeamAlwaysNothingOnboarding document only. The people get an invite after Review makes the practice.
7OperationsAlwaysNothingOnboarding document only (opening hours, patients per hour, IPD)
8PlanAlwaysOne planOnboarding document only. The step shows the price before anything is made.
9ReviewAlwaysNothing"Create my practice" makes the practice, its first facility, the owner role, the trial on the picked plan and the team invites. "Not now" makes nothing.

"Create my practice" carries an idempotency key, saved before the call goes out. A second press, or a retry after a failure, does not make a second practice. After the call, Connect switches the session into the new facility and opens the dashboard.

A change of facility type after Plan clears the confirmed price, and Plan opens again before Review.

An owner who already owns an active practice (for example, from the CMS) does not walk the Facility steps or Plan. Their flow is About you, then Practice and Verify when they see patients, then Review. They answer "I also see patients" on About you. Their Review makes nothing. They add more facilities from the dashboard. The owned practice is marked on read (withOwnedPractice).

Staff (Facility staff / front desk)

#StepRequired to continueWhat it saves
1About youFirst nameOnboarding document only
2FacilityAn accepted inviteAccept writes the invite. The step ticks by itself when the user already belongs to a facility. The option to join by code shows, but it is disabled. The step can be skipped.
3VerifyNothingA government photo ID is optional and kept on file. Staff are not reviewed.
4Your deskAt least one choiceOnboarding document only. It shapes the dashboard.
5ReviewNothing"Open my dashboard" writes the About languages to the staff work profile. It only adds languages.

A staff member with no staff row yet sees "Your work profile starts at your facility" on My profile.

Vendor (Wellness and care provider)

#StepRequired to continueWhat it saves
1About youFirst name and a category ("What do you offer?")Onboarding document only. The category sets the words on every page ("Sessions", "Visits", "Meal plans"). A category already on the profile must be confirmed with "Keep ".
2VerifyNothingDocuments go to the review queue when the user leaves the step
3OfferingsAt least one complete offeringOnboarding document only. Offerings the vendor already has count, and show read-only.
4ScheduleNothingOnboarding document only. Real availability is on /connect/availability.
5PoliciesNothingOnboarding document only
6Get paidNothingThe step shows the payout account state and links to /connect/payments. It stores only when money is taken and the invoice choice. It stores no bank details.
7ListingNothingOnboarding document only (intro, "Show in search")
8ReachNothingOnboarding document only
9GoalsAt least one goalOnboarding document only
10ReviewNothingMakes the vendor record, one offering per row and the intro (see the table above)

Each Review part checks the server first, so a second press makes nothing twice. A vendor who finished onboarding before Review made the practice can open Review again until the practice exists.

After the first finish, the "Show in search" answer goes to the profile. The listing goes public when the payout account is active, unless "Show in search" is off.

Add a facility (side flow)

"Add a facility" is not a signup. It opens /connect/facility/new from:

  • the "My facilities" tile ("Add a facility") and the practitioner tile "My facility (CMS)" ("Set up a facility") on the dashboard;
  • "Set up your own facility" on the "What just happened" card;
  • the Facilities page (/connect/facilities).

The route has no role check, but it sends a user whose own flow is not finished to that flow first (ownFlowResumeStep). An owner who already owns a practice is the exception.

#StepRequired to continueWhat it saves
1FacilityFacility name and typeOnboarding document only. The step starts blank. The rail says where the facility goes.
2AddressNothingOnboarding document only. Not for a virtual-only facility.
3TeamNothingOnboarding document only
4OperationsNothingOnboarding document only
5PlanOne plan, or the practice's current planFor a new practice, the plan. Under a practice the user already has, the new monthly total, when the user may see billing.
6ReviewNothing"Add my facility" (under a practice the user already has) or "Create my practice" (a new practice) calls POST /identity/my/facility_setup

Which practice the facility joins. A user who is owner or admin of an active practice adds the facility under it (existing_tenant). The practice open in the session wins when there are several. Any other user gets a new practice (new_tenant).

The start resets the run. It stores the user's own role in own_role, sets the role to add_facility, and sets Facility, Address, Team, Operations, Plan and Review to not_started with blank answers. The user's own completed_at stays, so /connect still opens the dashboard.

A run left part way. A run is open when at least one of its steps is completed or skipped, and Review has made nothing. An open run comes first at /connect, on Resume and on the dashboard card ("Continue adding a facility to ", or "Continue adding a new practice"). A run with every step not_started is ignored. The next "Add a facility" starts it again, blank. Answers typed on the first step, with no Continue or Skip for now, are lost in that case.

Stop adding this facility is on the rail, and on the dashboard card of an open run. It puts the user's own role back and makes nothing. It does not show once Review made the facility.

When a user leaves part way

Case 1: the user leaves before the end, and comes back later

For example, the user closes the tab on Verify.

When the user comes backWhat happens
Signed outA protected page sends the user to /signin?next=<page>. After sign-in, the user goes to that page, or to /connect for the root.
Still signed inThe session stays in browser storage until it expires or the user signs out. The root (/) opens /connect.

/connect then sees an unfinished flow and opens the user's next open step: the first step that is not completed or skipped. Steps already done keep their answers. A field that did not save yet comes back from the local draft.

A user with no known role goes back to Welcome.

An owner who pressed "Not now" on Review has a flow that is not finished, so /connect opens Review again. The dashboard also shows "Finish setting up your practice" with "Review and create". The practice is not made until the owner presses "Create my practice".

Case 2: the user skips steps, goes into Connect, and comes back

A skipped step counts as passed, so the next step opens. These steps have no Skip for now: About you, Facility (details), Offerings, Plan, Your desk, Goals and Review.

2a. The user finished Review with skipped steps. Onboarding is finished. Every later visit to /connect opens the dashboard, never the wizard.

  • Signed out: sign in, then the dashboard (or the next page).
  • Signed in: the root opens the dashboard.
  • The dashboard card "Continue setup" shows the setup percentage and names the first skipped step that no profile task covers, for example "Continue with verify" for a staff member.
  • Some skipped steps show inside a profile task and not as their own task: an owner's Address and Operations (facility task), Practice and Verify (practitioner task), a vendor's Get paid (vendor task, or the payout task when there is no vendor task) and Listing (vendor task), and a staff member's Facility (the join-a-facility task) (SKIPPED_STEP_COVERED_BY in components/dashboard/SetupChecklist.tsx).

2b. The user pressed "Do this later" before Review. Onboarding is not finished.

  • The dashboard shows "Continue setup" with the percentage and "Continue with ".
  • Signed out: sign in, then /connect opens the next open step, not the dashboard. Skipped steps stay skipped.
  • Signed in: the root opens the next open step. A direct link to /connect/dashboard or another Connect page still opens that page, with the "Continue setup" card.
  • Onboarding gates only the /connect page. The dashboard, the other Connect pages, the CMS and Growth open as usual.

What a finished user can open again

A finished user can open only these steps. Every other step URL goes to the dashboard.

  • Verify, while the verification status is none or rejected.
  • A step they skipped.
  • Goals, or Your desk for staff ("Change goals").
  • Vendor Review, while the vendor practice is not made.

On a step opened again, the main button reads "Save and return", and Back reads "Back to dashboard". Vendor Review is the exception: it shows the normal Review buttons ("Open my dashboard", Back and "Do this later").

Case 3: an "Add a facility" run left part way

  • With at least one step settled: sign-in reopens the run at its next step. The dashboard card reads "Continue adding a facility to ".
  • With no step settled: the run is ignored, and sign-in opens the dashboard (or the user's own next step).
  • "Stop adding this facility" ends the run either way.

Resume and the short path

  • Resume (/connect/resume) lists every step with its status and percentage. A skipped step reads "Skipped". The main button reads "Continue with " for the first step that is not settled, "Finish skipped steps" when only skipped steps are left, or "Go to dashboard". Resume also has Start over, which clears the whole document. Welcome links to it.
  • Confirm (/connect/confirm) is a short path for a practitioner a facility already entered. The user confirms three rows, and the page marks About you, Practice and Facilities completed and the other steps skipped. It never marks verification as verified. No screen links to it now.

Cross-references

On this page