Search by

bangsamu / master

BangsaMU

Clay menggunakan master

Package info

github.com/BangsaMU/master

pkg:composer/bangsamu/master

Statistics

Installs: 764

Dependents: 1

Suggesters: 0

Stars: 0

Open Issues: 0

v1.2.4 2026-09-14 06:52 UTC

This package is auto-updated.

Last update: 2026-09-14 06:53:04 UTC


README

Paket terpusat Master Data untuk ekosistem aplikasi berbasis Laravel.

Fitur Utama

  • Cakupan 15 Tabel Master Data:
    1. master_item_code (item_code)
    2. master_category (category_code)
    3. master_company (company_code)
    4. master_department (department_code)
    5. master_employee (no_ktp sebagai kode identitas utama unik)
    6. master_item_group (item_group_code)
    7. master_job_position (position_code)
    8. master_location (loc_code)
    9. master_pca (pca_code)
    10. master_project (project_code)
    11. master_project_detail (project_code_client)
    12. master_status (kode)
    13. master_uom (uom_code)
    14. master_vendor (vendor_code)
    15. master_vendor_contact (vendor_contact_name)
  • Real-Time WebSocket Broadcasting (Senada Reverb Hub): Setiap perubahan data master (created, updated, deleted) otomatis di-broadcast secara real-time ke channel masterdata.items dengan single unified event MasterDataUpdated (tanpa duplikasi notifikasi).
  • FCM-Like Catch-Up Sync (Tahan Offline/App Mati):
    • Jika aplikasi klien atau browser pengguna sempat offline atau server mati saat broadcast dikirimkan, klien tidak akan kehilangan data.
    • Checkpoint ID broadcast terakhir tersimpan aman di tabel dashboard_settings (key='last_synced_broadcast_id').
    • Paket secara otomatis melakukan validasi dan membuat tabel dashboard_settings jika belum ada di database lokal aplikasi.
    • Begitu koneksi WebSocket tersambung kembali, frontend secara otomatis memanggil /master-sync/catch-up untuk mengambil seluruh update yang terlewat.
    • Tersedia juga CLI command: php artisan master:catch-up.
  • Memory-Safe Data Cloning (MasterDataSyncService): Sinkronisasi data bertahap (chunking 250 rows) dengan MySQL upsert untuk menjaga tabel lokal tetap menjadi clone identik dari database master (db_master).
  • Whitelist Sinkronisasi & Penekanan Notifikasi (Notification Suppression):
    • Filter Tabel Lokal & Prefix master_*: Hanya tabel berawalan master_* yang benar-benar ada di database lokal aplikasi yang memenuhi syarat untuk disinkronkan. Tabel di luar database lokal atau tabel cadangan (*OLD, *dump*) otomatis diabaikan.
    • Penyimpanan di dashboard_settings:
      • key: sync_allowed_master_tables
      • group: senada_sync
      • type: json
      • label: Allowed Master Data Sync Tables
      • value: JSON array daftar tabel master_* yang diizinkan untuk disinkronkan (misal: ["master_category","master_company","master_department","master_employee","master_item_code", ...]).
      • options: JSON array seluruh tabel master_* yang terdeteksi di database lokal.
      • Auto-Discovery: Jika konfigurasi belum ada, sistem secara otomatis memindai database lokal dan menginisialisasi tabel-tabel master_* yang valid ke dashboard_settings.
    • Silent Ignore (Tanpa Popup Toast): Jika event broadcast diterima dari Senada untuk tabel yang tidak ada di database lokal klien atau tidak diaktifkan di dashboard_settings, klien mengabaikan event tersebut secara hening tanpa memunculkan popup toast notifikasi dan tanpa request fetch yang sia-sia karena tidak berdampak pada aplikasi klien.
    • Respon Backend Aman: Endpoint sinkronisasi mengembalikan 200 OK dengan flag skipped: true (bukan error 422).
  • Built-in Endpoints:
    • POST /master-sync/sync (Sinkronisasi universal semua master table)
    • POST /master-sync/sync-items (Alias kompatibel untuk item code)
    • GET|POST /master-sync/catch-up (Catch-up sync event yang terlewat)
    • GET /master-sync/allowed-tables (Daftar whitelist tabel yang diizinkan untuk disinkronkan)
    • POST /master-sync/channel-auth (Otorisasi channel privat browser)

Konfigurasi Database (config/database.php)

Pastikan koneksi db_master telah didaftarkan di aplikasi client:

