Model locations
Models live in two directories:app/Models/(root) — ~20 models includingTutor,Coupon,File,Note,Subscription, and non-Eloquent value objectsapp/Models/v1/— ~107 models — this is where the main domain logic lives
Most business logic is in the
v1/ models. When someone says “the User model” they mean app/Models/v1/User.php.User model
app/Models/v1/User.php — the central model. Extends Laravel’s Authenticatable, implements MustVerifyEmail, uses SoftDeletes.
Key relationships
Profile completion
Tutors go through a 4-step profile completion process.getProfileCompletionPercentage() tracks progress:
- Taught subjects — at least one
Teachwith aLessonPrice - Qualifications — valid education OR valid qualification document
- Bank account — active
PaymentAccountwith linkedBankAccount - Identity verification — passed
VerificationAccount
isVerified()) when they have: profile picture, bio, primary address, mobile number, taught subjects, valid availability, passed identity verification, valid qualification/education, and valid DBS.
Key query scopes
Tutor model
app/Models/Tutor.php — extends User via HasParent trait (from calebporzio/parental).
Tutor:: automatically filters to tutors only. Adds methods:
isVerified()— full profile + verification checkshouldApplyManagementFee()— first lesson of month logicgetAvailableLessonLocations()— based on verification statusisGoogleConnected()— Google Calendar status
Lesson model
app/Models/v1/Lesson.php — uses SoftDeletes and LoggableActivity trait.
States
Key methods
Auto-calculated fields
The model’sboot() method auto-calculates duration in minutes whenever start and finish are set.
Booking model
app/Models/v1/Booking.php — uses SoftDeletes and LoggableActivity.
States
Teach model
app/Models/v1/Teach.php — the tutor↔subject relationship. Uses SoftDeletes.
Each Teach record has:
- One
Subject - Many
SubjectLevels(viataught_subject_levelspivot) - Many
ExamBoards(viataught_exam_boardspivot) - One
LessonPrice(the tutor’s hourly rate for this subject)
Models with soft deletes
These models useSoftDeletes — queries need withTrashed() to include deleted records:
User,Booking,Lesson,TeachCard,BankAccount,ChildVerificationAccount,SubscriptionExamBoard