Dokumentasi Database
ERD, kamus data, dan langkah inisialisasi database eSchool
Dokumentasi ini menjelaskan struktur database eSchool. Database memakai MySQL dengan framework Laravel (Eloquent).
Kamus data lengkap seluruh tabel tenant ada di Kamus Data (192 tabel, 1762 kolom).
1. Gambaran database
eSchool memakai dua koneksi Laravel:
| Koneksi | Jenis | Isi |
|---|---|---|
mysql | Central | Data sekolah, paket, langganan, user super admin |
school | Tenant | Data akademik satu sekolah. Berpindah database sesuai sekolah aktif |
Nama database per environment:
| Aplikasi | Environment | Central | Tenant |
|---|---|---|---|
| API-Sekolah | Development | eschool-central | eschool_school |
| API-Sekolah | Staging | eschool-central-staging | eschool_school_staging |
| API-Sekolah | Production | eschool-central-prod | eschool_school_prod |
| Superadmin | Tiap server | eschool-central | database per sekolah (contoh: eschool-87-smkn100malang) |
Cara tenant dipilih dijelaskan di Multi-Tenant.
Isi database tenant
Database tenant dibaca dari dump sekolah eschool-87-smkn100malang (MariaDB 10.11, 192 tabel). Ringkasan per kelompok:
| Kelompok | Jumlah tabel | Contoh tabel |
|---|---|---|
| Pengguna dan akses | 15 | users, students, staffs, guardian_details |
| Sekolah, paket, dan langganan | 25 | schools, school_settings, system_settings, edu_level |
| Akademik dan kelas | 26 | session_years, semesters, grade_level, classes |
| Absensi | 9 | attendances, attendance_days, attendance_points, absensi_settings |
| Ujian dan nilai | 16 | exams, exam_marks, exam_results, exam_timetables |
| Tugas dan komunikasi | 11 | assignments, assignment_submissions, accepted_file, attachments |
| Keuangan | 19 | fees, fees_class, fees_paids, fees_types |
| Cuti dan pelanggaran | 7 | leaves, leave_details, leave_masters, student_violations |
| Ekstrakurikuler | 4 | estrakulikulers, eskul_details, eskul_absensis, eskul_timetables |
| Aset dan sarana | 9 | assets, asset_categories, asset_disposals, asset_items |
| Dokumen departemen | 42 | folder_bendahara, folder_humas, folder_kesiswaan, folder_kpk |
| Sistem Laravel | 9 | migrations, failed_jobs, form_fields, kpks |
Selain data akademik, database tenant juga berisi tabel schools, packages, features, subscriptions, dan tabel langganan lainnya. 85 tabel punya kolom school_id dengan foreign key ke schools.id (sekolah ini school_id = 87). Jadi di tenant, schools adalah baris data sekolah itu sendiri, bukan sekadar referensi ke central.
2. Entity Relationship Diagram (ERD)
ERD berikut dibuat dari foreign key di database tenant, hanya untuk tabel inti. Garis school_id ke schools tidak digambar karena hampir semua tabel memilikinya. Untuk relasi tabel lain, lihat baris Relasi di tiap tabel pada Kamus Data.
model_has_roles bersifat polymorphic: model_type + model_id menunjuk ke user dan tidak punya foreign key ke users. Nilai model_type harus konsisten antara web (TenantUser) dan API (App\\Models\\User\\User). Pada dump sekolah 87, nilai yang tersimpan adalah App\\Models\\User (1491 baris) dan App\\Models\\TenantUser (150 baris). Tidak ada App\\Models\\User\\User.
Kolom student_id tidak konsisten antar tabel. Menunjuk ke users.id: 12 tabel, termasuk attendances, exam_results, dan subject_attendance_students. Menunjuk ke students.id: eskul_details, original_classes, payment_history, recap_absensi, xendit_invoices. Tanpa foreign key: fees_paids, optional_fees, student_violations. Cek dulu tabelnya sebelum melakukan join.
3. Kamus Data (Data Dictionary)
Berikut tabel inti yang paling sering disentuh saat development. Seluruh tabel ada di Kamus Data.
Tabel: roles
Menyimpan daftar role. Role bawaan: School Admin, Teacher, Student, Guardian. Role tambahan per sekolah (Kesiswaan, Bendahara, Kepsek) punya custom_role = 1. Pada sekolah 87 semua role memakai guard web.
| Nama Kolom | Tipe Data | Atribut | Keterangan |
|---|---|---|---|
id | BIGINT UNSIGNED | PK, Auto Increment, Not Null | |
name | VARCHAR(191) | Unique (name+guard_name+school_id), Not Null | |
guard_name | VARCHAR(191) | Unique (name+guard_name+school_id), Not Null | |
school_id | BIGINT UNSIGNED | FK (schools.id), Unique (name+guard_name+school_id), Nullable | |
custom_role | TINYINT(1) | Not Null, Default 1 | |
editable | TINYINT(1) | Not Null, Default 1 | |
created_at | TIMESTAMP | Nullable | |
updated_at | TIMESTAMP | Nullable |
Tabel: permissions
Menyimpan daftar permission yang dipakai untuk membatasi menu dan aksi.
| Nama Kolom | Tipe Data | Atribut | Keterangan |
|---|---|---|---|
id | BIGINT UNSIGNED | PK, Auto Increment, Not Null | |
name | VARCHAR(191) | Unique (name+guard_name), Not Null | |
guard_name | VARCHAR(191) | Unique (name+guard_name), Not Null | |
created_at | TIMESTAMP | Nullable | |
updated_at | TIMESTAMP | Nullable |
Tabel: role_has_permissions
Tabel penghubung role dan permission.
| Nama Kolom | Tipe Data | Atribut | Keterangan |
|---|---|---|---|
permission_id | BIGINT UNSIGNED | PK (gabungan), FK (permissions.id), Not Null | |
role_id | BIGINT UNSIGNED | PK (gabungan), FK (roles.id), Not Null |
Tabel: model_has_roles
Menghubungkan role ke user (polymorphic). Di database tenant, tabel ini menentukan role user di sekolah tersebut.
| Nama Kolom | Tipe Data | Atribut | Keterangan |
|---|---|---|---|
role_id | BIGINT UNSIGNED | PK (gabungan), FK (roles.id), Not Null | |
model_type | VARCHAR(191) | PK (gabungan), Not Null | |
model_id | BIGINT UNSIGNED | PK (gabungan), Not Null |
Tabel: users
Akun semua pengguna sekolah (guru, siswa, wali, staff).
| Nama Kolom | Tipe Data | Atribut | Keterangan |
|---|---|---|---|
id | BIGINT UNSIGNED | PK, Auto Increment, Not Null | |
nip | VARCHAR(20) | Unique, Nullable | |
first_name | VARCHAR(128) | Not Null | |
last_name | VARCHAR(128) | Nullable | |
mobile | VARCHAR(191) | Nullable | |
phone | VARCHAR(20) | Nullable | |
email | VARCHAR(191) | Not Null | |
password | VARCHAR(191) | Not Null | |
gender | VARCHAR(16) | Nullable | |
image | VARCHAR(512) | Nullable | |
dob | DATE | Nullable | |
current_address | VARCHAR(191) | Nullable | |
permanent_address | VARCHAR(191) | Nullable | |
occupation | VARCHAR(128) | Nullable | |
status | TINYINT | Not Null, Default 1 | |
reset_request | TINYINT | Not Null, Default 0 | |
fcm_id | VARCHAR(1024) | Nullable | |
school_id | BIGINT UNSIGNED | FK (schools.id), Nullable | |
language | VARCHAR(191) | Not Null, Default en | |
remember_token | VARCHAR(100) | Nullable | |
email_verified_at | TIMESTAMP | Nullable | |
created_at | TIMESTAMP | Nullable | |
updated_at | TIMESTAMP | Nullable | |
deleted_at | TIMESTAMP | Nullable |
Tabel: students
Relasi ke user lewat students.user_id, bukan students.id.
| Nama Kolom | Tipe Data | Atribut | Keterangan |
|---|---|---|---|
id | BIGINT UNSIGNED | PK, Auto Increment, Not Null | |
user_id | BIGINT UNSIGNED | FK (users.id), Not Null | |
class_id | BIGINT UNSIGNED | FK (classes.id), Nullable | |
class_section_id | BIGINT UNSIGNED | FK (class_sections.id), Nullable | |
billing_disabled | TINYINT(1) | Not Null, Default 0 | |
billing_disabled_at | TIMESTAMP | Nullable | |
billing_disabled_reason | TEXT | Nullable | |
original_class_section_id | BIGINT UNSIGNED | FK (class_sections.id), Nullable | |
grade_level_id | BIGINT UNSIGNED | FK (grade_level.id), Nullable | |
application_type | VARCHAR(191) | Nullable, Default offline | |
admission_no | VARCHAR(512) | Not Null | |
nisn | VARCHAR(20) | Nullable | |
nis | VARCHAR(20) | Nullable | |
roll_number | INT | Nullable | |
admission_date | DATE | Not Null | |
school_id | BIGINT UNSIGNED | FK (schools.id), Not Null | |
application_status | INT | Nullable, Default 1 | 1- accepted, 0- rejected |
guardian_id | BIGINT UNSIGNED | FK (users.id), Not Null | |
session_year_id | BIGINT UNSIGNED | FK (session_years.id), Not Null | |
created_at | TIMESTAMP | Nullable | |
updated_at | TIMESTAMP | Nullable | |
deleted_at | TIMESTAMP | Nullable |
Tabel: staffs
Data staff (TU, Bendahara, Humas, dan lainnya). Kolom salary bertipe DOUBLE, bukan DECIMAL.
| Nama Kolom | Tipe Data | Atribut | Keterangan |
|---|---|---|---|
id | BIGINT UNSIGNED | PK, Auto Increment, Not Null | |
user_id | BIGINT UNSIGNED | FK (users.id), Not Null | |
qualification | VARCHAR(512) | Nullable | |
salary | DOUBLE | Not Null, Default 0 | |
joining_date | DATE | Nullable | |
created_at | TIMESTAMP | Nullable | |
updated_at | TIMESTAMP | Nullable |
Tabel: guardian_details
Data wali. Terhubung ke users lewat user_id.
| Nama Kolom | Tipe Data | Atribut | Keterangan |
|---|---|---|---|
id | BIGINT UNSIGNED | PK, Auto Increment, Not Null | |
user_id | BIGINT UNSIGNED | FK (users.id), Not Null | |
nama_wali | VARCHAR(191) | Not Null | |
tahun_lahir_wali | VARCHAR(191) | Not Null | |
jenjang_pendidikan_wali | VARCHAR(191) | Not Null | |
pekerjaan_wali | VARCHAR(191) | Not Null | |
penghasilan_wali | VARCHAR(191) | Not Null | |
NIK_wali | VARCHAR(191) | Not Null | |
created_at | TIMESTAMP | Nullable | |
updated_at | TIMESTAMP | Nullable |
Tabel: subject_teachers
Penugasan guru ke mata pelajaran dan kelas. teacher_id menunjuk ke users.id.
| Nama Kolom | Tipe Data | Atribut | Keterangan |
|---|---|---|---|
id | BIGINT UNSIGNED | PK, Auto Increment, Not Null | |
class_section_id | BIGINT UNSIGNED | FK (class_sections.id), Not Null | |
subject_id | BIGINT UNSIGNED | FK (subjects.id), Not Null | |
teacher_id | BIGINT UNSIGNED | FK (users.id), Not Null | user_id |
class_subject_id | BIGINT UNSIGNED | FK (class_subjects.id), Not Null | |
school_id | BIGINT UNSIGNED | FK (schools.id), Not Null | |
created_at | TIMESTAMP | Nullable | |
updated_at | TIMESTAMP | Nullable | |
deleted_at | TIMESTAMP | Nullable |
Di dump tidak ada tabel user_relation. Relasi wali dan siswa tersimpan lewat students.guardian_id (FK ke users.id) dan guardian_details.user_id. Jika user_relation masih dipakai di kode, kemungkinan tabelnya hanya ada di database central.
4. Generate otomatis dari database
Script scripts/generate-kamus-data.mjs membaca information_schema dan menulis halaman kamus-data.mdx berisi:
- ERD Mermaid dari foreign key yang ada di database,
- tabel kamus data tiap tabel (tipe, atribut PK/FK/Unique/Not Null/Default, dan keterangan dari
COLUMN_COMMENT).
Halaman Kamus Data saat ini dibuat dari dump database tenant sekolah 87, dengan format yang sama. Jalankan ulang script di bawah setelah skema berubah.
Atur koneksi lewat environment variable
export DB_HOST=127.0.0.1 DB_PORT=3306
export DB_USER=root DB_PASSWORD=
export DB_NAME=eschool_schoolJalankan script
npm run docs:dbRapikan hasilnya
Buka content/docs/kamus-data.mdx, lalu isi kolom Keterangan yang masih kosong. Dari 1762 kolom, baru 113 yang punya COMMENT di database. Supaya keterangan otomatis terisi di generate berikutnya, tambahkan ->comment('...') di migration.
Jalankan hanya di database development. Jangan taruh kredensial production di terminal atau di repository.
Mengisi keterangan langsung dari migration:
$table->string('nis')->unique()->comment('Nomor induk siswa');
$table->foreignId('user_id')->comment('FK ke users.id');5. Langkah inisialisasi database
Menggunakan migrasi dan seeder (Laravel)
# buat tabel database central
php artisan migrate
# isi data awal
php artisan db:seedUntuk database tenant, jalankan migration dengan koneksi school:
php artisan migrate --database=school --path=database/migrations/tenantSesuaikan path migration tenant dengan struktur project yang sebenarnya.
Menggunakan file SQL (dump)
# membuat dump
mysqldump -u root -p eschool_school > database/schema.sql
# import
mysql -u root -p eschool_school < database/schema.sqlDump database sekolah berisi data pribadi (siswa, wali, akun pengguna). Jangan commit dump berdata ke repository. Untuk dokumentasi atau repo, buat dump struktur saja dengan mysqldump --no-data.
6. Aturan dan konvensi
- Nama tabel
snake_case, bentuk jamak. - Semua perubahan skema lewat migration.
- Jangan buat foreign key lintas database (central ke tenant). Jaga integritasnya di level aplikasi.
- Saat menghapus siswa permanen, hapus juga baris
model_has_rolesterkait agar angka dashboard tidak membengkak. - Saat memakai
upsert(), isicreated_atdanupdated_at. - Tambahkan
->comment()pada kolom di migration supaya kamus data bisa terisi otomatis. - Tabel
password_resetstidak punya primary key. Jangan andalkanidpada tabel ini.