Decisions (ADRs)ADR-007 · Scripted onboarding

ADR-007 · Scripted onboarding over self-serve wizard first

Status: Accepted (scripted path primary; wizard behind a feature flag)

Context

A school is useless until its academic structure exists — units, academic year, terms, grades, classes, subjects, admin accounts. There are two ways to create that: a self-serve setup wizard the school clicks through, or operator-driven seeding where NexSchool builds it for them. The immediate business goal is a small, high-touch Gujarat pilot — a handful of schools that NexSchool onboards personally — not mass self-serve signup.

Decision

Make scripted, operator-driven seeding the primary onboarding path, and keep the self-serve wizard behind a feature flag until it’s ready:

  • server/scripts/seed_school.py consumes a YAML description of a school and bulk-creates its structure in one pass.
  • The structured school-setup flow (/api/school-setup/*) is super-admin-only (tenant Admin role stripped of school_setup.* in migration 064); operators run it via god-mode from the panel.
  • The in-app wizard is gated by NEXT_PUBLIC_ENABLE_SCHOOL_SETUP so it can mature without being exposed to tenants prematurely.

Consequences

Positive

  • Matches the white-glove pilot model: NexSchool sets each school up correctly, avoiding half-configured tenants.
  • YAML seeding is fast, repeatable, and reviewable — good for demos and re-seeding test tenants.
  • Keeps a not-yet-polished wizard out of tenants’ hands while still developing it.

Negative / cost

  • Does not scale to self-serve signup — every new school needs operator effort. This is an intentional trade for the pilot stage and will need the wizard (or an improved flow) before broad rollout.
  • Two onboarding paths to keep coherent as the academic model evolves.

Alternatives considered

  • Self-serve wizard first — necessary eventually, but shipping it half-baked risks broken tenants during the exact period when each pilot school matters most.
  • Manual DB entry — unrepeatable and error-prone; rejected.