refactor: update model relationships and request validation rules for consistency

This commit is contained in:
Yoga Pangestu 2026-09-03 10:53:48 +07:00
parent 88286fe596
commit 9f717a3441
26 changed files with 197 additions and 124 deletions

View File

@ -73,13 +73,6 @@ public function update(FeedbackRequest $request, Feedback $feedback): RedirectRe
return to_route('admin.feedback.index'); return to_route('admin.feedback.index');
} }
public function updateStatus(UpdateFeedbackStatusRequest $request, Feedback $feedback): RedirectResponse
{
$this->service->updateStatus($feedback, $request->validated('status'));
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Status masukan berhasil diperbarui.'])->back();
}
public function destroy(Request $request, Feedback $feedback): RedirectResponse public function destroy(Request $request, Feedback $feedback): RedirectResponse
{ {
abort_unless($feedback->user_id === $request->user()->id, 403); abort_unless($feedback->user_id === $request->user()->id, 403);
@ -88,4 +81,11 @@ public function destroy(Request $request, Feedback $feedback): RedirectResponse
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Masukan berhasil dihapus.'])->back(); return Inertia::flash('toast', ['type' => 'success', 'message' => 'Masukan berhasil dihapus.'])->back();
} }
public function updateStatus(UpdateFeedbackStatusRequest $request, Feedback $feedback): RedirectResponse
{
$this->service->updateStatus($feedback, $request->validated('status'));
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Status masukan berhasil diperbarui.'])->back();
}
} }

View File

@ -17,7 +17,7 @@ public function rules(): array
{ {
return [ return [
'course_class_id' => ['required', 'integer', Rule::exists('course_classes', 'id')], 'course_class_id' => ['required', 'integer', Rule::exists('course_classes', 'id')],
'day_of_week' => ['required', 'string', Rule::in(DayOfWeek::values())], 'day_of_week' => ['required', 'string', Rule::enum(DayOfWeek::class)],
'start_time' => ['required', 'date_format:H:i'], 'start_time' => ['required', 'date_format:H:i'],
'end_time' => ['required', 'date_format:H:i', 'after:start_time'], 'end_time' => ['required', 'date_format:H:i', 'after:start_time'],
'room' => ['nullable', 'string', 'max:20'], 'room' => ['nullable', 'string', 'max:20'],

View File

@ -16,7 +16,7 @@ public function authorize(): bool
public function rules(): array public function rules(): array
{ {
return [ return [
'type' => ['required', 'string', Rule::in(FeedbackType::values())], 'type' => ['required', 'string', Rule::enum(FeedbackType::class)],
'subject' => ['required', 'string', 'max:150'], 'subject' => ['required', 'string', 'max:150'],
'message' => ['required', 'string'], 'message' => ['required', 'string'],
]; ];

View File

@ -69,7 +69,7 @@ function ($attribute, $value, $fail) {
}, },
], ],
'academic_term_id' => ['required', 'integer', Rule::exists('academic_terms', 'id')], 'academic_term_id' => ['required', 'integer', Rule::exists('academic_terms', 'id')],
'method' => ['nullable', 'string', Rule::in(ClassMethod::values())], 'method' => ['nullable', 'string', Rule::enum(ClassMethod::class)],
]; ];
} }
@ -92,7 +92,7 @@ function ($attribute, $value, $fail) {
Rule::exists('lecturer_department', 'lecturer_id')->where('department_id', $departmentId), Rule::exists('lecturer_department', 'lecturer_id')->where('department_id', $departmentId),
], ],
'academic_term_id' => ['required', 'integer', Rule::exists('academic_terms', 'id')], 'academic_term_id' => ['required', 'integer', Rule::exists('academic_terms', 'id')],
'method' => ['nullable', 'string', Rule::in(ClassMethod::values())], 'method' => ['nullable', 'string', Rule::enum(ClassMethod::class)],
]; ];
} }
} }

View File

