Initial commit - lms-v2 + CLAUDE.md

This commit is contained in:
Iwit
2026-05-30 22:15:16 +07:00
commit 5811409e2d
183 changed files with 23225 additions and 0 deletions
+28
View File
@@ -0,0 +1,28 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Department extends Model
{
protected $fillable = ['name', 'code'];
// public function users(): HasMany
// {
// return $this->hasMany(User::class);
// }
// Relasi ke Posisi (dari tabel class_sections lama)
public function positions()
{
return $this->belongsToMany(Position::class, 'department_position');
}
// Relasi ke Karyawan (Users) untuk menghitung total karyawan di departemen ini
public function users()
{
return $this->hasMany(User::class, 'department_id');
}
}
+21
View File
@@ -0,0 +1,21 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Exam extends Model
{
protected $fillable = [
'old_id',
'title',
'duration',
'passing_percentage'
];
public function results(): HasMany
{
return $this->hasMany(ExamResult::class);
}
}
+32
View File
@@ -0,0 +1,32 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class ExamResult extends Model
{
protected $fillable = [
'user_id',
'exam_id',
'is_attempted',
'score',
'is_passed'
];
protected $casts = [
'is_attempted' => 'boolean',
'is_passed' => 'boolean',
];
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function exam(): BelongsTo
{
return $this->belongsTo(Exam::class);
}
}
+21
View File
@@ -0,0 +1,21 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Position extends Model
{
protected $fillable = ['name'];
public function users()
{
return $this->hasMany(User::class, 'position_id');
}
public function departments()
{
return $this->belongsToMany(Department::class, 'department_position');
}
}
+23
View File
@@ -0,0 +1,23 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Question extends Model
{
// Pastikan ini sesuai dengan nama tabel Anda di database (misalnya 'questions')
protected $table = 'questions';
// Sesuaikan array ini dengan nama kolom yang ada di database Anda
protected $fillable = [
'question_text',
'category',
'type',
'answer_a',
'answer_b',
'answer_c',
'answer_d',
'correct_answer'
];
}
+65
View File
@@ -0,0 +1,65 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class QuestionBank extends Model
{
// Opsional, tapi sangat disarankan agar Laravel tidak salah menebak nama tabel
protected $table = 'question_banks';
protected $fillable = [
// Atribut Soal dari desain Anda
'old_id',
'subject',
'question_type',
'question_level',
'passing_grade',
'duration',
'question_text',
'option_a',
'option_b',
'option_c',
'option_d',
'option_e',
'correct_answer',
// PENTING: Atribut Relasi yang dibutuhkan form Create/Edit & Filter Index
'department_id',
'position_id',
'training_matrix_id',
'created_by'
];
protected $casts = [
'correct_answer' => 'array', // Otomatis ubah JSON di database jadi Array di PHP
];
/*
|--------------------------------------------------------------------------
| RELASI DATABASE (Diperlukan agar Filter Dropdown & Tabel berfungsi)
|--------------------------------------------------------------------------
*/
public function department()
{
return $this->belongsTo(Department::class, 'department_id');
}
public function position()
{
return $this->belongsTo(Position::class, 'position_id');
}
public function matrix()
{
return $this->belongsTo(TrainingMatrix::class, 'training_matrix_id');
}
public function creator()
{
// Merujuk ke tabel users untuk mengetahui siapa staff/admin yang buat soal
return $this->belongsTo(User::class, 'created_by');
}
}
+15
View File
@@ -0,0 +1,15 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Role extends Model
{
protected $fillable = ['name'];
public function users()
{
return $this->belongsToMany(User::class);
}
}
+48
View File
@@ -0,0 +1,48 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
// 1. Baris Spatie di-comment/dihapus
// use Spatie\Activitylog\Traits\LogsActivity;
// use Spatie\Activitylog\LogOptions;
class Sop extends Model
{
// 2. Trait LogsActivity di-comment/dihapus
// use LogsActivity;
protected $table = 'sops';
protected $fillable = [
'title',
'sop_code',
'category_name',
'version',
'revision_history',
'status'
];
protected $casts = [
'revision_history' => 'array',
];
// 3. Fungsi getActivitylogOptions di-comment/dihapus
/*
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults()
->logFillable()
->logOnlyDirty()
->dontSubmitEmptyLogs()
->setDescriptionForEvent(fn(string $eventName) => "SOP {$eventName}");
}
*/
public function trainingMatrices(): HasMany
{
return $this->hasMany(TrainingMatrix::class, 'sop_id');
}
}
+32
View File
@@ -0,0 +1,32 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class TrainingMatrix extends Model
{
protected $table = 'training_matrices';
protected $fillable = [
'department_id',
'position_id',
'sop_id'
];
public function department(): BelongsTo
{
return $this->belongsTo(Department::class);
}
public function position(): BelongsTo
{
return $this->belongsTo(Position::class);
}
public function sop(): BelongsTo
{
return $this->belongsTo(Sop::class);
}
}
+83
View File
@@ -0,0 +1,83 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
use HasFactory, Notifiable, HasRoles;
/**
* The attributes that are mass assignable.
* Kolom-kolom ini wajib didaftarkan agar form Create & Edit tidak diblokir Laravel.
*/
protected $fillable = [
'nik',
'identity_number',
'initial',
'first_name',
'last_name',
'phone',
'email',
'password',
'role',
'gender',
'date_of_birth',
'join_date',
'photo',
'department_id',
'position_id',
'training_matrix_id',
'old_id',
'old_password_hash',
'is_active',
];
/**
* The attributes that should be hidden for serialization.
*/
protected $hidden = [
'password',
'remember_token',
'old_password_hash',
];
/**
* Mengubah format string dari database menjadi format Date/Time Carbon otomatis.
*/
protected $casts = [
'email_verified_at' => 'datetime',
'password' => 'hashed',
'date_of_birth' => 'date',
'join_date' => 'date',
'is_active' => 'boolean',
];
// =========================================================================
// RELASI ANTAR TABEL (MASTER DATA)
// =========================================================================
// Relasi ke tabel departments
public function department()
{
return $this->belongsTo(Department::class, 'department_id');
}
// Relasi ke tabel positions
public function position()
{
return $this->belongsTo(Position::class, 'position_id');
}
// Jika model TrainingMatrix sudah Anda buat, buka komentar di bawah ini:
/*
public function trainingMatrix()
{
return $this->belongsTo(TrainingMatrix::class);
}
*/
}
+21
View File
@@ -0,0 +1,21 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class UserDocument extends Model
{
protected $fillable = [
'user_id',
'document_name',
'file_path',
'file_type'
];
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
}