Inventory PWA — Offline-First
Staf gudang kehilangan sinyal, dan itu kondisi normal—bukan kasus tepi. Saya membangun aplikasi inventory yang tetap dapat digunakan tanpa jaringan, dengan ledger append-only agar perubahan stok dapat disinkronkan tanpa konflik.
Aplikasi inventory berbasis Progressive Web App yang tetap dapat digunakan saat perangkat kehilangan koneksi. Sistem digunakan oleh Owner, Admin, dan staf gudang untuk mencatat stok masuk, stok keluar, dan mutasi barang, termasuk melalui pemindaian QR.
Studi Kasus
- Peran
- Full Stack Developer · Freelance
- Durasi
- 2 Minggu
- Ukuran tim
- 1 orang
Overview
Kondisi gudang tidak selalu menyediakan koneksi yang stabil. Dinding beton, rak logam, dan area yang jauh dari access point dapat membuat perangkat kehilangan jaringan ketika proses pencatatan sedang berlangsung.
Karena pencatatan stok tidak boleh berhenti hanya karena koneksi terputus, aplikasi dirancang sebagai offline-first sejak awal, bukan sebagai aplikasi online yang kemudian diberi cache.
Masalah
Masalah utamanya bukan sekadar bagaimana menyimpan data ketika perangkat offline, tetapi bagaimana memastikan perubahan tersebut tetap benar ketika perangkat kembali online.
Beberapa perangkat dapat melakukan perubahan terhadap barang yang sama ketika tidak terhubung ke server. Pendekatan sinkronisasi record biasa kemudian membutuhkan mekanisme conflict resolution untuk menentukan perubahan mana yang harus dianggap benar.
Untuk data inventory, keputusan tersebut berisiko karena konflik yang salah dapat menghasilkan saldo stok yang tidak sesuai dengan transaksi sebenarnya.
Solusi
Saya menggunakan pendekatan append-only ledger untuk mencatat setiap mutasi stok. Transaksi tidak mengubah record sebelumnya, tetapi selalu ditambahkan sebagai event baru. Saldo dapat dihitung berdasarkan rangkaian mutasi tersebut sehingga tidak ada record yang harus ditimpa ketika perangkat melakukan sinkronisasi.
Data produk disimpan secara lokal menggunakan IndexedDB melalui Dexie, sehingga pencarian, pemindaian QR, dan pencatatan transaksi dapat dilakukan tanpa menunggu server.
Transaksi yang dibuat ketika offline masuk ke antrean sinkronisasi dan dikirim otomatis ketika koneksi kembali tersedia. Status sinkronisasi juga ditampilkan kepada pengguna sehingga mereka dapat mengetahui apakah transaksi masih menunggu atau sudah berhasil dikirim.
Untuk menjaga akurasi data, pembacaan data inventory dari API menggunakan network-only, sedangkan aset dan data yang aman untuk disimpan sementara menggunakan caching. Dengan demikian, aplikasi tetap responsif tanpa menjadikan saldo stok yang sudah lama sebagai sumber kebenaran.
Arsitektur
Aplikasi menggunakan REST API sebagai penghubung antara frontend dan backend. Data yang diperlukan untuk penggunaan offline disimpan secara lokal melalui IndexedDB, sementara Service Worker dan Workbox menangani caching serta background synchronization.
Owner dan Admin dipisahkan menjadi dua SPA agar masing-masing hanya membawa fitur dan bundle yang diperlukan oleh perannya. QR digunakan untuk identifikasi produk sehingga staf dapat melakukan pencatatan tanpa memasukkan SKU secara manual
Hasil
15.003 SKU berhasil di-cache dalam sekitar 4,5 detik. 15 transaksi offline berhasil disinkronkan dalam sekitar 313 ms pada pengujian. Tidak ditemukan duplikasi transaksi selama pengujian sinkronisasi. Aplikasi tetap dapat digunakan untuk pencatatan ketika perangkat kehilangan koneksi. Sinkronisasi berjalan otomatis ketika koneksi kembali tersedia.
Pelajaran
Pelajaran terbesar dari project ini adalah bahwa beberapa masalah lebih baik dihilangkan melalui desain daripada diselesaikan setelah masalah muncul. Saya sempat mempertimbangkan mekanisme conflict resolution untuk record yang berubah secara offline, tetapi setiap aturan "siapa yang menang" selalu memiliki kasus yang dapat menghasilkan keputusan yang salah. Dengan append-only ledger, kelas konflik tersebut tidak perlu terjadi karena transaksi tidak saling menimpa.
Saya juga belajar bahwa offline dan offline-first bukan sekadar perbedaan caching. Offline-first berarti jaringan diperlakukan sebagai sesuatu yang dapat hilang kapan saja, sehingga penyimpanan lokal, sinkronisasi, pembacaan data, dan pengalaman pengguna harus dirancang dengan asumsi tersebut sejak awal.