'db_master' => [
    'driver' => 'mysql',
    'url' => env('DATABASE_URL_MASTER'),
    'host' => env('DB_HOST_MASTER', '192.168.20.187'),
    'port' => env('DB_PORT_MASTER', '3306'),
    'database' => env('DB_DATABASE_MASTER', 'master'),
    'username' => env('DB_USERNAME_MASTER', 'user'),
    'password' => env('DB_PASSWORD_MASTER', 'pass'),
    'charset' => 'utf8mb4',
    'collation' => 'utf8mb4_unicode_ci',
    'prefix' => '',
    'strict' => false,
],

Konfigurasi Lingkungan (.env)

# ==============================================================================
# SENADA REVERB WEBSOCKET & MASTER SYNC (SISI CLIENT)
# ==============================================================================
# Endpoint Senada Broadcast Hub
SENADA_URL=http://192.168.20.187:9029
SENADA_API_KEY=snd_masterdata_key_secret
SENADA_BROADCAST_ACTIVE=true

# Kredensial Reverb WebSocket (Wajib untuk otorisasi channel private)
REVERB_APP_ID=senada_app
REVERB_APP_KEY=senada_hub_key
REVERB_APP_SECRET=senada_hub_secret
REVERB_HOST="192.168.20.187"
REVERB_PORT=9029
REVERB_SCHEME=http

# ==============================================================================
# JADWAL OTOMATIS & DISTRIBUTED LOCK SINKRONISASI MASTER
# ==============================================================================
# Mengaktifkan/menonaktifkan auto-schedule catch-up di Laravel Scheduler (true/false)
MASTER_SYNC_SCHEDULE_ENABLED=true
# Frekuensi jadwal: hourly (default 1 jam), everyThirtyMinutes, everyTwoHours, daily, atau cron string "0 * * * *"
MASTER_SYNC_SCHEDULE_INTERVAL=hourly
# Maksimal jumlah event broadcast yang disinkronkan per siklus
MASTER_SYNC_SCHEDULE_LIMIT=50
# Durasi masa aktif Central Master Sync Lock (detik, default: 300 = 5 menit, maks 3600 = 1 jam)
MASTER_SYNC_LOCK_TTL=300
# Cooldown pencegah banjir sync saat user login / buka tab baru di browser (detik, default: 300 = 5 menit)
MASTER_SYNC_BROWSER_COOLDOWN=300

Cara Penggunaan di Aplikasi Client

1. Memasang Listener Real-time di View

Cukup tambahkan komponen Blade ini di layout utama aplikasi (seperti di layouts/app.blade.php atau components/layouts/app.blade.php):

<x-master::broadcast-listener />

Komponen ini akan secara otomatis:

  1. Menginisiasi koneksi ke Senada WebSocket Reverb.
  2. Saat koneksi terhubung (connected), otomatis memanggil catch-up ke Senada dengan proteksi Local Cooldown & Multi-Tab Debounce (localStorage), sehingga saat 50 user login bersamaan tidak terjadi banjir request ke database master.
  3. Berlangganan ke channel masterdata.items dan channel privat pengguna (private-user.{email}).
  4. Menampilkan toast notifikasi modern saat master data berubah atau saat catch-up selesai.
  5. Melakukan sinkronisasi database lokal ke db_master via endpoint bawaan paket /master-sync/sync.
  6. Merefresh DataTable aktif secara otomatis jika ada di halaman.
  7. Me-reload halaman jika pengguna sedang membuka formulir/detail dari item yang bersangkutan.

2. Penjadwalan Otomatis & Central Distributed Lock

A. Penjadwalan Otomatis (Auto-Scheduler)

Paket secara otomatis mendaftarkan task php artisan master:catch-up ke Laravel Scheduler tanpa perlu mengedit file app/Console/Kernel.php secara manual. Pastikan cron server aplikasi Anda sudah menjalankan scheduler standar Laravel:

* * * * * cd /path/to/app && php artisan schedule:run >> /dev/null 2>&1

Frekuensi eksekusi dapat diatur bebas via .env:

  • MASTER_SYNC_SCHEDULE_INTERVAL=hourly (Default: setiap 1 jam)
  • MASTER_SYNC_SCHEDULE_INTERVAL=everyThirtyMinutes (Setiap 30 menit)
  • MASTER_SYNC_SCHEDULE_INTERVAL=everyTwoHours (Setiap 2 jam)
  • MASTER_SYNC_SCHEDULE_INTERVAL="0 */4 * * *" (Custom cron: setiap 4 jam)

B. Central Distributed Lock (Perlindungan DB Master Lintas Aplikasi)

