DEV Community

Cover image for Arsitektur Offline-First untuk Pelaporan Progres Proyek Konstruksi Saat Sinyal Hilang
Mightyblue
Mightyblue

Posted on

Arsitektur Offline-First untuk Pelaporan Progres Proyek Konstruksi Saat Sinyal Hilang

Ada satu pola yang berulang di hampir setiap sistem lapangan yang saya audit: aplikasi pelaporan dibangun dengan asumsi koneksi selalu tersedia. Padahal survei APJII 2026 mencatat penetrasi internet Indonesia baru menyentuh 81,72 persen, dengan wilayah rural tertinggal di angka 78,18 persen. Statistik itu terdengar melegakan — sampai Anda berdiri di basement gedung yang sedang dikerjakan, atau di lantai lima struktur yang dindingnya belum terpasang. Sinyal hilang. Form gagal submit. Tiga jam pekerjaan menguap. Di titik inilah pelaporan progres proyek konstruksi offline berhenti menjadi fitur opsional dan mulai menjadi keputusan arsitektur.

Ini bukan sekadar keluhan praktisi. Sebuah studi yang terbit di jurnal Future Internet (MDPI) pada 2026 menguji runtime offline-first berbasis CRDT dan MQTT-SN di skenario logistik rural, dan hasilnya tegas: arsitektur cloud-centric hanya bertahan di kisaran 62–71 persen ketersediaan operasional saat koneksi terputus-putus, sementara pendekatan edge-centric mempertahankan 96–99 persen. Selisih itu bukan angka kosmetik — itu selisih antara laporan yang masuk dan laporan yang hilang. Saya mengangkat tema ini karena mayoritas tutorial yang beredar berhenti di "simpan ke local storage", lalu diam soal bagian tersulitnya: rekonsiliasi konflik.

Dan bagian tersulit itulah yang akan membuat sistem Anda dipercaya atau ditinggalkan.

Bukan UI-nya.

Bukan pilihan framework-nya.

Tapi apa yang terjadi ketika dua orang mengedit data yang sama, di dua lokasi berbeda, sama-sama dalam kondisi offline.

Kesimpulan yang akan Anda temukan di bawah: offline-first bukan soal menyimpan data di perangkat. Itu bagian yang mudah. Offline-first adalah soal memutuskan — di level desain, bukan di level bug fix — versi kebenaran mana yang menang ketika dua realitas bertabrakan. Sistem yang gagal hampir selalu gagal di keputusan ini, bukan di penyimpanannya.


1. Kenapa Sinyal Lokasi Proyek Selalu Diremehkan

Masalah konektivitas di proyek konstruksi punya karakter yang berbeda dari "internet lambat" biasa. Ini bukan soal bandwidth kecil, tapi soal ketidakpastian temporal: koneksi bisa hilang 30 detik, bisa 4 jam, dan tidak ada cara memprediksinya dari dalam aplikasi. Kebanyakan arsitektur yang gagal justru gagal karena memperlakukan dua kondisi itu sebagai satu masalah yang sama.

Realita Lapangan yang Tidak Pernah Muncul di Diagram Arsitektur

Diagram arsitektur selalu rapi. Lapangan tidak.

Struktur beton memblokir sinyal seluler jauh lebih agresif daripada dinding rumah. Basement dan area lift praktis adalah faraday cage. Pekerja berpindah antar zona setiap 20 menit. Perangkat yang dipakai bukan flagship — biasanya Android kelas menengah dengan RAM 4 GB dan penyimpanan yang hampir penuh.

Lalu ada faktor yang paling sering dilupakan: baterai. Sinkronisasi agresif yang terus-menerus melakukan polling akan menghabiskan daya sebelum jam makan siang, dan pengguna akan mematikan aplikasi Anda.

Biaya Tersembunyi dari Laporan yang Hilang

Kegagalan submit tidak berhenti di frustrasi pengguna. Efek berantainya nyata:

  • Audit trail bolong — pekerjaan tercatat selesai tanpa bukti waktu yang valid
  • Klaim progres tertunda — termin pembayaran mundur karena dokumentasi tidak lengkap
  • Duplikasi data — pengguna menekan tombol kirim berkali-kali, menghasilkan entri ganda
  • Kehilangan kepercayaan — sekali data hilang, tim kembali ke WhatsApp dan spreadsheet

Poin terakhir yang paling mahal. Sistem yang tidak dipercaya akan ditinggalkan, dan biaya migrasi kembali jauh lebih besar daripada biaya membangun sinkronisasi yang benar sejak awal.


2. Prinsip Inti: Perangkat Adalah Sumber Kebenaran

Pergeseran mental yang harus terjadi lebih dulu adalah ini: server berhenti menjadi otoritas tunggal dan berubah menjadi peer sinkronisasi. Perangkat lokal yang memegang kebenaran utama, minimal sampai rekonsiliasi terjadi. Tanpa pergeseran ini, setiap upaya membangun pelaporan progres proyek konstruksi offline hanya akan menghasilkan tambal-sulam di atas arsitektur yang asumsinya sudah salah sejak awal.

Local-First Bukan Sekadar Cache

Banyak tim mengira mereka sudah offline-first padahal hanya menerapkan caching. Bedanya fundamental.

Cache adalah salinan sementara dari kebenaran yang ada di server. Kalau cache dan server berbeda, server menang.

Local-first adalah kebalikannya. Data lokal punya legitimasi penuh. Perubahan tercatat sebagai operasi yang sah, bukan sebagai "draft yang menunggu persetujuan server".

Konsekuensinya: Anda tidak lagi bertanya "bagaimana cara sync ke server?" melainkan "bagaimana cara dua state yang sama-sama sah bisa konvergen?"

Membandingkan Strategi Penyimpanan dan Sinkronisasi

Pendekatan Sumber Kebenaran Ketersediaan Offline Kompleksitas Implementasi Cocok Untuk
Online-only + retry Server Nol Rendah Aplikasi admin di kantor
Cache read-only Server Baca saja Rendah Katalog, dokumen spek
Queue + Last-Write-Wins Server Penuh Sedang Laporan harian, checklist K3
Version vector Hybrid Penuh Sedang–tinggi Data dengan editor ganda
CRDT (delta-state) Perangkat Penuh Tinggi Kolaborasi konkuren, anotasi

Tabel ini penting karena satu kesalahan klasik adalah memilih CRDT untuk semuanya. CRDT itu elegan, tapi punya biaya: metadata membengkak, debugging jadi sulit, dan tim Anda harus benar-benar memahaminya. Untuk laporan harian yang hanya diisi satu mandor per zona, LWW sederhana sudah cukup dan jauh lebih mudah dirawat.


3. Menangani Konflik Data Tanpa Kehilangan Akal Sehat

Konflik terjadi ketika dua perangkat memodifikasi entitas yang sama sebelum sempat bertemu. Ini bukan kasus tepi — di proyek dengan shift yang tumpang tindih, ini kejadian mingguan. Strategi resolusinya harus dipilih per tipe data, bukan satu kebijakan global untuk seluruh aplikasi.

Kapan Last-Write-Wins Sudah Memadai

LWW bekerja baik jika data bersifat append atau kepemilikannya jelas.

Contoh: catatan cuaca harian, absensi, foto dokumentasi. Setiap entri berdiri sendiri. Tidak ada yang saling menimpa.

Syaratnya satu: jangan pernah gunakan jam perangkat sebagai penentu urutan. Jam ponsel di lapangan bisa meleset berjam-jam. Gunakan hybrid logical clock atau timestamp server yang diberikan saat sinkronisasi, dengan tie-breaker berupa device ID.

Kapan Anda Benar-Benar Butuh CRDT

CRDT masuk akal ketika beberapa orang mengedit objek yang sama secara konkuren dan semua perubahan harus dipertahankan.

Contoh konkret: daftar defect pada satu area. Mandor A menambah tiga item, QC B menghapus satu item lama, keduanya offline. Dengan LWW, salah satu pekerjaan hilang total. Dengan OR-Set (Observed-Remove Set), keduanya bertahan dan konvergen secara deterministik.

Struktur yang paling sering terpakai di konteks ini:

  • G-Counter — akumulasi monoton, misal jumlah unit terpasang
  • OR-Set — koleksi dengan penambahan dan penghapusan konkuren
  • LWW-Register — variabel status tunggal, misal status zona

Untuk pembahasan implementasi yang lebih teknis di sisi mobile, artikel Offline-First Mobile App Architecture: Syncing, Caching, and Conflict Resolution di DEV Community membedah pola Room + WorkManager yang relevan untuk kasus pengumpulan data lapangan.

Konflik Semantik yang Tidak Bisa Diselesaikan Mesin

Ini bagian yang jarang dibahas.

Ada konflik yang secara teknis bisa di-merge, tapi secara bisnis tidak boleh.

Mandor menandai zona "selesai". QC menandai zona yang sama "ditolak". CRDT akan dengan senang hati menyimpan keduanya. Tapi keduanya tidak boleh berlaku bersamaan.

Solusinya bukan algoritma, melainkan kebijakan domain: tetapkan hierarki otoritas (status QC mengalahkan status pelaksana), lalu tampilkan konflik secara eksplisit ke pengguna alih-alih menyembunyikannya. Penelitian Future Internet di atas menyebut pendekatan ini sebagai semantic reconciliation — rekonsiliasi yang memperhatikan makna, bukan sekadar data.


4. Foto Lapangan: Musuh Terbesar Sinkronisasi

Kalau ada satu komponen yang paling sering merusak sistem pelaporan lapangan, itu adalah foto. Ukurannya besar, jumlahnya banyak, dan pengguna tidak pernah mengambil hanya satu. Menangani foto dengan pipeline yang sama seperti data teks adalah resep kegagalan.

Kompresi, Antrean, dan Upload Berbasis Chunk

Prinsipnya: pisahkan metadata dari binary.

Kirim record laporan lebih dulu — ukurannya kecil, cepat, dan langsung memberi kepastian ke pengguna bahwa data mereka aman. Foto menyusul sebagai job terpisah dengan referensi ID.

Aturan praktis yang terbukti bekerja:

  1. Kompres di perangkat sebelum masuk antrean — target 1600px sisi terpanjang, WebP atau JPEG kualitas 75
  2. Simpan di penyimpanan aplikasi, bukan di memori
  3. Upload per potongan (chunked) supaya kegagalan di 80 persen tidak mengulang dari nol
  4. Terapkan exponential backoff dengan batas, jangan retry tak terbatas
  5. Batasi upload otomatis ke jaringan tak terukur jika pengguna mengaktifkan opsi hemat kuota

Metadata yang Wajib Ikut

Foto tanpa konteks tidak punya nilai audit. Sertakan minimal:

  • Timestamp perangkat dan timestamp saat diterima server
  • Koordinat GPS beserta nilai akurasinya
  • ID zona atau item pekerjaan
  • ID perangkat dan ID pengguna
  • Hash konten untuk deteksi duplikat

Hash terakhir itu menyelamatkan Anda dari masalah klasik: pengguna menekan kirim berkali-kali karena mengira gagal, lalu server menerima lima salinan foto yang sama.


5. Membangun Pelaporan Progres Proyek Konstruksi Offline dalam Tujuh Langkah

Bagian ini adalah kerangka implementasi yang bisa langsung Anda adaptasi. Urutannya disusun berdasarkan risiko: langkah awal menyelesaikan masalah yang paling sering menghancurkan sistem, langkah akhir menangani kasus yang lebih jarang tapi tetap perlu.

Urutan Implementasi

Langkah 1 — Petakan tipe data dan strategi konfliknya. Buat tabel: entitas, siapa yang boleh mengedit, apakah konkuren mungkin terjadi, strategi resolusi. Lakukan ini sebelum menulis kode apa pun.

Langkah 2 — Jadikan penyimpanan lokal sebagai sumber kebenaran. Gunakan SQLite (Room, Drift, atau WatermelonDB). Semua pembacaan UI berasal dari sini. Tidak ada pengecualian.

Langkah 3 — Bangun outbox pattern. Setiap mutasi menghasilkan record operasi di tabel antrean, lengkap dengan idempotency key. Ini yang membuat retry aman.

Langkah 4 — Terapkan sinkronisasi delta dua arah. Kirim hanya perubahan sejak checkpoint terakhir, terima hanya perubahan sejak cursor terakhir. Jangan pernah sinkronkan seluruh dataset.

Langkah 5 — Pisahkan pipeline media. Foto dan lampiran punya worker sendiri, prioritas lebih rendah, dan kebijakan jaringan tersendiri.

Langkah 6 — Tampilkan status sinkronisasi secara jujur. Tiga keadaan minimal: tersimpan lokal, sedang dikirim, terkonfirmasi server. Jangan menyembunyikan status. Kepercayaan pengguna dibangun dari transparansi.

Langkah 7 — Uji dengan gangguan jaringan yang realistis. Simulasikan putus 30 detik, 5 menit, dan 3 jam. Uji juga skenario aplikasi dibunuh sistem operasi di tengah upload.

Skema HowTo untuk Dokumentasi Anda

