Skip to content

test: School Creation, Onboarding Wizard & Multi-Tenant Isolation #298

Description

@guillermoscript

Scope

The school creation funnel, first-time admin onboarding, and multi-tenant data isolation (each school sees only its own data).

Personas

Persona Email Role
New creator fresh account creates school
Admin/Owner owner@e2etest.com Default School admin
Creator Admin creator@codeacademy.com Code Academy Pro admin
Student student@e2etest.com Default School
Alice alice@student.com Code Academy Pro

Local Dev Setup

Two tenants accessible locally:

  • school.lvh.me:3000 → Default School (owner@e2etest.com)
  • codeacademy.lvh.me:3000 → Code Academy Pro (creator@codeacademy.com)

Ensure NEXT_PUBLIC_PLATFORM_DOMAIN=lvh.me:3000 in .env.local.

Test Cases

School Creation Flow

  • /create-school on main domain: unauthenticated → shows sign-up step first
  • /create-school: authenticated → skips auth, shows school naming step
  • Slug auto-generated from name, editable, live preview shown
  • Duplicate slug → rejected with clear error
  • Successful creation: tenants row + tenant_users (admin role) created
  • After creation: cross-subdomain auth redirect to new school subdomain
  • New admin on new subdomain sees onboarding wizard (first visit only)

Onboarding Wizard

  • Steps shown: school branding, connect Stripe, create first course, invite team
  • Each step completable independently
  • Completed steps marked as done in wizard
  • "Skip" works for optional steps (Stripe)
  • Wizard dismisses after all steps done or explicit dismiss
  • Wizard does NOT show again after completion (localStorage/DB flag)

Join School Flow

  • Student visits school subdomain without being a member → redirected to /join-school
  • /join-school: Join button → creates tenant_users row with student role
  • After joining: redirected to /dashboard/student
  • Already-joined user visiting /join-school → redirected to dashboard without duplicate row

Multi-Tenant Data Isolation

  • owner@e2etest.com at Default School: sees only Default School courses/students
  • creator@codeacademy.com at Code Academy Pro: sees only Code Academy Pro data
  • Student on Default School (school.lvh.me:3000) cannot see Code Academy Pro courses
  • Student on Code Academy Pro (codeacademy.lvh.me:3000) cannot see Default School courses
  • Manually crafting URL with another school's course_id → returns 404 or access denied
  • Admin cannot see another tenant's transactions/enrollments/users

Role-Based Route Guards (middleware)

  • Student visiting /dashboard/admin → redirected to /dashboard/student
  • Student visiting /dashboard/teacher → redirected to /dashboard/student
  • Teacher visiting /dashboard/admin → redirected to /dashboard/teacher
  • Unauthenticated user visiting any /dashboard/* → redirected to /auth/login

Cross-Tenant Access (negative test)

  • owner@e2etest.com logged in at Default School subdomain — visiting codeacademy.lvh.me:3000 → redirected to /join-school for Code Academy Pro (not auto-joined)

Definition of Done

  • New school creation fully functional end-to-end
  • RLS confirmed: zero data leakage between tenants on all tested routes
  • Middleware role guards work for all three role types
  • Onboarding wizard only shows once per admin

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions