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
Onboarding Wizard
Join School Flow
Multi-Tenant Data Isolation
Role-Based Route Guards (middleware)
Cross-Tenant Access (negative test)
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
Scope
The school creation funnel, first-time admin onboarding, and multi-tenant data isolation (each school sees only its own data).
Personas
owner@e2etest.comcreator@codeacademy.comstudent@e2etest.comalice@student.comLocal 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:3000in.env.local.Test Cases
School Creation Flow
/create-schoolon main domain: unauthenticated → shows sign-up step first/create-school: authenticated → skips auth, shows school naming steptenantsrow +tenant_users(admin role) createdOnboarding Wizard
Join School Flow
/join-school/join-school: Join button → createstenant_usersrow withstudentrole/dashboard/student/join-school→ redirected to dashboard without duplicate rowMulti-Tenant Data Isolation
owner@e2etest.comat Default School: sees only Default School courses/studentscreator@codeacademy.comat Code Academy Pro: sees only Code Academy Pro dataschool.lvh.me:3000) cannot see Code Academy Pro coursescodeacademy.lvh.me:3000) cannot see Default School coursescourse_id→ returns 404 or access deniedRole-Based Route Guards (middleware)
/dashboard/admin→ redirected to/dashboard/student/dashboard/teacher→ redirected to/dashboard/student/dashboard/admin→ redirected to/dashboard/teacher/dashboard/*→ redirected to/auth/loginCross-Tenant Access (negative test)
owner@e2etest.comlogged in at Default School subdomain — visitingcodeacademy.lvh.me:3000→ redirected to/join-schoolfor Code Academy Pro (not auto-joined)Definition of Done