@ -38,7 +38,7 @@ function ($attribute, $value, $fail) {
'semester' => [ 'semester' => [
'required', 'required',
'string', 'string',
Rule::in(Semester::values()), Rule::enum(Semester::class),
Rule::unique('academic_terms')->where(function ($query) { Rule::unique('academic_terms')->where(function ($query) {
return $query->where('academic_year', $this->input('academic_year')); return $query->where('academic_year', $this->input('academic_year'));
})->ignore($this->route('academic_term')), })->ignore($this->route('academic_term')),

View File

@ -43,7 +43,7 @@ public function rules(): array
'full_name' => ['required', 'string', 'max:150'], 'full_name' => ['required', 'string', 'max:150'],
'phone_number' => ['required', 'string', 'max:20'], 'phone_number' => ['required', 'string', 'max:20'],
'address' => ['required', 'string'], 'address' => ['required', 'string'],
'gender' => ['required', 'string', Rule::in(Gender::values())], 'gender' => ['required', 'string', Rule::enum(Gender::class)],
'birth_date' => ['required', 'date'], 'birth_date' => ['required', 'date'],
'birth_place' => ['required', 'string', 'max:100'], 'birth_place' => ['required', 'string', 'max:100'],
]; ];

View File

@ -42,7 +42,7 @@ public function rules(): array
'full_name' => ['required', 'string', 'max:150'], 'full_name' => ['required', 'string', 'max:150'],
'phone_number' => ['required', 'string', 'max:20'], 'phone_number' => ['required', 'string', 'max:20'],
'address' => ['required', 'string'], 'address' => ['required', 'string'],
'gender' => ['required', 'string', Rule::in(Gender::values())], 'gender' => ['required', 'string', Rule::enum(Gender::class)],
'birth_date' => ['required', 'date'], 'birth_date' => ['required', 'date'],
'birth_place' => ['required', 'string', 'max:100'], 'birth_place' => ['required', 'string', 'max:100'],

View File

@ -43,7 +43,7 @@ public function rules(): array
'full_name' => ['required', 'string', 'max:150'], 'full_name' => ['required', 'string', 'max:150'],
'phone_number' => ['required', 'string', 'max:20'], 'phone_number' => ['required', 'string', 'max:20'],
'address' => ['required', 'string'], 'address' => ['required', 'string'],
'gender' => ['required', 'string', Rule::in(Gender::values())], 'gender' => ['required', 'string', Rule::enum(Gender::class)],
'birth_date' => ['required', 'date'], 'birth_date' => ['required', 'date'],
'birth_place' => ['required', 'string', 'max:100'], 'birth_place' => ['required', 'string', 'max:100'],
@ -79,7 +79,7 @@ public function rules(): array
'status' => [ 'status' => [
'nullable', 'nullable',
'string', 'string',
Rule::in(StudentStatus::values()), Rule::enum(StudentStatus::class),
], ],
]; ];
} }

View File

@ -16,7 +16,7 @@ public function authorize(): bool
public function rules(): array public function rules(): array
{ {
return [ return [
'status' => ['required', 'string', Rule::in(StudentStatus::values())], 'status' => ['required', 'string', Rule::enum(StudentStatus::class)],
]; ];
} }
} }

View File

