Sistem ini adalah aplikasi web untuk menjejak jangka hayat mesin dan status kesihatan berdasarkan tarikh pembelian dan rekod penyelenggaraan. Ia menggunakan Supabase sebagai pangkalan data backend dan boleh di-embed dalam laman web WordPress.
Sistem ini terdiri daripada 3 komponen utama:
Widget utama untuk pengurusan penuh mesin dan penyelenggaraan.
Widget khusus untuk memaparkan status kesihatan satu mesin sahaja (untuk halaman individu).
Menggunakan 3 jadual utama: users, machines, maintenances
- Jangka hayat asas: Setiap mesin bermula dengan 100% dan menurun secara linear ke 0% dalam 10 tahun (3,650 hari)
- Formula linear:
Peratus = 100% - (Hari Berlalu / 3650 hari Γ 100%)
Penyelenggaraan menambah jangka hayat mesin:
| Jenis Penyelenggaraan | Peningkatan Peratus | Bersamaan Hari Ditambah |
|---|---|---|
| Kendiri (Self maintenance) | +0.001% | ~0.365 hari (~9 jam) |
| Major (Professional service) | +0.01% | ~3.65 hari (~88 jam) |
Kesan penyelenggaraan tidak segera penuh, tetapi meningkat secara beransur-ansur menggunakan ease-in-out sine curve selama 6 bulan:
``` Progress = min(1, (BulanSelepas + 1) / 6) Factor = -(cos(Ο Γ Progress) - 1) / 2 KesampaianSebenar = AsasPeratus + (BoostPenyelenggaraan Γ Factor) ```
Contoh Praktik:
- Bulan 1 selepas major service: +~0.001% (10% daripada +0.01%)
- Bulan 3 selepas major service: +~0.005% (50% daripada +0.01%)
- Bulan 6 selepas major service: +0.01% (100% penuh)
Status kesihatan dikira berdasarkan 2 faktor:
``` JangkaHayatSemasa = PeratusAsas + Ξ£(KesampaianPenyelenggaraan) ```
``` BulanSejakPenyelenggaraan = (TarikhHariIni - TarikhPenyelenggaraanTerakhir) dalam bulan ```
| Status | Kriteria | Warna | Tindakan |
|---|---|---|---|
| Baik | Jangka hayat > 60% DAN penyelenggaraan dalam 1 bulan terakhir | π’ Hijau | Tiada tindakan |
| Sederhana (Perlu Perhatian) | Jangka hayat 40-60% ATAU penyelenggaraan 1-12 bulan lepas | π‘ Kuning | Rancang penyelenggaraan |
| Buruk (Perlu Penyelenggaraan) | Jangka hayat < 40% DAN tiada penyelenggaraan 12+ bulan | π΄ Merah | Tindakan segera! |
Pseudocode: ``` if (jangkaHayat > 60% AND bulanSejakPenyelenggaraan <= 1): status = "Baik" else if (jangkaHayat > 40% OR bulanSejakPenyelenggaraan <= 12): status = "Sederhana" else: status = "Buruk" ```
Diuruskan oleh Supabase Auth secara automatik.
| Kolum | Jenis | Keterangan |
|---|---|---|
id |
UUID | Primary key (auto) |
email |
TEXT | Email pengguna |
created_at |
TIMESTAMPTZ | Tarikh daftar |
Menyimpan maklumat mesin.
| Kolum | Jenis | Keterangan | Contoh |
|---|---|---|---|
id |
UUID | Primary key (auto) | a1b2c3d4-... |
user_id |
UUID | Foreign key ke auth.users |
e5f6g7h8-... |
machine_id |
TEXT | ID unik mesin (ditentukan pengguna) | "SMAW-001" |
name |
TEXT | Nama mesin | "SMAW 1" |
purchase_date |
DATE | Tarikh pembelian | 2020-03-15 |
created_at |
TIMESTAMPTZ | Tarikh dicipta dalam sistem | 2025-01-07T10:30:00Z |
updated_at |
TIMESTAMPTZ | Tarikh dikemaskini | 2025-01-07T10:30:00Z |
Constraints:
UNIQUE(user_id, machine_id)β Seorang pengguna tidak boleh ada 2 mesin dengan ID yang sama- Row Level Security (RLS) aktif β Pengguna hanya boleh akses mesin sendiri
Menyimpan rekod penyelenggaraan.
| Kolum | Jenis | Keterangan | Contoh |
|---|---|---|---|
id |
UUID | Primary key (auto) | j9k0l1m2-... |
user_id |
UUID | Foreign key ke auth.users |
e5f6g7h8-... |
machine_id |
UUID | Foreign key ke machines |
a1b2c3d4-... |
maintenance_date |
DATE | Tarikh penyelenggaraan dilakukan | 2024-06-20 |
maintainer_name |
TEXT | Nama orang yang menyelenggara | "Ahmad bin Ali" |
maintainer_role |
TEXT | Peranan penyelenggara | "Student" / "Staff" / "Technician" |
maintenance_type |
TEXT | Jenis penyelenggaraan | "kendiri" / "major" |
notes |
TEXT | Nota tambahan (optional) | "Tukar bearing motor" |
created_at |
TIMESTAMPTZ | Tarikh dicipta | 2024-06-20T14:20:00Z |
Constraints:
- Row Level Security (RLS) aktif β Pengguna hanya boleh akses maintenance records sendiri
``` βββββββββββββββββββ β Pengguna Buka β β Widget β ββββββββββ¬βββββββββ β βΌ βββββββββββββββββββ ββββββββββββββββββββ β Check Auth ββNOβββΆβ Tunjuk Skrin β β (Supabase) β β Login/Register β ββββββββββ¬βββββββββ ββββββββββ¬ββββββββββ β β β YES β βΌ βΌ βββββββββββββββββββ ββββββββββββββββββββ β Load User's ββββββββ User Login/ β β Machines β β Register β βββββββββββββββββββ ββββββββββββββββββββ ```
Input:
- Email pengguna
- Password (minimum 6 characters)
- Username (optional, untuk display)
Output:
- Pengguna berjaya log masuk
- Session token disimpan dalam browser
- Redirect ke skrin utama aplikasi
Error Handling:
- Email sudah wujud β Guna log masuk
- Email belum verified β Tunjuk mesej "Check email untuk verification"
- Password salah β Tunjuk error message
``` βββββββββββββββββββ β User Isi Form: β β - Nama Mesin β β - ID Mesin β β - Tarikh Beli β ββββββββββ¬βββββββββ β βΌ βββββββββββββββββββ β Click "Tambah/ β β Simpan Mesin" β ββββββββββ¬βββββββββ β βΌ βββββββββββββββββββββββββββββββ β Supabase INSERT/UPSERT β β ke jadual 'machines' β β ON CONFLICT (user_id, β β machine_id) DO UPDATE β ββββββββββ¬βββββββββββββββββββββ β βΌ βββββββββββββββββββ ββββββββββββββββββββ β Success? ββNOβββΆβ Tunjuk Error β ββββββββββ¬βββββββββ ββββββββββββββββββββ β YES βΌ βββββββββββββββββββ β Refresh List β β Mesin & Auto β β Select Mesin β β Baru β βββββββββββββββββββ ```
Input:
name(TEXT): Nama mesin, contoh "SMAW 1", "CMM"machine_id(TEXT): ID unik, contoh "SMAW-001"purchase_date(DATE): Tarikh pembelian dalam format YYYY-MM-DD
Output:
- Mesin baru disimpan ke database
- Mesin muncul dalam dropdown "Mesin Sedia Ada"
- Chart kosong ditunjukkan (tiada penyelenggaraan lagi)
Validasi:
- Semua field wajib diisi
machine_idmesti unik untuk user tersebut (enforced by database)
``` βββββββββββββββββββ β User Pilih β β Mesin dari β β Dropdown β ββββββββββ¬βββββββββ β βΌ βββββββββββββββββββ β Load Machine β β Details dari DB β ββββββββββ¬βββββββββ β βΌ ββββββββββββββββββββββββββββ β Load Maintenance Records β β untuk mesin tersebut β ββββββββββ¬ββββββββββββββββββ β βΌ ββββββββββββββββββββββββββββ β Kira Jangka Hayat: β β 1. Baseline (linear) β β 2. Boost (maintenance) β β 3. Smooth over 6 months β ββββββββββ¬ββββββββββββββββββ β βΌ ββββββββββββββββββββββββββββ β Kira Status Kesihatan: β β - Check peratus jangka β β - Check last maintenance β ββββββββββ¬ββββββββββββββββββ β βΌ ββββββββββββββββββββββββββββ β Render Chart.js Graph β β & Info Panel β ββββββββββββββββββββββββββββ ```
Input:
machine_id(UUID) mesin yang dipilih
Output: ```javascript { // Maklumat Mesin machineName: "SMAW 1", machineID: "SMAW-001", purchaseDate: "2020-03-15",
// Kiraan Jangka Hayat baselineLifetimeToday: 45.67, // % (linear tanpa maintenance) adjustedLifetimeToday: 52.34, // % (dengan maintenance) baselineEOL: "2030-03-15", // Tarikh tamat hayat asas adjustedEOL: "2031-01-20", // Tarikh tamat hayat selepas maintenance
// Status Kesihatan healthStatus: "Sederhana (Perlu Perhatian)", // "Baik" / "Sederhana" / "Buruk" healthStatusClass: "health-sederhana", // CSS class untuk styling
// Maintenance Info lastMaintenanceDate: "2024-11-15", totalMaintenanceRecords: 12, monthsSinceLastMaintenance: 2 } ```
Visual Output:
- Chart Graf: Garis biru (adjusted lifetime) vs garis putus-putus kelabu (baseline)
- Card Status: Kotak berwarna menunjukkan status kesihatan
- Info Panel: Details tarikh beli, jangka hayat semasa, dll.
``` βββββββββββββββββββ β User Isi Form: β β - Tarikh β β - Nama β β - Role β β - Jenis β β - Nota β ββββββββββ¬βββββββββ β βΌ βββββββββββββββββββ β Validasi: β β - Tarikh < beli?β β - Field kosong? β ββββββββββ¬βββββββββ β Valid βΌ βββββββββββββββββββββββββββββββ β Supabase INSERT ke jadual β β 'maintenances' β ββββββββββ¬βββββββββββββββββββββ β βΌ βββββββββββββββββββ β Auto Refresh: β β - Reload logs β β - Recalculate β β jangka hayat β β - Update chart β βββββββββββββββββββ ```
Input: ```javascript { machine_id: "a1b2c3d4-...", // UUID (auto dari selected machine) user_id: "e5f6g7h8-...", // UUID (auto dari logged user) maintenance_date: "2024-12-05", // DATE maintainer_name: "Ahmad bin Ali", // TEXT maintainer_role: "Student", // "Student" | "Staff" | "Technician" maintenance_type: "kendiri", // "kendiri" | "major" notes: "Tukar oil & bersih filter" // TEXT (optional) } ```
Output:
- Rekod disimpan ke database
- Log baru muncul dalam "Sejarah Penyelenggaraan"
- Chart dikemaskini dengan marker baru (bulatan hijau untuk kendiri, triangle merah untuk major)
- Jangka hayat mesin meningkat sesuai dengan jenis penyelenggaraan
- Status kesihatan mungkin berubah ke "Baik" jika memenuhi kriteria
Validasi:
maintenance_datetidak boleh sebelumpurchase_datemesinmaintainer_namewajib diisi- Tarikh tidak boleh masa depan (optional check)
``` βββββββββββββββββββββββββββββββ β User Embed Widget di β β WordPress Page dengan: β β window.MACHINE_NAME="SMAW 1"β ββββββββββ¬βββββββββββββββββββββ β βΌ βββββββββββββββββββββββββββββββ β Widget Load & Detect β β Machine Name dari Variable β ββββββββββ¬βββββββββββββββββββββ β βΌ βββββββββββββββββββββββββββββββ β Query Supabase: β β SELECT * FROM machines β β WHERE name ILIKE 'SMAW 1' β ββββββββββ¬βββββββββββββββββββββ β βΌ ββββββββββββββββ ββββββββββββββββββββ β Machine ββNOβββΆβ Tunjuk "Data β β Wujud? β β Belum β ββββββββββ¬ββββββ β Dikemaskini" β β YES ββββββββββββββββββββ βΌ βββββββββββββββββββββββββββββββ β Load Maintenance Records β ββββββββββ¬βββββββββββββββββββββ β βΌ βββββββββββββββββββββββββββββββ β Kira Status Kesihatan β β (Sama seperti Flow 3) β ββββββββββ¬βββββββββββββββββββββ β βΌ βββββββββββββββββββββββββββββββ β Render Status Card: β β - Status (Baik/Sederhana/ β β Buruk) β β - ID Mesin β β - Tarikh Beli β β - Jangka Hayat % β β - Last Maintenance β βββββββββββββββββββββββββββββββ ```
Input:
window.MACHINE_NAME(STRING): Nama mesin yang ditetapkan dalam WordPress
Output (Contoh untuk SMAW 1): ```html
Cara Guna di WordPress:
- Tambah Custom HTML Block
- Copy kod dari
machine-health-status-widget.html - Tambah di atas kod:
<script>window.MACHINE_NAME = "SMAW 1";</script> - Publish
Kelebihan:
- Ringan (no login required)
- Auto-update bila data berubah
- Boleh embed di mana-mana page (SMAW 1 page, SMAW 2 page, dll)
``` βββββββββββββββββββ β User Click β β "Generate Dummy"β ββββββββββ¬βββββββββ β βΌ βββββββββββββββββββββββββββββββ β Generate Monthly 'kendiri' β β + Semiannual 'major' dari β β purchase date β today β ββββββββββ¬βββββββββββββββββββββ β βΌ βββββββββββββββββββββββββββββββ β Bulk INSERT ke 'maintenances'β ββββββββββ¬βββββββββββββββββββββ β βΌ βββββββββββββββββββββββββββββββ β Auto refresh chart & logs β βββββββββββββββββββββββββββββββ ```
Tujuan: Untuk testing atau populate data lama secara cepat
Output:
- Rekod bulanan
kendiri(setiap bulan) - Rekod
majorsetiap 6 bulan - Data dari tarikh beli hingga hari ini
```sql -- Users can only see their own machines CREATE POLICY "Users can view their own machines" ON machines FOR SELECT USING (auth.uid() = user_id);
-- Users can only insert/update/delete their own machines CREATE POLICY "Users can insert their own machines" ON machines FOR INSERT WITH CHECK (auth.uid() = user_id); ```
```sql -- Users can only see maintenance records for their machines CREATE POLICY "Users can view their own maintenance records" ON maintenances FOR SELECT USING (auth.uid() = user_id); ```
Implikasi:
- User A tidak boleh lihat mesin User B
- Semua query automatik filtered by
user_id - Widget health status (public) masih boleh access kerana ia query by
name(bukan protected by RLS jika mesin set sebagai public β currently setup untuk private only)
-
Buat project baru di supabase.com
-
Run semua SQL scripts dalam folder
/scripts:001_create_users_table.sql002_create_machines_table.sql003_create_maintenances_table.sql004_create_profile_trigger.sql
-
Dapatkan credentials:
SUPABASE_URLdari Settings β APISUPABASE_ANON_KEYdari Settings β API
Replace dalam kedua-dua file machine-lifetime-widget.html dan machine-health-status-widget.html:
```javascript const SUPABASE_URL = 'YOUR_SUPABASE_URL'; const SUPABASE_ANON_KEY = 'YOUR_ANON_KEY'; ```
- Edit halaman WordPress
- Tambah block "Custom HTML"
- Copy & paste semua kod dari
machine-lifetime-widget.html - Publish
- Edit halaman mesin (contoh: "SMAW 1" page)
- Tambah block "Custom HTML"
- Tambah di atas sekali: ```html <script>window.MACHINE_NAME = "SMAW 1";</script> ```
- Copy & paste kod dari
machine-health-status-widget.html - Publish
Edit dalam <style> section:
```css .health-baik { background-color: #dcfce7; /* Hijau muda / color: #166534; / Hijau gelap */ }
.health-sederhana { background-color: #fefce8; /* Kuning muda / color: #854d0e; / Kuning gelap */ }
.health-buruk { background-color: #FFF2F2; /* Merah muda / color: #E22627; / Merah */ } ```
Edit dalam JavaScript function showMachineInfo():
```javascript // Semasa: if (adjustedNow > 60 && monthsSinceLastMaint <= 1) { healthStatus = 'Baik'; }
// Contoh perubahan: Longgarkan syarat "Baik" if (adjustedNow > 50 && monthsSinceLastMaint <= 3) { healthStatus = 'Baik'; } ```
Edit nilai dalam JavaScript:
```javascript // Semasa: const EFFECTS = { kendiri: 0.001, major: 0.01 };
// Contoh: Tingkatkan kesan maintenance const EFFECTS = { kendiri: 0.005, major: 0.05 }; ```
Sebab: Database tables belum dicipta
Penyelesaian: Run semua SQL scripts dalam folder /scripts
Sebab: Supabase Auth wajibkan email verification
Penyelesaian:
- Check inbox/spam untuk email dari Supabase
- Click link verify
- Log masuk semula
Sebab: Nama mesin dalam window.MACHINE_NAME tidak match dengan database
Penyelesaian:
- Check spelling β case-sensitive! ("SMAW 1" β "smaw 1")
- Pastikan mesin sudah didaftar dalam widget utama
- Check browser console untuk error messages
Sebab: Chart.js library tidak load
Penyelesaian: Pastikan line ini ada sebelum </script>:
```html
```
Untuk bantuan lanjut:
- Check browser console (F12) untuk error messages
- Verify Supabase credentials betul
- Pastikan semua SQL scripts sudah run
- Check RLS policies aktif di Supabase dashboard
- β Authentication dengan Supabase Auth
- β Machine management (add, view, update)
- β Maintenance logging
- β Linear baseline + smooth maintenance effects
- β Health status calculation
- β Chart visualization
- β Standalone health status widget
- β WordPress embeddable
- β Row Level Security (RLS)
Dicipta untuk Penjejakan Jangka Hayat Mesin Industri
Menggunakan: Next.js, Supabase, Chart.js, WordPress Integration