Database

The database is engineered as a multi-tenant school management system that supports multiple schools in a single database with complete data isolation. Built on PostgreSQL with Prisma ORM, it provides a robust foundation for educational institutions while maintaining strict security boundaries between tenants.

Core Principles

Our database design is guided by fundamental principles that ensure scalability, security, and maintainability:

  • Row-Level Security – Every model includes a schoolId field ensuring complete data isolation between schools
  • Shared Schema Architecture – All schools use the same database schema, optimizing resource utilization
  • Domain-Based Tenant Identification – Schools are uniquely identified by subdomain (e.g., hogwarts.hogwarts.app), with optional custom domains via CNAME
  • Type-Safe Database Operations – Prisma ORM provides end-to-end type safety from database to frontend
  • Multi-File Schema Organization – Schema is organized into logical domains for better maintainability

Database Design

The database follows a comprehensive relational design that captures all aspects of school management from core infrastructure to daily operations.

Database Schema Diagram

The entity relationship diagram above illustrates the interconnected nature of our school management system, showing how entities relate through foreign key relationships while maintaining multi-tenant isolation through the schoolId field present in every table.

Multi-Tenant Isolation Strategy

The tenant isolation strategy ensures that each school's data remains completely separate while sharing the same database infrastructure.

Tenant Entity (School Model)

model School {
  id          String  @id @default(cuid())
  name        String
  domain      String  @unique // e.g., "hogwarts"
  logoUrl     String?
  address     String?
  phoneNumber String?
  email       String?
  timezone    String  @default("UTC")
  
  // Subscription/billing
  planType    String  @default("basic")
  maxStudents Int     @default(100)
  maxTeachers Int     @default(10)
  isActive    Boolean @default(true)
}

Data Isolation Example

// Correct - Always include schoolId
const students = await prisma.student.findMany({
  where: { schoolId: "school_123" }
})

// Wrong - Missing schoolId (security risk)
const students = await prisma.student.findMany()

Directory Structure

The Prisma directory follows a well-organized structure that supports both development and production scenarios with clear separation of concerns.

prisma/
schema.prismaMain configuration with datasource and generator
models/Schema files organized by domain (8 domains)
school.prismaSchool, SchoolYear, Period, Term, YearLevel
staff.prismaTeacher, Department, TeacherDepartment
students.prismaStudent, Guardian, StudentGuardian
subjects.prismaSubject, Class, StudentClass, ScoreRange
classrooms.prismaClassroom, ClassroomType
assessments.prismaAssignment, AssignmentSubmission
attendance.prismaAttendance with status tracking
auth.prismaUser, Account, tokens, 2FA
generator/Database seeding scripts
seed.tsSimple seeding for basic data
multi-seed.tsMulti-school seeding orchestrator
seed-selector.tsAdvanced seed selection options
migrations/Auto-generated migration files
migration_lock.tomlMigration provider lock
README.mdDatabase documentation and guide
ISSUE.mdKnown issues and troubleshooting

Schema Tables

Each model contains realistic sample data that demonstrates the relationships and data structure of our multi-tenant school management system.

School (Tenant Entity)

Main tenant entities representing different schools in the multi-tenant system

IDSchool NameDomainPlanMax StudentsActive
sch_001Hogwartshogwartspremium1000Yes
sch_002Beauxbatonsbeauxbatonspremium500Yes
sch_003Durmstrangdurmstrangbasic300Yes

Teacher

Teaching staff with school-specific isolation and department assignments

IDSchool IDFirst NameLast NameEmailGender
tch_001sch_001MinervaMcGonagallm.mcg@hogwarts.eduF
tch_002sch_001SeverusSnapes.snape@hogwarts.eduM
tch_003sch_001RubeusHagridr.hagrid@hogwarts.eduM

Student

Student enrollment records with guardian relationships and year-level tracking

IDSchool IDFirst NameMiddle NameLast NameDate of BirthGender
std_001sch_001HarryJPotter1980-07-31M
std_002sch_001HermioneJGranger1979-09-19F
std_003sch_001RonBWeasley1980-03-01M

Department

Academic departments organizing subjects and teacher assignments

IDSchool IDDepartment Name
dep_001sch_001Transfiguration
dep_002sch_001Potions
dep_003sch_001Creatures

Subject

Academic subjects within departments that form the basis of classes

IDSchool IDDepartment IDSubject Name
sub_001sch_001dep_001Transfiguration
sub_002sch_001dep_002Potions
sub_003sch_001dep_003Creatures

