# Revisi Implementasi Decision Tree untuk Penomoran Surat Otomatis ## 1. Latar Belakang Sistem penomoran surat otomatis saat ini masih menggunakan increment sederhana (`nomor_terakhir + 1`). Untuk meningkatkan akurasi dan memberikan kontribusi akademik yang lebih berbobot, Node 3 (penentuan nomor urut) akan menggunakan **Full Decision Tree (scikit-learn)** dengan multi-feature, bukan counter biasa. ## 2. Ruang Lingkup Perubahan | Area | File | Perubahan | |------|------|-----------| | **eLaDesSkripsiML** | `ml_model.py` | Rombak: tambah DecisionTreeClassifier + fitur multi untuk DecisionTreeRegressor | | | `elades_mysql.py` | Tambah auto-klasifikasi, kode surat, counter dengan FOR UPDATE, orchestrator | | | `app.py` | Update endpoint `/api/proses-nomor/`, tambah `/api/retrain` | | **eLaDesSkripsi** | 3 Migration baru | Tambah kolom ke jenis_surat, pengajuan, dan tabel nomor_surat_counters | ## 3. Decision Tree Flow ``` Root: jenis_surat_id tersedia? ├── Tidak → Error return └── Ya → Fetch jenis_surat dari MySQL │ ├── Node 1: KLASIFIKASI SURAT │ ├── Cek jenis_surat.kategori │ │ ├── Ada → gunakan itu │ │ └── Tidak → Python keyword matching: │ │ ├── "pernyataan" → "Surat Pernyataan" │ │ ├── "pengantar" → "Surat Pengantar" │ │ ├── "keterangan" → "Surat Keterangan" │ │ └── default → "Surat Keterangan" │ └── Output: klasifikasi_surat │ ├── Node 2: KODE SURAT │ ├── jenis_surat.kode_surat ada? │ │ ├── Ya → gunakan kode_surat │ │ └── Tidak → default: │ │ ├── Surat Keterangan → "SK" │ │ ├── Surat Pengantar → "SP" │ │ └── Surat Pernyataan → "SPT" │ └── Output: kode_surat │ ├── Node 3: FULL DECISION TREE — NOMOR URUT │ ├── Tentukan periode: │ │ ├── reset_periode = "bulanan" → filter (jenis, klasifikasi, BULAN, TAHUN) │ │ └── reset_periode = "tahunan" → filter (jenis, klasifikasi, TAHUN) │ ├── Ambil existing numbers (FOR UPDATE lock) │ ├── Cek gap: ada nomor yang loncat? │ │ ├── Ya → pakai nomor gap pertama (isi celah) │ │ └── Tidak → Full Decision Tree prediction │ ├── Siapkan fitur training multi-dimensi │ ├── Train DecisionTreeRegressor │ ├── Predict nomor berikutnya │ ├── Validasi: cek duplikat via FOR UPDATE │ └── Output: nomor_urut │ ├── Node 4: FORMAT NOMOR SURAT │ ├── format_nomor dari jenis_surat │ ├── Replace: {NO_URUT} {KODE} {BULAN_ROM} {TAHUN} │ └── Output: nomor_terformat │ └── SAVE: UPDATE pengajuan ├── nomor_surat = nomor_urut ├── klasifikasi_surat = hasil Node 1 ├── kode_surat = hasil Node 2 └── tanggal_surat = NOW() ``` ## 4. Fitur Multi-Dimensi untuk DecisionTreeRegressor | Fitur | Keterangan | |-------|------------| | `bulan` | Bulan pengajuan (1-12) | | `tahun` | Tahun pengajuan | | `index_ke` | Urutan ke berapa dalam sequence | | `jumlah_dalam_periode` | Total surat dalam periode yang sama | | `selisih_hari` | Selisih hari dari pengajuan sebelumnya | ## 5. Endpoint API | Endpoint | Method | Fungsi | |----------|--------|--------| | `/api/proses-nomor/` | POST | Decision Tree lengkap: klasifikasi + kode + nomor urut + format | | `/api/retrain` | POST | Retrain model setelah ada jenis_surat baru | | `/api/health` | GET | Cek kesehatan server | ## 6. Output Response ```json { "success": true, "nomor_surat": "001/SKD/VI/2026", "nomor_urut": 1, "klasifikasi_surat": "Surat Keterangan", "kode_surat": "SKD", "message": "Nomor surat berhasil diproses" } ```