Jika Anda menulis ulang panduan ini di situs sendiri, sertakan structured data berikut agar mesin pencari dan mesin jawaban dapat memahami strukturnya:

{
  "@context": "https://schema.org",
  "@type": "HowTo",
  "name": "Membangun Pelaporan Progres Proyek Konstruksi Offline",
  "description": "Panduan implementasi arsitektur offline-first untuk aplikasi pelaporan lapangan di area dengan konektivitas tidak stabil.",
  "totalTime": "PT40H",
  "tool": [
    { "@type": "HowToTool", "name": "SQLite lokal (Room / Drift / WatermelonDB)" },
    { "@type": "HowToTool", "name": "Background job scheduler (WorkManager)" }
  ],
  "step": [
    {
      "@type": "HowToStep",
      "position": 1,
      "name": "Petakan tipe data dan strategi konflik",
      "text": "Klasifikasikan setiap entitas berdasarkan kemungkinan pengeditan konkuren, lalu tentukan strategi resolusi per tipe."
    },
    {
      "@type": "HowToStep",
      "position": 2,
      "name": "Jadikan penyimpanan lokal sebagai sumber kebenaran",
      "text": "Seluruh pembacaan antarmuka berasal dari basis data lokal, bukan dari respons jaringan."
    },
    {
      "@type": "HowToStep",
      "position": 3,
      "name": "Bangun outbox pattern",
      "text": "Catat setiap mutasi sebagai operasi antrean dengan idempotency key agar percobaan ulang aman."
    },
    {
      "@type": "HowToStep",
      "position": 4,
      "name": "Terapkan sinkronisasi delta dua arah",
      "text": "Pertukarkan hanya perubahan sejak checkpoint terakhir untuk menghemat bandwidth dan baterai."
    },
    {
      "@type": "HowToStep",
      "position": 5,
      "name": "Pisahkan pipeline media",
      "text": "Kelola unggahan foto pada worker terpisah dengan kompresi, chunking, dan backoff."
    },
    {
      "@type": "HowToStep",
      "position": 6,
      "name": "Tampilkan status sinkronisasi",
      "text": "Bedakan secara eksplisit antara tersimpan lokal, sedang dikirim, dan terkonfirmasi server."
    },
    {
      "@type": "HowToStep",
      "position": 7,
      "name": "Uji dengan gangguan jaringan realistis",
      "text": "Simulasikan pemutusan koneksi 30 detik hingga 3 jam serta terminasi aplikasi di tengah proses."
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

6. Lima Kesalahan yang Paling Sering Saya Temui

Sebagian besar kegagalan sistem lapangan bukan disebabkan oleh keputusan besar yang salah, melainkan oleh detail kecil yang diabaikan berulang kali. Berikut lima yang paling sering muncul dalam audit.

Daftar Kesalahannya

  • Mengandalkan jam perangkat untuk urutan kejadian. Jam ponsel lapangan sering meleset. Selalu pasangkan dengan logical clock.
  • Retry tanpa idempotency key. Hasilnya entri ganda yang mengacaukan laporan volume pekerjaan.
  • Menyinkronkan seluruh dataset setiap kali online. Boros kuota, boros baterai, dan lambat begitu data melewati beberapa ribu record.
  • Menyembunyikan kegagalan sinkronisasi. Pengguna yang tidak tahu datanya belum terkirim akan menyalahkan sistem saat data hilang.
  • Tidak pernah menguji skenario offline panjang. Tim menguji putus 10 detik, lalu produksi menghadapi putus 6 jam.

Kesalahan keempat menarik untuk dibahas. Banyak desainer menganggap indikator "belum tersinkron" membuat aplikasi terlihat tidak profesional, lalu menyembunyikannya. Padahal justru sebaliknya — pengguna lapangan sangat menghargai kejujuran sistem. Mereka terbiasa dengan kondisi tanpa sinyal. Yang mereka tidak tolerir adalah ketidakpastian.


7. Pertanyaan yang Sering Muncul

Beberapa pertanyaan berikut hampir selalu muncul saat saya mendiskusikan pendekatan ini dengan tim engineering maupun manajemen proyek.

Apakah PWA cukup, atau harus aplikasi native?

PWA dengan Service Worker dan IndexedDB memadai untuk formulir teks dan checklist sederhana. Begitu Anda butuh upload foto besar dalam antrean panjang, background sync yang andal saat aplikasi tertutup, serta akses penyimpanan yang stabil, aplikasi native atau Flutter memberi kontrol yang jauh lebih baik. Batasan background execution di iOS khususnya masih menjadi kendala nyata bagi PWA.

Berapa lama data boleh bertahan di perangkat sebelum tersinkron?

Tetapkan batas eksplisit sesuai kebutuhan audit — 72 jam adalah titik awal yang wajar. Lewat batas itu, tampilkan peringatan aktif kepada pengguna dan supervisor. Jangan biarkan data mengendap tanpa batas, karena semakin lama rentangnya, semakin besar kemungkinan konflik dan semakin sulit rekonsiliasinya.

Apakah pelaporan progres proyek konstruksi offline membutuhkan CRDT?

Tidak selalu, dan ini penting ditegaskan. Jika satu record hanya dimiliki satu peran dan pengeditan konkuren praktis tidak terjadi, kombinasi outbox pattern dan LWW dengan logical clock sudah memberi hasil yang solid. CRDT baru layak dipertimbangkan ketika kolaborasi konkuren atas objek yang sama menjadi kebutuhan nyata, bukan sekadar kemungkinan teoretis.

Bagaimana menangani perubahan skema database saat aplikasi offline berbulan-bulan?

Rancang migrasi yang bersifat additive — tambah kolom, jangan hapus atau ubah tipe. Sertakan nomor versi skema di setiap payload sinkronisasi, dan siapkan lapisan transformasi di sisi server untuk menerima payload versi lama. Perangkat yang lama tidak dibuka adalah realitas di proyek dengan pekerja rotasi.

Apa metrik yang harus dipantau setelah rilis?

Empat yang paling informatif: persentase operasi yang berhasil sinkron dalam 24 jam, median waktu antara pembuatan record dan konfirmasi server, jumlah konflik yang memerlukan intervensi manual, serta rasio kegagalan upload media. Metrik ketiga adalah alarm paling dini bahwa strategi resolusi Anda salah pilih.


Sinkronisasi Adalah Keputusan Arsitektur, Bukan Perbaikan Belakangan

Sebagai penutup, ada satu hal yang ingin saya tekankan dari seluruh pembahasan di atas: hampir setiap sistem lapangan yang gagal, gagal karena sinkronisasi diperlakukan sebagai pekerjaan tambahan di akhir sprint. Padahal keputusan tentang siapa yang memegang kebenaran, bagaimana konflik diselesaikan, dan apa yang dilihat pengguna saat data belum terkirim — semuanya adalah keputusan arsitektural yang harus diambil di hari pertama.

"Everything fails all the time."
— Werner Vogels

Werner Vogels adalah Chief Technology Officer Amazon dan salah satu figur paling berpengaruh dalam desain sistem terdistribusi modern. Tulisannya, Eventually Consistent, menjadi rujukan standar tentang bagaimana sistem berskala besar menerima ketidakkonsistenan sementara sebagai harga dari ketersediaan tinggi — gagasan yang persis menjadi fondasi arsitektur offline-first. Kalimatnya di atas terdengar pesimistis, tapi maksudnya justru sebaliknya: kegagalan bukan pengecualian yang perlu dicegah, melainkan kondisi normal yang harus diakomodasi sejak desain. Koneksi akan putus. Aplikasi akan dibunuh sistem operasi. Baterai akan habis di tengah upload. Sistem yang baik bukan yang mengandaikan hal-hal itu tidak terjadi, melainkan yang tetap benar ketika semuanya terjadi.

Pendekatan yang saya uraikan di sini lahir dari pekerjaan nyata bersama tim di lapangan, termasuk saat menangani kebutuhan dokumentasi progres untuk proyek industri yang dikerjakan kontraktor di kawasan Karawang — lokasi dengan kombinasi khas antara struktur beton tebal, area basement, dan tim yang berpindah zona sepanjang hari. Konteks seperti itu memaksa Anda jujur pada arsitektur: tidak ada ruang untuk asumsi bahwa koneksi akan selalu ada.

Jika Anda sedang membangun sistem serupa, saya ingin mendengar bagaimana tim Anda menangani konflik semantik — bagian yang menurut saya paling sedikit dibahas dan paling sering menimbulkan masalah. Tulis di kolom komentar.


Bacaan lanjutan:

  • Herrera dkk. (2026), CAMS F Edge DTN: Context-Aware Offline-First Synchronization and Local Reasoning Using CRDTs and MQTT-SN, Future Internet 18(4) — doi.org/10.3390/fi18040180
  • Survei Profil Internet Indonesia 2026 (APJII) — voi.id

Top comments (0)