Classroom

Physical classroom locations with capacity and type information

IDSchool IDRoom NameCapacityType
cls_001sch_001Great Hall400Hall
cls_002sch_001Dungeon30Lab
cls_003sch_001Room 10135Class

Assignment

Assessment tasks including homework, quizzes, tests, and projects

IDSchool IDTitleTypeStatusPointsDue Date
asg_001sch_001EssayESSAYPUBLISHED1002024-02-15
asg_002sch_001QuizQUIZCOMPLETED502024-02-10
asg_003sch_001ProjectPROJECTIN_PROGRESS1502024-02-20

Attendance

Daily attendance tracking per student per class with detailed status information

IDSchool IDStudent IDDateStatusNotes
att_001sch_001std_0012024-02-08PRESENT
att_002sch_001std_0022024-02-08PRESENT
att_003sch_001std_0032024-02-08LATELate

User (Authentication)

Multi-tenant user accounts with role-based access control and school isolation

IDEmailRoleSchool IDVerified
usr_001harry@hog.eduSTUDENTsch_001Yes
usr_002mcg@hog.eduTEACHERsch_001Yes
usr_003admin@dev.comDEVELOPERnull (all schools)Yes

Authentication & User Roles

The system supports 8 distinct user roles with varying levels of access and school-specific constraints:

RoleDescriptionSchool AccessTypical Use Case
DEVELOPERPlatform administratorAll schoolsSystem maintenance, cross-tenant operations
ADMINSchool administratorSingle schoolSchool management, user oversight
TEACHERTeaching staffSingle schoolClass management, grading, attendance
STUDENTEnrolled studentsSingle schoolLearning management, assignment submission
GUARDIANStudent parents/guardiansSingle schoolMonitor child's progress, communication
ACCOUNTANTFinance staffSingle schoolBilling, financial reporting
STAFFGeneral school staffSingle schoolAdministrative support
USERDefault roleSingle schoolBase level access

Security & Data Protection

Automatic Tenant Filtering

Every database query must include the schoolId to ensure proper data isolation:

// Server action with tenant context
export async function getStudents() {
  const schoolId = getSchoolId() // From middleware context
  
  return await prisma.student.findMany({
    where: { schoolId }
  })
}

Unique Constraints with School Scope

All unique constraints include schoolId to allow data duplication across schools:

// Teachers can have same email across different schools
@@unique([schoolId, emailAddress])

// Departments can have same names across schools
@@unique([schoolId, departmentName])

Performance Optimization

Recommended Database Indexes

-- Critical indexes for multi-tenant queries
CREATE INDEX idx_students_school_id ON students(school_id);
CREATE INDEX idx_teachers_school_id ON teachers(school_id);
CREATE INDEX idx_classes_school_id ON classes(school_id);
CREATE INDEX idx_attendance_school_id ON attendance(school_id);

Query Performance Guidelines

  • Always filter by schoolId first in WHERE clauses
  • Use composite indexes for frequently queried field combinations
  • Implement connection pooling for high-traffic scenarios
  • Consider read replicas for reporting and analytics

Deployment Configuration

Environment Variables

# Database Connection
DATABASE_URL="postgresql://username:password@host:port/database"

# Multi-tenancy Configuration
DEFAULT_SCHOOL_DOMAIN="demo"
ALLOW_SCHOOL_SIGNUP="true"

# Subscription Limits
BASIC_MAX_STUDENTS=100
PREMIUM_MAX_STUDENTS=500
ENTERPRISE_MAX_STUDENTS=2000

Migration Commands

# Generate Prisma Client
pnpm prisma generate

# Create and apply migrations
pnpm prisma migrate dev --name init

# Deploy to production
pnpm prisma migrate deploy

# Seed sample data
pnpm prisma db seed

Sample Schools & Test Data

The seeding system creates three sample schools with complete datasets:

SchoolDomainDescription
Hogwartshogwarts.comSchool of Witchcraft and Wizardry
Beauxbatonsbeauxbatons.comAcademy of Magic
Durmstrangdurmstrang.comInstitute for Magical Learning

Hogwarts

  • Complete academic structure
  • 4 houses with qualified professors
  • 1000+ active students
  • Full magical curriculum

Beauxbatons

  • French academic system
  • 6 departments
  • 700+ students
  • Specialized courses

Durmstrang

  • Nordic education model
  • 5 faculties
  • 500+ students
  • Advanced programs

This comprehensive database architecture provides the foundation for building scalable, secure, and feature-rich educational management systems.