Untuk mencegah lonjakan koneksi dan perlambatan pada Database Master ketika banyak aplikasi (Clay, MCU, Warehouse, dll.) menjalankan sync secara bersamaan:

  1. Single-Sync Guarantee: Sebelum melakukan sinkronisasi dari db_master, aplikasi meminta Central Lock ke Senada Hub. Hanya 1 aplikasi yang diizinkan melakukan sinkronisasi dalam satu waktu.
  2. Auto-Postpone yang Ramah: Jika aplikasi lain sedang melakukan sinkronisasi, proses sync ditunda secara elegan tanpa membebani koneksi DB Master.
  3. Anti-Stuck & Auto-Expire: Lock memiliki TTL otomatis (default 5 menit / diset via MASTER_SYNC_LOCK_TTL). Jika aplikasi mati mendadak saat proses sync, lock otomatis kadaluarsa sehingga proses sync berikutnya tidak akan macet selamanya.
  4. Force Override: Tersedia opsi --force-lock untuk memecah lock yang dicurigai macet.

3. Perintah Artisan Catch-Up & Lock Management

A. Catch-Up Sync

# Sinkronkan semua broadcast yang terlewat (dilindungi Central Lock)
php artisan master:catch-up

# Cek ID checkpoint sinkronisasi saat ini
php artisan master:catch-up --info

# Paksa catch-up dan override lock jika lock terindikasi macet
php artisan master:catch-up --force-lock

# Jalankan dengan parameter checkpoint & limit tertentu
php artisan master:catch-up --since=80 --limit=50

B. Inspeksi & Rilis Central Lock (master:sync-lock)

# Cek apakah saat ini ada aplikasi yang sedang mengunci DB Master
php artisan master:sync-lock --status

# Paksa rilis lock yang macet di Senada Hub
php artisan master:sync-lock --release

# Manual lock untuk kebutuhan maintenance khusus
php artisan master:sync-lock --acquire --ttl=600

3. Memanggil Broadcast Secara Manual dari Kode

Setiap Model di bawah namespace Bangsamu\Master\Models\* sudah terpasang trait BroadcastsMasterChanges secara otomatis. Namun jika ingin memanggil secara manual:

use Bangsamu\Master\Services\MasterBroadcastService;

// Broadcast perubahan entitas master apapun
$broadcastService = app(MasterBroadcastService::class);
$broadcastService->broadcastTableChange('master_category', $categoryModel, 'updated');

4. Memanggil Sinkronisasi Manual dari Kode

use Bangsamu\Master\Services\MasterDataSyncService;

$syncService = app(MasterDataSyncService::class);

// 1. Sinkronkan tabel tertentu berdasarkan ID
$result = $syncService->syncTable('master_employee', 12, 450, 'updated');

// 2. Jalankan Catch-Up event terlewat
$catchUpResult = $syncService->catchUpMissedBroadcasts();

5. Optimasi Bulk Import (10.000+ Data) & Single Summary Broadcast

Untuk mencegah Broadcast Storm (di mana pengunggahan 10.000 data memicu 10.000 panggilan HTTP ke Senada, menyebabkan HTTP 429 Rate Limit dan browser freeze):

  1. Suppression Selama Proses Import: Semua per-row broadcast dinonaktifkan sementara via MasterBroadcastService::withoutBroadcasting(...) dan event hook BeforeImport.
  2. 1 Kali Ringkasan Broadcast di Akhir Batch: Setelah seluruh sheet dan chunk selesai dibaca, dikirimkan 1 kali ringkasan event MasterDataUpdated ke Senada:
    {
        "table": "master_item_code",
        "action": "created",
        "id": 26500,
        "max_id": 26500,
        "batch_count": 10000,
        "is_batch": true,
        "identifier": "Batch Import (10.000 data)",
        "item_code": "Batch Import (10.000 data)"
    }
  3. Cloning Otomatis Sisi Klien: Aplikasi klien yang menerima event ini mendeteksi bahwa max_id master (misal: 26.500) melompat melampaui max_id lokal (misal: 16.500). Klien otomatis mengeksekusi syncRange() dengan batch 250 record secara langsung dari db_master via MySQL upsert.
  4. Trait HandlesBatchImportBroadcast: Semua class Import (Item Code, Category, Department, Employee, Item Group, Location, PCA, Project, UoM, Vendor) mengimplementasikan trait HandlesBatchImportBroadcast serta WithChunkReading (chunk 1.000) dan koleksi lookup in-memory (memoized) untuk menghindari N+1 kueri ke database master.