@ -22,19 +22,19 @@ public function rules(): array
'per_page' => ['nullable', 'integer', 'in:25,50,100,999999'], 'per_page' => ['nullable', 'integer', 'in:25,50,100,999999'],
'search' => ['nullable', 'string', 'max:255'], 'search' => ['nullable', 'string', 'max:255'],
'highlight' => ['nullable', 'integer'], 'highlight' => ['nullable', 'integer'],
'gender' => ['nullable', 'string', Rule::in(Gender::values())], 'gender' => ['nullable', 'string', Rule::enum(Gender::class)],
'department_id' => ['nullable', 'integer'], 'department_id' => ['nullable', 'integer'],
'status' => ['nullable', 'string'], 'status' => ['nullable', 'string'],
'enrollment_year' => ['nullable', 'integer'], 'enrollment_year' => ['nullable', 'integer'],
'semester_number' => ['nullable', 'integer'], 'semester_number' => ['nullable', 'integer'],
'semester' => ['nullable', 'string', Rule::in(Semester::values())], 'semester' => ['nullable', 'string', Rule::enum(Semester::class)],
'is_active' => ['nullable', Rule::in(['true', 'false'])], 'is_active' => ['nullable', Rule::in(['true', 'false'])],
'academic_term_id' => ['nullable', 'integer'], 'academic_term_id' => ['nullable', 'integer'],
'method' => ['nullable', 'string', Rule::in(ClassMethod::values())], 'method' => ['nullable', 'string', Rule::enum(ClassMethod::class)],
'course_class_id' => ['nullable', 'integer'], 'course_class_id' => ['nullable', 'integer'],
'lecturer_id' => ['nullable', 'integer'], 'lecturer_id' => ['nullable', 'integer'],
'type' => ['nullable', 'string'], 'type' => ['nullable', 'string'],
'payment_method' => ['nullable', 'string', Rule::in(PaymentMethod::values())], 'payment_method' => ['nullable', 'string', Rule::enum(PaymentMethod::class)],
'file' => ['nullable', 'string'], 'file' => ['nullable', 'string'],
'level' => ['nullable', 'string'], 'level' => ['nullable', 'string'],
]; ];

View File

@ -13,13 +13,13 @@ class AcademicAdvisingLog extends Model
{ {
use HasFactory; use HasFactory;
public function students(): BelongsToMany
{
return $this->belongsToMany(Student::class);
}
public function lecturer(): BelongsTo public function lecturer(): BelongsTo
{ {
return $this->belongsTo(Lecturer::class); return $this->belongsTo(Lecturer::class);
} }
public function students(): BelongsToMany
{
return $this->belongsToMany(Student::class);
}
} }

View File

@ -16,6 +16,21 @@ class AcademicTerm extends Model
{ {
use HasFactory; use HasFactory;
public function courseClasses(): HasMany
{
return $this->hasMany(CourseClass::class);
}
public function courseRegistrations(): HasMany
{
return $this->hasMany(CourseRegistration::class);
}
public function courseRegistrationSubmissions(): HasMany
{
return $this->hasMany(CourseRegistrationSubmission::class);
}
public function tuitionInvoices(): HasMany public function tuitionInvoices(): HasMany
{ {
return $this->hasMany(TuitionInvoice::class); return $this->hasMany(TuitionInvoice::class);

View File

@ -13,13 +13,13 @@ class Announcement extends Model
{ {
use HasFactory, SoftDeletes; use HasFactory, SoftDeletes;
public function department(): BelongsTo
{
return $this->belongsTo(Department::class);
}
public function creator(): BelongsTo public function creator(): BelongsTo
{ {
return $this->belongsTo(User::class, 'created_by'); return $this->belongsTo(User::class, 'created_by');
} }
public function department(): BelongsTo
{
return $this->belongsTo(Department::class);
}
} }

View File

@ -22,6 +22,11 @@ protected function casts(): array
]; ];
} }
public function academicTerm(): BelongsTo
{
return $this->belongsTo(AcademicTerm::class);
}
public function course(): BelongsTo public function course(): BelongsTo
{ {
return $this->belongsTo(Course::class); return $this->belongsTo(Course::class);
@ -32,9 +37,14 @@ public function lecturer(): BelongsTo
return $this->belongsTo(Lecturer::class); return $this->belongsTo(Lecturer::class);
} }
public function academicTerm(): BelongsTo public function assignments(): HasMany
{ {
return $this->belongsTo(AcademicTerm::class); return $this->hasMany(Assignment::class);
}
public function attendances(): HasMany
{
return $this->hasMany(Attendance::class);
} }
public function enrollments(): HasMany public function enrollments(): HasMany
@ -47,23 +57,13 @@ public function materials(): HasMany
return $this->hasMany(Material::class); return $this->hasMany(Material::class);
} }
public function assignments(): HasMany public function registrations(): HasMany
{ {
return $this->hasMany(Assignment::class); return $this->hasMany(CourseRegistration::class);
} }
public function schedules(): HasMany public function schedules(): HasMany
{ {
return $this->hasMany(Schedule::class); return $this->hasMany(Schedule::class);
} }
public function attendances(): HasMany
{
return $this->hasMany(Attendance::class);
}
public function registrations(): HasMany
{
return $this->hasMany(CourseRegistration::class);
}
} }

