Alur kerja berorientasi dokumen dijelaskan dengan model data praktis dan pola UI untuk versi, pratinjau, metadata, dan status yang jelas.

Sebuah aplikasi disebut berorientasi dokumen ketika dokumen itu sendiri adalah produk yang dibuat, ditinjau, dan diandalkan pengguna. Pengalaman dibangun di sekitar file seperti PDF, gambar, scan, dan struk, bukan di sekitar form di mana file hanyalah lampiran.
Dalam alur kerja berorientasi dokumen, orang melakukan pekerjaan nyata di dalam dokumen: mereka membukanya, memeriksa apa yang berubah, menambahkan konteks, dan memutuskan langkah berikutnya. Jika dokumen tidak bisa dipercaya, aplikasi berhenti berguna.
Kebanyakan aplikasi berorientasi dokumen membutuhkan beberapa layar inti di awal:
Masalah muncul cepat. Pengguna mengupload struk yang sama dua kali. Seseorang mengedit PDF dan mengupload ulang tanpa menjelaskan alasan. Scan tidak punya tanggal, vendor, atau pemilik. Minggu kemudian, tak ada yang tahu versi mana yang disetujui atau alasan keputusannya.
Aplikasi berorientasi dokumen yang baik terasa cepat dan dapat diandalkan. Pengguna seharusnya bisa menjawab pertanyaan ini dalam beberapa detik:
Kejelasan itu datang dari definisi. Sebelum membangun layar, putuskan apa arti “versi”, “pratinjau”, “metadata”, dan “status” di aplikasi Anda. Jika istilah itu kabur, Anda akan mendapat duplikat, riwayat yang membingungkan, dan alur review yang tidak sesuai pekerjaan nyata.
UI sering terlihat sederhana (daftar, viewer, beberapa tombol), tetapi model data yang memegang beban. Jika objek inti tepat, riwayat audit, pratinjau cepat, dan persetujuan yang dapat diandalkan jadi lebih mudah.
Mulailah dengan memisahkan “record dokumen” dari “konten file.” Record adalah apa yang dibicarakan pengguna (Invoice dari ACME, struk taksi). Konten adalah byte (PDF, JPG) yang mungkin diganti, diproses ulang, atau dipindahkan tanpa mengubah apa arti dokumen di dalam aplikasi.
Sekumpulan objek praktis untuk dimodelkan:
Tentukan apa yang mendapat ID yang tak berubah. Aturan berguna: Document ID hidup selamanya, sementara File dan Pratinjau dapat digenerasi ulang. Versi juga perlu ID stabil, karena orang merujuk ke “bagaimana tampilannya kemarin” dan Anda butuh jejak audit.
Modelkan relasi secara eksplisit. Sebuah Document punya banyak Versi. Setiap Versi bisa punya beberapa Pratinjau (ukuran atau format berbeda). Ini menjaga layar daftar tetap cepat karena bisa memuat data pratinjau ringan, sementara layar detail memuat file penuh hanya saat diperlukan.
Contoh: pengguna mengupload foto struk yang kusut. Anda membuat Document, menyimpan File asli, menghasilkan Thumbnail Pratinjau, dan membuat Versi 1. Kemudian pengguna mengupload scan lebih jelas. Itu menjadi Versi 2, tanpa merusak komentar, persetujuan, atau pencarian yang terkait Document.
Orang mengharapkan dokumen berubah dari waktu ke waktu tanpa “berubah menjadi” item lain. Cara paling sederhana untuk mewujudkan itu adalah memisahkan identitas (Document) dari konten (Versi dan File).
Mulailah dengan document_id yang stabil dan tak berubah. Bahkan jika pengguna mengupload ulang PDF yang sama, mengganti foto buram, atau mengupload scan yang diperbaiki, itu harus tetap record dokumen yang sama. Komentar, penugasan, dan log audit menempel rapi pada satu ID yang tahan lama.
Anggap setiap perubahan bermakna sebagai baris version. Setiap versi harus merekam siapa yang membuatnya dan kapan, plus pointer penyimpanan (file key, checksum, size, jumlah halaman) dan artefak turunan (teks OCR, gambar pratinjau) yang terkait dengan file itu persis. Hindari “mengedit langsung.” Itu terlihat lebih sederhana pada awalnya, tetapi merusak keterlacakan dan membuat bug sulit dibalik.
Untuk bacaan cepat, simpan current_version_id di dokumen. Sebagian besar layar hanya butuh “yang terbaru,” jadi Anda tidak harus mengurutkan versi di setiap pemuatan. Saat perlu riwayat, muat versi secara terpisah dan tampilkan timeline bersih.
Rollback hanyalah perubahan pointer. Daripada menghapus apa pun, set current_version_id kembali ke versi lama. Ini cepat, aman, dan menjaga jejak audit tetap utuh.
Untuk menjaga riwayat dapat dipahami, catat mengapa setiap versi ada. Field kecil dan konsisten reason (plus catatan opsional) mencegah timeline penuh pembaruan misterius. Alasan umum: penggantian upload, pembersihan scan, koreksi OCR, redaksi, dan edit persetujuan.
Contoh: tim keuangan mengupload foto struk, menggantinya dengan scan lebih jelas, lalu memperbaiki OCR agar total terbaca. Setiap langkah adalah versi baru, tetapi dokumen tetap satu item di inbox. Jika perbaikan OCR salah, rollback satu klik karena Anda hanya mengganti current_version_id.
Dalam alur kerja berorientasi dokumen, pratinjau sering kali adalah hal utama yang diinteraksikan pengguna. Jika pratinjau lambat atau tidak stabil, seluruh aplikasi terasa rusak.
Perlakukan pembuatan pratinjau sebagai job terpisah, bukan sesuatu yang menunggu layar upload. Simpan file asli dulu, kembalikan kendali ke pengguna, lalu buat pratinjau di background. Ini menjaga UI responsif dan membuat retry aman.
Simpan beberapa ukuran pratinjau. Satu ukuran tidak pernah cocok untuk semua layar: thumbnail kecil untuk daftar, gambar menengah untuk tampilan terpisah, dan gambar halaman penuh untuk review detail (per-halaman untuk PDF).
Lacak state pratinjau secara eksplisit sehingga UI selalu tahu apa yang ditampilkan: pending, ready, failed, dan needs_retry. Gunakan label ramah pengguna di UI, tetapi simpan state yang jelas di data.
Agar rendering cepat, cache nilai turunan pada record pratinjau alih-alih menghitung ulang setiap kali dilihat. Field umum termasuk jumlah halaman, lebar dan tinggi pratinjau, rotasi (0/90/180/270), dan opsional “halaman terbaik untuk thumbnail.”
Rancang untuk file lambat dan berantakan. PDF scan 200 halaman atau foto struk yang kusut bisa butuh waktu untuk diproses. Gunakan pemuatan progresif: tampilkan halaman pertama yang siap segera setelah tersedia, lalu isi sisanya.
Contoh: pengguna mengupload 30 foto struk. Tampilan daftar menunjukkan thumbnail sebagai “pending,” lalu setiap kartu berubah menjadi “ready” saat pratinjau selesai. Jika beberapa gagal karena gambar korup, mereka tetap terlihat dengan aksi retry jelas daripada menghilang atau memblokir seluruh batch.
Metadata mengubah tumpukan file menjadi sesuatu yang bisa dicari, diurutkan, ditinjau, dan disetujui. Ini membantu orang menjawab pertanyaan sederhana dengan cepat: Apa dokumen ini? Dari siapa? Valid? Apa yang harus terjadi selanjutnya?
Cara praktis menjaga metadata bersih adalah memisahkannya berdasarkan asalnya:
Bucket ini mencegah argumen kemudian. Jika jumlah total salah, Anda bisa melihat apakah itu berasal dari OCR atau edit manusia.
Untuk struk dan faktur, set kecil field yang konsisten sangat berguna (nama, format yang sama). Field jangkar umum: vendor, tanggal, total, mata uang, dan document_number. Biarkan mereka opsional dulu. Orang mengupload scan parsial dan foto buram, dan memblokir progress karena satu field hilang akan memperlambat alur kerja.
Perlakukan nilai yang tidak diketahui sebagai kelas utama. Gunakan state eksplisit seperti null/unknown, plus alasan bila berguna (halaman hilang, tidak terbaca, tidak berlaku). Itu memungkinkan dokumen bergerak maju sambil tetap menunjukkan kepada reviewer apa yang perlu perhatian.
Juga simpan provenance dan confidence untuk field yang diekstrak. Sumber bisa user, OCR, import, atau API. Confidence bisa skor 0–1 atau set kecil seperti high/medium/low. Jika OCR membaca “$18.70” dengan confidence rendah karena digit terakhir buram, UI bisa menandainya dan meminta konfirmasi cepat.
Dokumen multi-halaman memerlukan keputusan ekstra: apa yang berlaku untuk seluruh dokumen vs satu halaman. Total dan vendor biasanya milik dokumen. Catatan per-halaman, redaksi, rotasi, dan klasifikasi per-halaman seringkali disimpan di level halaman.
Status menjawab satu pertanyaan: “Di mana dokumen ini dalam proses?” Jaga sesedikit dan seinformatif mungkin. Jika Anda menambah status baru setiap kali seseorang minta, akhirnya Anda punya filter yang tak dipercaya siapa pun.
Set status bisnis praktis yang memetakan ke keputusan nyata:
Jaga “processing” di luar status bisnis. OCR berjalan dan pratinjau dibuat menggambarkan apa yang sistem lakukan, bukan apa yang orang harus lakukan selanjutnya. Simpan itu sebagai state pemrosesan terpisah.
Juga pisahkan penugasan dari status (assignee_id, team_id, due_date). Dokumen bisa Approved tapi tetap ditugaskan untuk tindak lanjut, atau Needs review tanpa pemilik.
Catat riwayat status, bukan hanya nilai saat ini. Log sederhana seperti (from_status, to_status, changed_at, changed_by, reason) sangat berguna saat seseorang bertanya, “Siapa yang menolak struk ini dan mengapa?”
Terakhir, tentukan aksi yang diperbolehkan di tiap status. Buat aturan sederhana: Imported bisa pindah ke Needs review; Approved read-only kecuali versi baru dibuat; Rejected bisa dibuka kembali tapi harus menyimpan alasan sebelumnya.
Sebagian besar waktu dihabiskan untuk memindai daftar, membuka satu item, memperbaiki beberapa field, lalu lanjut. UI yang baik membuat langkah-langkah itu cepat dan dapat diprediksi.
Untuk daftar dokumen, perlakukan setiap baris seperti ringkasan sehingga pengguna bisa memutuskan tanpa membuka tiap file. Baris kuat menampilkan thumbnail kecil, judul jelas, beberapa field kunci (merchant, tanggal, total), badge status, dan peringatan halus saat sesuatu butuh perhatian.
Pertahankan tampilan detail tetap tenang dan mudah dipindai. Tata umum: pratinjau di kiri dan metadata di kanan, dengan kontrol edit di samping tiap field. Pengguna harus bisa zoom, rotasi, dan mengganti halaman tanpa kehilangan posisinya di form. Jika field diekstrak dari OCR, tampilkan petunjuk confidence kecil, dan idealnya sorot area sumber di preview saat field difokuskan.
Versi bekerja paling baik sebagai timeline, bukan dropdown. Tampilkan siapa mengubah apa dan kapan, dan biarkan pengguna membuka versi lama dalam mode read-only. Jika Anda menawarkan perbandingan, fokus pada perbedaan metadata (jumlah berubah, vendor dikoreksi) daripada memaksakan perbandingan pixel demi pixel PDF.
Mode review harus mengoptimalkan kecepatan. Alur triase berbasis keyboard sering cukup: aksi cepat setujui/tolak, perbaikan cepat untuk field umum, dan kotak komentar singkat untuk penolakan.
Empty state penting karena dokumen sering dalam proses. Alih-alih kotak kosong, jelaskan apa yang terjadi: “Pratinjau sedang dibuat,” “OCR berjalan,” atau “Tipe file ini belum punya pratinjau.”
Alur sederhana terasa seperti “upload, cek, setujui.” Di balik layar, bekerja paling baik saat Anda memisahkan file itu sendiri (versi dan pratinjau) dari makna bisnis (metadata dan status).
Pengguna mengupload PDF, foto, atau scan struk dan langsung melihatnya di daftar inbox. Jangan tunggu pemrosesan selesai. Tampilkan nama file, waktu upload, dan badge jelas seperti “Processing.” Jika Anda sudah tahu sumbernya (email import, kamera mobile, drag-and-drop), tampilkan juga.
Saat upload, buat record Document (entitas jangka panjang) dan record Version (file spesifik ini). Set current_version_id ke versi baru. Simpan preview_state = pending dan extraction_state = pending sehingga UI bisa jujur tentang apa yang siap.
Tampilan detail harus terbuka segera, tetapi tampilkan viewer placeholder dan pesan jelas “Mempersiapkan pratinjau” alih-alih frame rusak.
Job background membuat thumbnail dan pratinjau yang dapat dilihat (gambar halaman untuk PDF, gambar yang diubah ukurannya untuk foto). Job lain mengekstrak metadata (merchant, tanggal, total, mata uang, tipe dokumen). Saat tiap job selesai, perbarui hanya state dan timestamp-nya supaya Anda bisa retry kegagalan tanpa menyentuh semuanya.
Jaga UI ringkas: tunjukkan state pratinjau, state data, dan sorot field dengan confidence rendah.
Saat pratinjau siap, reviewer memperbaiki field, menambahkan catatan, dan memindahkan dokumen melalui status bisnis seperti Imported -> Needs review -> Approved (atau Rejected). Log siapa yang mengubah apa dan kapan.
Jika reviewer mengupload file yang diperbaiki, itu menjadi Versi baru dan dokumen otomatis kembali ke Needs review.
Ekspor, sinkronisasi akuntansi, atau laporan internal harus membaca dari current_version_id dan snapshot metadata yang disetujui, bukan "ekstraksi terbaru." Itu mencegah re-upload setengah-proses mengubah angka.
Alur kerja berorientasi dokumen gagal karena alasan membosankan: jalan pintas awal jadi masalah sehari-hari ketika orang mengupload duplikat, memperbaiki kesalahan, atau bertanya, “Siapa yang mengubah ini dan kapan?”
Menganggap nama file sebagai identitas dokumen adalah kesalahan klasik. Nama berubah, pengguna mengupload ulang, dan kamera menghasilkan duplikat seperti IMG_0001. Beri setiap dokumen ID stabil, dan anggap nama file sebagai label.
Menimpa file asli ketika seseorang mengupload pengganti juga bermasalah. Terlihat lebih sederhana, tetapi Anda kehilangan jejak audit dan tidak bisa menjawab pertanyaan dasar nanti (apa yang disetujui, apa yang diedit, apa yang dikirim). Jadikan binary file tak dapat diubah dan tambahkan record versi baru.
Kebingungan status menciptakan bug halus juga. “OCR berjalan” tidak sama dengan “Needs review.” State pemrosesan menggambarkan apa yang sistem lakukan; status bisnis menggambarkan apa yang orang harus lakukan selanjutnya. Saat itu tercampur, dokumen bisa tersangkut di bucket yang salah.
Keputusan UI juga bisa menciptakan friksi. Jika Anda memblokir layar sampai pratinjau dibuat, orang akan merasakan aplikasi lambat meskipun upload berhasil. Tampilkan dokumen segera dengan placeholder yang jelas, lalu tukar thumbnail saat siap.
Akhirnya, metadata menjadi tidak dapat dipercaya jika Anda menyimpan nilai tanpa provenance. Jika total berasal dari OCR, katakan begitu. Simpan timestamp.
Daftar cek cepat:
Contoh: pada aplikasi struk, pengguna mengupload foto lebih jelas. Jika Anda memversi, simpan gambar lama, tandai OCR sebagai sedang diproses ulang, dan pertahankan Needs review sampai manusia mengonfirmasi jumlah.
Alur kerja berorientasi dokumen terasa "selesai" hanya ketika orang bisa mempercayai apa yang mereka lihat dan pulih saat terjadi masalah. Sebelum diluncurkan, uji dengan dokumen nyata yang berantakan (struk buram, PDF terrotasi, upload berulang).
Lima cek yang menangkap sebagian besar kejutan:
Tes realitas cepat: minta seseorang meninjau tiga struk serupa dan sengaja membuat satu perubahan salah. Jika mereka bisa menemukan versi saat ini, memahami status, dan memperbaiki kesalahan dalam waktu kurang dari satu menit, Anda mendekati selesai.
Penggantian struk bulanan adalah contoh jelas pekerjaan berorientasi dokumen. Seorang karyawan mengupload struk, lalu dua reviewer memeriksanya: manajer, lalu finance. Struk adalah produknya, jadi aplikasi Anda hidup atau mati pada versioning, pratinjau, metadata, dan status yang jelas.
Jamie mengupload foto struk taksi. Sistem Anda membuat Document #1842 dengan Versi v1 (file asli), thumbnail dan pratinjau, serta metadata seperti merchant, tanggal, mata uang, total, dan skor confidence OCR. Dokumen mulai di Imported, lalu pindah ke Needs review setelah pratinjau dan ekstraksi siap.
Kemudian, Jamie secara tidak sengaja mengupload struk yang sama lagi. Pengecekan duplikat (hash file plus merchant/tanggal/total mirip) bisa menampilkan pilihan sederhana: “Sepertinya duplikat dari #1842. Lampirkan saja atau buang.” Jika mereka melampirkannya, simpan sebagai File lain yang terhubung ke Document yang sama sehingga Anda tetap punya satu thread review dan satu status.
Selama review, manajer melihat pratinjau, field kunci, dan peringatan. OCR menebak total $18.00, tetapi gambar jelas menunjukkan $13.00. Jamie memperbaiki total. Jangan timpa sejarah. Buat Versi v2 dengan field yang diperbarui, biarkan v1 tidak berubah, dan log “Total dikoreksi oleh Jamie.”
Jika Anda ingin membangun alur semacam ini dengan cepat, Koder.ai (koder.ai) dapat membantu menghasilkan versi pertama aplikasi dari rencana berbasis chat, tetapi aturan yang sama berlaku: definisikan objek dan state dulu, lalu biarkan layar mengikuti.
Langkah praktis selanjutnya:
Aplikasi berorientasi dokumen memperlakukan dokumen sebagai hal utama yang dikerjakan pengguna, bukan sekadar lampiran. Orang perlu membukanya, mempercayai apa yang mereka lihat, memahami apa yang berubah, dan memutuskan langkah berikutnya berdasarkan dokumen tersebut.
Mulailah dengan inbox/daftar, tampilan detail dokumen dengan pratinjau cepat, area aksi review sederhana (setujui/tolak/minta perubahan), dan cara untuk mengekspor atau membagikan. Keempat layar ini menutup loop umum: temukan, buka, putuskan, dan serahkan.
Modelkan sebuah record Document yang stabil dan tak berubah, simpan bytes file aktual sebagai objek File terpisah, lalu tambahkan Version sebagai snapshot yang mengikat dokumen ke file tertentu (dan artefak turunannya). Pemisahan ini menjaga komentar, penugasan, dan riwayat tetap utuh saat file diganti.
Buat setiap perubahan bermakna sebagai versi baru — jangan menimpa file. Simpan current_version_id pada dokumen untuk bacaan "terbaru" yang cepat, dan simpan timeline versi lama untuk audit dan rollback. Ini mencegah kebingungan tentang apa yang disetujui dan mengapa.
Hasilkan pratinjau secara asinkron setelah menyimpan file asli, sehingga upload terasa instan dan retry aman. Pantau state pratinjau seperti pending/ready/failed agar UI bisa jujur, dan simpan beberapa ukuran sehingga daftar tetap ringan sementara tampilan detail tetap tajam.
Simpan metadata dalam tiga kelompok: sistem (ukuran file, tipe), diekstrak (field OCR dan confidence), dan koreksi yang dimasukkan pengguna. Simpan provenance sehingga Anda bisa mengetahui apakah nilai berasal dari OCR atau manusia, dan jangan paksa setiap field harus terisi sebelum pekerjaan bisa lanjut.
Gunakan set status bisnis kecil yang menjelaskan apa yang harus dilakukan orang berikutnya: Imported, Needs review, Approved, Rejected, dan Archived. Lacak pemrosesan terpisah (preview/OCR berjalan) agar dokumen tidak terjebak dalam status yang mencampur pekerjaan manusia dan mesin.
Simpan checksum file yang tidak dapat diubah dan bandingkan saat upload, lalu tambahkan pengecekan kedua menggunakan field kunci seperti vendor/tanggal/total bila tersedia. Saat curiga duplikat, tawarkan pilihan jelas untuk melampirkannya ke thread dokumen yang sama atau membuangnya agar riwayat review tidak terpecah.
Simpan log riwayat status yang mencatat siapa mengubah apa, kapan, dan mengapa; simpan versi yang dapat dibaca melalui timeline. Rollback harus berupa perubahan pointer kembali ke versi lama, bukan penghapusan, sehingga pemulihan cepat tanpa kehilangan jejak audit.
Tentukan objek dan state terlebih dulu, lalu biarkan UI mengikuti definisi itu. Jika Anda memakai Koder.ai untuk menghasilkan aplikasi dari rencana chat, jelaskan dengan tegas Document/Version/File, state preview dan ekstraksi, serta aturan status, agar layar yang dihasilkan sesuai dengan perilaku alur kerja nyata.