# Onboarding

A club's applicant onboarding, blocks, editing, and immutable application snapshots.

Source: https://docs.champagne.dev-ukab.fr/en/onboarding

Each club can have multiple onboardings for different audiences. Choose a club in the
back-office switcher, open **Applications**, then select the **Onboardings** tab. The list
shows each onboarding's name, description, and copyable short ID. Staff can add an onboarding
and edit its identity and blocks. New clubs receive a common-members onboarding automatically.

## Champagne-hosted application site [#champagne-hosted-application-site]

An onboarding can be published as a ready-to-use applicant site when a club does not want to
build its own form. In the onboarding editor, enable **Champagne-hosted application**, choose a
globally unique address label such as `51-iena`, then select a font and primary brand color. The
resulting public address is `https://51-iena.champagne.dev-ukab.fr` (staging: `https://51-iena.staging.champagne.dev-ukab.fr`).

Address labels are deliberately separate from both the onboarding name and its implementation ID.
They use one DNS-safe label of 3–63 lowercase letters, numbers, and hyphens; leading or trailing
hyphens and reserved Champagne service labels are rejected. This keeps a public address stable when
staff rename an onboarding while still allowing an explicit address change. Disabling publication
removes public resolution but retains the selected address and branding for later reuse.

Every onboarding contains exactly one required **Applicant name** block and one
required **Email verification** block. They cannot be removed or made optional.
The entered first and last names identify the application in the back office and
are used to create a person when the application is accepted. An optional
**Applicant address** block can be added once; it collects a structured address
(`line1`, `line2`, `city`, `postalCode`, `state`, `country`) whose value is forwarded to the
person record on acceptance, or saved on it at once when asked after approval.

## Blocks and editing [#blocks-and-editing]

An onboarding has an ordered list of 1–50 blocks. Ordinary questions have a stable
UUID, title, required-answer flag, and one of three types:

* **Short answer**: a single-line response.
* **Long answer**: a multiline response.
* **Options**: one choice from 2–20 distinct options.

The editor also offers **Applicant name**, **Applicant address**, **Plan selection**, **Plan payment**,
**Document signature**, and **Email verification** blocks. Email verification,
plan selection, plan payment, and applicant address may each appear once. Payment requires a plan
selection earlier in the list. Signature blocks may appear multiple times and
each requires a PDF attachment before saving.

Steps after approval are asked once the application is accepted. Plan payment and document
signature belong there only. Applicant address, phone verification, identity verification and
visit booking can be placed either before or after approval, once in the whole onboarding; before
approval, identity verification and booking come after the applicant name and email blocks.

PDF attachments are limited to 2 MiB each and 4 MiB across the onboarding. Save
persists the whole onboarding atomically. Failed saves preserve pending edits;
leaving with unsaved changes warns the administrator. Optimistic revisions reject
stale saves instead of overwriting another edit.

## Database and API [#database-and-api]

`public.onboarding` stores `id`, `clubId`, `name`, `description`, hosted-site publication and
branding settings, ordered JSONB
`questions`, `afterApproval`, and `revision`. Multiple rows can belong to one club;
`club.onboardingId` keeps the automatically created common-members onboarding reference.
Startup installs an idempotent PostgreSQL trigger and backfills clubs missing that initial onboarding.

GraphQL exposes `onboardings(clubId)`, `onboarding(clubId, id)`, `hostedOnboarding(slug)`,
`createOnboarding(input)`, and `saveOnboarding(input)`. Reads and writes keep explicit
club scope; application starts instead use the short onboarding ID so consumer apps can route
different audiences to different experiences.

## Application snapshots [#application-snapshots]

Starting an application with `startApplication(onboardingId)` copies the selected onboarding's revision, ordered blocks, options,
and signature documents. Later onboarding edits cannot reinterpret an
in-progress or historical application.

## Sponsorship [#sponsorship]

Add **Sponsorship** and set **Number of sponsors** (1–5, default 2). Applicants enter
that many sponsor codes, each generated by a different active member from the
**Sponsorship** tab of their account. A code works once and is checked when the step is
saved. The application dossier lists the sponsors, and accepting the application records
them on the new member's profile. The final admission remains a staff decision. Changing
the count does not change existing applications.