View File

@ -12,11 +12,6 @@ class CourseRegistration extends Model
{ {
use HasFactory; use HasFactory;
public function student(): BelongsTo
{
return $this->belongsTo(Student::class);
}
public function academicTerm(): BelongsTo public function academicTerm(): BelongsTo
{ {
return $this->belongsTo(AcademicTerm::class); return $this->belongsTo(AcademicTerm::class);
@ -27,6 +22,11 @@ public function courseClass(): BelongsTo
return $this->belongsTo(CourseClass::class); return $this->belongsTo(CourseClass::class);
} }
public function student(): BelongsTo
{
return $this->belongsTo(Student::class);
}
public function submission(): BelongsTo public function submission(): BelongsTo
{ {
return $this->belongsTo(CourseRegistrationSubmission::class, 'submission_id'); return $this->belongsTo(CourseRegistrationSubmission::class, 'submission_id');

View File

@ -35,11 +35,6 @@ public function registerMediaCollections(): void
$this->addMediaCollection('advisor_signature')->singleFile(); $this->addMediaCollection('advisor_signature')->singleFile();
} }
public function student(): BelongsTo
{
return $this->belongsTo(Student::class);
}
public function academicTerm(): BelongsTo public function academicTerm(): BelongsTo
{ {
return $this->belongsTo(AcademicTerm::class); return $this->belongsTo(AcademicTerm::class);
@ -50,6 +45,11 @@ public function reviewer(): BelongsTo
return $this->belongsTo(User::class, 'reviewed_by'); return $this->belongsTo(User::class, 'reviewed_by');
} }
public function student(): BelongsTo
{
return $this->belongsTo(Student::class);
}
public function courseRegistrations(): HasMany public function courseRegistrations(): HasMany
{ {
return $this->hasMany(CourseRegistration::class, 'submission_id'); return $this->hasMany(CourseRegistration::class, 'submission_id');

View File

@ -17,13 +17,13 @@ protected function casts(): array
]; ];
} }
public function submission(): BelongsTo
{
return $this->belongsTo(CourseRegistrationSubmission::class, 'submission_id');
}
public function actor(): BelongsTo public function actor(): BelongsTo
{ {
return $this->belongsTo(User::class, 'actor_id'); return $this->belongsTo(User::class, 'actor_id');
} }
public function submission(): BelongsTo
{
return $this->belongsTo(CourseRegistrationSubmission::class, 'submission_id');
}
} }

View File

@ -15,14 +15,19 @@ class Department extends Model
{ {
use HasFactory, SoftDeletes; use HasFactory, SoftDeletes;
public function lecturers(): BelongsToMany public function currentLeader(): HasOne
{ {
return $this->belongsToMany(Lecturer::class, 'lecturer_department'); return $this->hasOne(DepartmentLeadership::class)->whereNull('ended_at');
} }
public function students(): HasMany public function announcements(): HasMany
{ {
return $this->hasMany(Student::class); return $this->hasMany(Announcement::class);
}
public function courses(): HasMany
{
return $this->hasMany(Course::class);
} }
public function leaderships(): HasMany public function leaderships(): HasMany
@ -30,8 +35,13 @@ public function leaderships(): HasMany
return $this->hasMany(DepartmentLeadership::class); return $this->hasMany(DepartmentLeadership::class);
} }
public function currentLeader(): HasOne public function students(): HasMany
{ {
return $this->hasOne(DepartmentLeadership::class)->whereNull('ended_at'); return $this->hasMany(Student::class);
}
public function lecturers(): BelongsToMany
{
return $this->belongsToMany(Lecturer::class, 'lecturer_department');
} }
} }

View File

@ -24,13 +24,13 @@ protected function casts(): array
]; ];
} }
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function handler(): BelongsTo public function handler(): BelongsTo
{ {
return $this->belongsTo(User::class, 'handled_by'); return $this->belongsTo(User::class, 'handled_by');
} }
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
} }

View File

@ -20,9 +20,9 @@ public function user(): BelongsTo
return $this->belongsTo(User::class); return $this->belongsTo(User::class);
} }
public function departments(): BelongsToMany public function academicAdvisingLogs(): HasMany
{ {
return $this->belongsToMany(Department::class, 'lecturer_department'); return $this->hasMany(AcademicAdvisingLog::class);
} }
public function advisees(): HasMany public function advisees(): HasMany
@ -30,13 +30,18 @@ public function advisees(): HasMany
return $this->hasMany(Student::class, 'academic_advisor_id'); return $this->hasMany(Student::class, 'academic_advisor_id');
} }
public function courseClasses(): HasMany
{
return $this->hasMany(CourseClass::class);
}
public function leaderships(): HasMany public function leaderships(): HasMany
{ {
return $this->hasMany(DepartmentLeadership::class); return $this->hasMany(DepartmentLeadership::class);
} }
public function academicAdvisingLogs(): HasMany public function departments(): BelongsToMany
{ {
return $this->hasMany(AcademicAdvisingLog::class); return $this->belongsToMany(Department::class, 'lecturer_department');
} }
} }

View File

@ -32,16 +32,16 @@ public function registerMediaCollections(): void
$this->addMediaCollection('letter_result')->singleFile(); $this->addMediaCollection('letter_result')->singleFile();
} }
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function processor(): BelongsTo public function processor(): BelongsTo
{ {
return $this->belongsTo(User::class, 'processed_by'); return $this->belongsTo(User::class, 'processed_by');
} }
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
protected function resultUrl(): Attribute protected function resultUrl(): Attribute
{ {
return Attribute::make( return Attribute::make(

View File

@ -1,10 +0,0 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Mahasiswa extends Model
{
//
}

View File

@ -19,13 +19,13 @@ protected function casts(): array
]; ];
} }
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function creator(): BelongsTo public function creator(): BelongsTo
{ {
return $this->belongsTo(User::class, 'created_by'); return $this->belongsTo(User::class, 'created_by');
} }
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
} }

View File

@ -8,6 +8,7 @@
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\SoftDeletes;
#[Guarded(['id'])] #[Guarded(['id'])]
@ -22,9 +23,9 @@ protected function casts(): array
]; ];
} }
public function user(): BelongsTo public function academicAdvisor(): BelongsTo
{ {
return $this->belongsTo(User::class); return $this->belongsTo(Lecturer::class, 'academic_advisor_id');
} }
public function department(): BelongsTo public function department(): BelongsTo
@ -32,19 +33,14 @@ public function department(): BelongsTo
return $this->belongsTo(Department::class); return $this->belongsTo(Department::class);
} }
public function academicAdvisor(): BelongsTo public function user(): BelongsTo
{ {
return $this->belongsTo(Lecturer::class, 'academic_advisor_id'); return $this->belongsTo(User::class);
} }
public function enrollments(): HasMany public function academicAdvisingLogs(): HasMany
{ {
return $this->hasMany(ClassEnrollment::class); return $this->hasMany(AcademicAdvisingLog::class);
}
public function submissions(): HasMany
{
return $this->hasMany(Submission::class);
} }
public function attendances(): HasMany public function attendances(): HasMany
@ -52,11 +48,6 @@ public function attendances(): HasMany
return $this->hasMany(Attendance::class); return $this->hasMany(Attendance::class);
} }
public function tuitionInvoices(): HasMany
{
return $this->hasMany(TuitionInvoice::class);
}
public function courseRegistrations(): HasMany public function courseRegistrations(): HasMany
{ {
return $this->hasMany(CourseRegistration::class); return $this->hasMany(CourseRegistration::class);
@ -67,13 +58,30 @@ public function courseRegistrationSubmissions(): HasMany
return $this->hasMany(CourseRegistrationSubmission::class); return $this->hasMany(CourseRegistrationSubmission::class);
} }
public function letterRequests(): HasMany public function enrollments(): HasMany
{ {
return $this->hasMany(LetterRequest::class); return $this->hasMany(ClassEnrollment::class);
} }
public function academicAdvisingLogs(): HasMany public function submissions(): HasMany
{ {
return $this->hasMany(AcademicAdvisingLog::class); return $this->hasMany(Submission::class);
}
public function tuitionInvoices(): HasMany
{
return $this->hasMany(TuitionInvoice::class);
}
public function letterRequests(): HasManyThrough
{
return $this->hasManyThrough(
LetterRequest::class,
User::class,
'id',
'user_id',
'user_id',
'id',
);
} }
} }

View File

@ -21,16 +21,16 @@ protected function casts(): array
]; ];
} }
public function student(): BelongsTo
{
return $this->belongsTo(Student::class);
}
public function academicTerm(): BelongsTo public function academicTerm(): BelongsTo
{ {
return $this->belongsTo(AcademicTerm::class); return $this->belongsTo(AcademicTerm::class);
} }
public function student(): BelongsTo
{
return $this->belongsTo(Student::class);
}
public function payments(): HasMany public function payments(): HasMany
{ {
return $this->hasMany(TuitionPayment::class, 'invoice_id'); return $this->hasMany(TuitionPayment::class, 'invoice_id');

View File

@ -38,6 +38,11 @@ protected function fullName(): Attribute
return Attribute::get(fn () => $this->profile?->full_name ?? $this->username); return Attribute::get(fn () => $this->profile?->full_name ?? $this->username);
} }
public function lecturer(): HasOne
{
return $this->hasOne(Lecturer::class);
}
public function profile(): HasOne public function profile(): HasOne
{ {
return $this->hasOne(UserProfile::class); return $this->hasOne(UserProfile::class);
@ -48,9 +53,34 @@ public function student(): HasOne
return $this->hasOne(Student::class); return $this->hasOne(Student::class);
} }
public function lecturer(): HasOne public function courseRegistrationSubmissionLogs(): HasMany
{ {
return $this->hasOne(Lecturer::class); return $this->hasMany(CourseRegistrationSubmissionLog::class, 'actor_id');
}
public function createdAnnouncements(): HasMany
{
return $this->hasMany(Announcement::class, 'created_by');
}
public function createdNotifications(): HasMany
{
return $this->hasMany(Notification::class, 'created_by');
}
public function feedbacks(): HasMany
{
return $this->hasMany(Feedback::class);
}
public function handledFeedbacks(): HasMany
{
return $this->hasMany(Feedback::class, 'handled_by');
}
public function letterRequests(): HasMany
{
return $this->hasMany(LetterRequest::class);
} }
public function notifications(): HasMany public function notifications(): HasMany
@ -58,9 +88,24 @@ public function notifications(): HasMany
return $this->hasMany(Notification::class); return $this->hasMany(Notification::class);
} }
public function feedbacks(): HasMany public function processedLetterRequests(): HasMany
{ {
return $this->hasMany(Feedback::class); return $this->hasMany(LetterRequest::class, 'processed_by');
}
public function recordedTuitionPayments(): HasMany
{
return $this->hasMany(TuitionPayment::class, 'recorded_by');
}
public function reviewedCourseRegistrationSubmissions(): HasMany
{
return $this->hasMany(CourseRegistrationSubmission::class, 'reviewed_by');
}
public function uploads(): HasMany
{
return $this->hasMany(EditorUpload::class, 'uploaded_by');
} }
public function isAdvisorOf(Student $student): bool public function isAdvisorOf(Student $student): bool