24 KiB
Analisis Detail Alur Kerja Aplikasi PFM OCR (Mobile & Backend API)
Dokumen ini memuat analisis mendalam mengenai seluruh alur kerja (workflow) sistem Prima Fresh Mart (PFM) Scanner OCR v2, dengan memfokuskan analisis secara eksklusif pada interaksi antara Aplikasi Mobile Flutter dan Layanan Backend API (API Gateway Next.js, Database PostgreSQL, Pipeline OCR FastAPI, vLLM Server, dan Server Klasifikasi YOLO).
Asumsi analisis ini didasarkan sepenuhnya pada peniadaan antarmuka web (web interface/dashboard), sehingga sistem diposisikan murni sebagai aplikasi mobile tersinkronisasi dengan backend OCR.
1. Arsitektur Aliran Data (Tanpa Web Interface)
Berikut adalah diagram alur kerja yang menggambarkan interaksi ujung-ke-ujung (end-to-end) antara aplikasi mobile Flutter dan komponen backend:
graph TD
%% Sisi Client (Flutter)
subgraph Client [Aplikasi Mobile Flutter]
Start([Mulai: Supir/Operator Scan DO]) --> Capture[Ambil Foto via Camera API]
Capture --> GPS[Ambil Geoposition via Geolocator]
GPS --> BlurCheck{Cek Kualitas via BlurDetector}
BlurCheck -- Blurry / Skor < 80 --> Capture
BlurCheck -- Tajam / Skor >= 80 --> Queue[Tambahkan ke Pending Queue]
Queue --> Upload[Kirim Multipart POST ke /api/v1/documents/upload]
%% Polling
Upload --> StartPoll[Mulai Polling GET /api/v1/documents]
StartPoll --> PollRequest{Cek Dokumen di List?}
PollRequest -- Belum Parsed / Timeout --> StartPoll
PollRequest -- Berhasil Parsed --> StateUpdate[Perbarui UI via Riverpod]
%% Editor & PDF
StateUpdate --> Editor[Manual Correction & Validation]
Editor --> SaveEdit[Kirim PUT ke /api/v1/documents/:id]
SaveEdit --> PrintPDF[Cetak Label / A4 PDF Natively]
PrintPDF --> End([Selesai])
end
%% Sisi Backend (Docker Stack)
subgraph Backend [Backend API & AI Engine]
%% Nginx & API Gateway
Upload --> Nginx[Nginx Router :8000]
Nginx --> UploadAPI[Next.js API Gateway :3000]
UploadAPI --> DBInsert[SQL: Simpan Dokumen Awal - parsed=false]
DBInsert --> TriggerParse[Panggil Internal POST /api/parse]
%% Pipeline API
TriggerParse --> Pipeline[FastAPI Pipeline API :8090]
Pipeline --> Deskew{Hitung Sudut Rata-rata - Tilt > 1.0 deg?}
Deskew -- Ya --> Unwarp[Unwarping via UVDoc & Re-Run]
Deskew -- Tidak --> LayoutDet[Layout Detection via PP-DocLayoutV3]
Unwarp --> LayoutDet
%% Text Extraction & LLM
LayoutDet --> TextOCR[PaddleOCR Text Recognition]
TextOCR --> FormatMD[Format Hasil ke Markdown]
FormatMD --> VllmProxy[vLLM Server: PaddleOCR-VL-1.6 :8118]
VllmProxy --> SendMD[Kembalikan Hasil Teks Terstruktur]
%% Next.js Post-processing
SendMD --> ParserTS[parseDOMetadata - Regex Extraction]
ParserTS --> StoreMatch[resolveStoreFromText - Fuzzy Toko]
StoreMatch --> TripleCheck[Intelligent Triple-Check SKU / Nama / Unit]
TripleCheck --> DBSave[SQL: UPDATE documents - parsed=true & ocr_items]
DBSave --> PollRequest
SaveEdit --> Nginx
end
2. Analisis Alur Kerja Sisi Client (Aplikasi Mobile Flutter)
Aplikasi mobile Flutter bertindak sebagai gerbang pertama pengumpulan data di lapangan oleh supir/operator pengiriman.
A. Pengambilan Gambar & Geolokasi
- Operator menggunakan modul kamera bawaan aplikasi Flutter untuk memotret kertas dokumen Delivery Order (DO).
- Bersamaan dengan pengambilan foto, aplikasi mengakses layanan lokasi perangkat menggunakan paket
geolocatoruntuk mengambil titik koordinat GPS (latitudedanlongitude). Koordinat ini akan disematkan sebagai penanda lokasi pengunggahan (geolocation tags).
B. Pendeteksian Blur (Blur Detection) secara Real-time
Untuk memastikan gambar yang dikirim memiliki kualitas yang layak dibaca oleh mesin OCR, aplikasi menjalankan deteksi ketajaman gambar via kelas BlurDetector sebelum diunggah:
- Isolate Execution: Agar antarmuka (UI) tidak mengalami patah-patah (stuttering), pemrosesan gambar dipindahkan ke Dart Isolate terpisah menggunakan fungsi
compute. - Preprocessing Gambar:
- Gambar asli diperkecil skalanya (resized) menjadi lebar 300 piksel untuk mempercepat kalkulasi.
- Dilakukan pemotongan area tengah sebesar 60% (center crop), dengan tujuan mengabaikan latar belakang (meja, lantai) dan fokus sepenuhnya pada teks dokumen.
- Mengaplikasikan Gaussian Blur dengan radius
1untuk menyaring noise sensor kamera. - Mengonversi gambar hasil crop ke format skala abu-abu (grayscale).
- Algoritma Varians Laplacian:
- Aplikasi memindai piksel gambar dan menerapkan matriks konvolusi Laplacian 3x3 untuk mendeteksi tepi (edge detection):
\text{Laplacian} = 4 \times \text{Center} - \text{Left} - \text{Right} - \text{Top} - \text{Bottom} - Menghitung nilai varians dari seluruh piksel Laplacian. Nilai varians yang tinggi mengindikasikan banyaknya perubahan intensitas piksel yang tajam (tepi teks jelas), sedangkan varians rendah berarti transisi piksel halus (gambar blur).
- Aplikasi memindai piksel gambar dan menerapkan matriks konvolusi Laplacian 3x3 untuk mendeteksi tepi (edge detection):
- Penentuan Batas Kelolosan (Thresholding):
- Varians mentah dipetakan ke skala 0 hingga 100 dengan batas skor kelolosan sebesar 80.0 (setara dengan nilai varians mentah sebesar 400.0 dari batas maksimum 500.0).
- Jika gambar di bawah skor 80.0, aplikasi memblokir proses unggah dan meminta pengguna mengambil ulang foto.
C. Antrean Unggah & Sinkronisasi Latar Belakang (Background Polling)
Setelah lolos uji blur, berkas gambar didaftarkan ke state management Riverpod melalui kelas PendingDocumentsNotifier:
- Status dokumen diatur menjadi
PendingDocumentStatus.uploading. - Aplikasi mengirimkan berkas gambar bersama koordinat GPS menggunakan objek
FormDatamelalui pustakaDioHTTP Client ke endpoint backend:POST /api/v1/documents/upload - Begitu API mengonfirmasi bahwa gambar sukses diunggah ke server (HTTP status
201), aplikasi mengubah status menjadiPendingDocumentStatus.processing. - Mekanisme Polling:
Aplikasi Flutter memulai loop polling otomatis di latar belakang dengan melakukan request
GET /api/v1/documentssetiap 2 detik.- Aplikasi membandingkan ID dokumen yang sedang diunggah dengan daftar dokumen yang dikembalikan oleh server.
- Server hanya akan menampilkan dokumen pada daftar tersebut jika kolom
parseddi database sudah bernilaitrue. - Loop polling dibatasi maksimal 60 kali percobaan (timeout 2 menit). Begitu terdeteksi di server, status diubah menjadi
PendingDocumentStatus.successdan data terisi ke UI.
D. Koreksi Manual & Standardisasi Sisi Editor
Jika terdapat karakter OCR yang tidak sempurna, operator dapat melakukan penyelarasan langsung pada aplikasi mobile (editor_screen.dart):
- Menyesuaikan nomor dokumen (PO, SO, DO) atau detail pengiriman (Plat truk, nama driver, nama penerima).
- Melakukan penyuntingan baris item barang (SKU, kuantitas/banyak, jumlah unit).
- Memberi tanda bendera (
is_flagged) dan catatan khusus (remark) jika ada ketidaksesuaian barang. - Menyimpan seluruh perubahan kembali ke database backend melalui endpoint:
PUT /api/v1/documents/[id]
E. Ekspor PDF & Cetak Struk Nativel
Setelah data terverifikasi bersih, operator dapat langsung mencetak tanda terima fisik:
- Pustaka
pdfmenyusun tata letak lembaran A4 yang memuat logo PFM, ringkasan PO/SO/DO, informasi pengiriman (Driver, plat nomor, alamat toko), tabel barang hasil OCR yang sudah bersih, serta kolom tanda tangan basah untuk supir dan penjaga toko. - Pustaka
printingmemicu manajer cetak bawaan sistem operasi (Native OS Print Spooler) untuk mencetak dokumen langsung ke printer thermal/portable via Bluetooth/Wi-Fi atau menyimpannya sebagai berkas PDF lokal.
3. Analisis Alur Kerja Sisi Backend (Gateway API & Database)
Backend bertindak sebagai API gateway dan orkestrator yang mengarahkan gambar dokumen ke unit pemrosesan AI, melakukan sanitasi, dan menyimpannya ke database relasional.
A. Penerimaan Berkas & Inisialisasi Database (/api/v1/documents/upload)
Ketika file diunggah dari aplikasi mobile, Next.js API Gateway memprosesnya sebagai berikut:
- Menyimpan berkas gambar fisik ke direktori
/uploadsdengan nama unik terstempel waktu (Date.now() - safe_name.jpg). - Menghitung nilai hash SHA-256 dari berkas biner untuk melacak integritas data dan mencegah duplikasi konten.
- Melakukan insert record ke tabel
documentsdengan kolomparsed = falsedan menyimpan metadata awal beserta koordinat GPS. - Memicu eksekusi parsing secara sinkron dan cepat dengan menembak API internal
/api/parsemembawa payload nama file.
B. Alur Ekstraksi & Pipeline OCR (/api/parse)
Pada endpoint ini, Next.js meneruskan base64 gambar ke kontainer Python paddleocr-pipeline-api (FastAPI pada port 8090) yang menjalankan pipeline pengolahan gambar berbasis GPU:
1. Deteksi Sudut & Koreksi Kemiringan Otomatis (Auto-Deskew & Unwarping)
Dokumen yang difoto secara manual oleh supir sering kali miring atau melengkung.
- Sistem mendeteksi poligon koordinat blok teks menggunakan model PP-LCNet_x1_0_doc_ori untuk klasifikasi arah orientasi dokumen.
- Sistem menghitung kemiringan rata-rata teks secara trigonometri dari koordinat sudut poligon blok teks (
block_polygon_points):\text{Kemiringan Rata-rata} = \frac{1}{N} \sum_{i=1}^{N} \arctan\left(\frac{y_1 - y_0}{x_1 - x_0}\right) \times \frac{180}{\pi} - Jika rata-rata kemiringan melampaui batas toleransi 1.0 derajat, backend akan menolak hasil bacaan awal dan memicu pemrosesan ulang dengan mengaktifkan modul unwarping dokumen UVDoc (
useDocUnwarping: true). Modul ini merentangkan kembali kertas yang melengkung/miring agar teks sejajar horizontal sebelum dibaca ulang.
2. Segmentasi Tata Letak & Deteksi Teks
- Model PP-DocLayoutV3 membagi area dokumen ke dalam beberapa tipe tata letak (Tabel, Paragraf, Judul, Header, Footer).
- Untuk memastikan informasi penting di bagian tepi kertas (seperti Nomor PO, SO, dan Tanggal pengiriman) tidak dibuang oleh OCR, parameter
markdown_ignore_labelspadapipeline_config_vllm.yamldisetel kosong ([]). - Teks dibaca per wilayah menggunakan engine PaddleOCR v6 dan disusun kembali menjadi representasi teks terstruktur berformat Markdown mentah.
- Pipeline FastAPI mengirimkan teks Markdown tersebut ke kontainer vLLM Server (port
8118) yang memuat model lokal PaddleOCR-VL-1.6-0.9B untuk interpretasi kontekstual lanjutan guna menyusun kembali kalimat-kalimat yang terpecah akibat deteksi tabel.
4. Pengolahan Data Lanjutan & Validasi Lapis Dua (Next.js)
Setelah menerima respons Markdown terstruktur dari pipeline OCR, Next.js Gateway melakukan serangkaian pembersihan data menggunakan aturan logika bisnis yang ketat:
A. Ekstraksi Informasi Utama (Regex Matching)
Fungsi parser.ts menggunakan ekspresi reguler (Regex) untuk menarik data dari teks mentah:
- No PO (Purchase Order):
- Mengekstrak kode PO menggunakan pola regex
/No\.?\s*PO\s*[:\-]\s*([A-Z0-9\-\/]+)/i. - Mengoreksi kegagalan bacaan OCR yang sering menyatukan karakter (fused digits) seperti
PO1207000019dengan memisahkannya kembali menjadi format standarPO/YY/NNNN+(di manaYYdisamakan dengan tahun pada tanggal dokumen).
- Mengekstrak kode PO menggunakan pola regex
- No SO & DO:
- Mencari pola 10 digit angka numerik (yang biasanya diawali angka
16atau10).
- Mencari pola 10 digit angka numerik (yang biasanya diawali angka
- Plat Nomor Kendaraan:
- Mencari format plat nomor Indonesia dengan pola
[KODE_WILAYAH] [NOMOR_POLISI] [SERI_AKHIR]. Huruf depan divalidasi ke daftar kode plat resmi (sepertiB,D,F,DK, dll.).
- Mencari format plat nomor Indonesia dengan pola
- Koreksi Layout Tergeser (Shifted Layout Correction):
- Kadang-kadang teks label ("Tanggal :", "No. SO :") tercetak terpisah jauh di atas nilainya karena tata letak visual bergeser. Jika parser mendeteksi nilai-nilai kunci kosong tetapi menemukan deretan angka 10-digit berurutan di baris-baris bawahnya, parser otomatis melakukan realinyasi indeks baris untuk menarik nilai ke kunci yang sesuai.
B. Sanitasi & Standardisasi Data (sanitizeParsedMetadata)
Semua metadata yang berhasil ditarik disaring kembali untuk menjamin kepatuhan data sebelum masuk ke database:
- Tanggal: Harus lolos pola
"dd Month yyyy"dengan nama bulan bahasa Inggris lengkap (contoh:"02 February 2026"). Jika OCR menghasilkan tanggal yang salah format atau di luar rentang wajar (2010 s.d. tahun depan), nilainya diganti menjadi"Not Found"agar memaksa operator melakukan koreksi manual, alih-alih melakukan auto-fallback ke tanggal hari ini yang berpotensi memalsukan tanggal dokumen asli. - SO & DO: Wajib berupa digit angka murni sepanjang 7 s.d. 12 karakter. Sistem otomatis mengoreksi kesalahan visual karakter OCR yang umum terjadi (visual digit correction):
- Huruf
Oatauodi tengah angka\rightarrow0 - Huruf
I,i,l, atau simbol|di tengah angka\rightarrow1 - Huruf
Sataus\rightarrow5 - Huruf
Zatauz\rightarrow2 - Huruf
Bataub\rightarrow8 - Angka bulan salah seperti
012atau112diubah menjadi02(Februari).
- Huruf
C. Pencocokan Toko Penerima (Fuzzy Store Matching)
Toko penerima ditentukan secara cerdas dari teks area customer (customerInfo):
- Sistem mengambil teks mentah customer, melakukan normalisasi ke huruf kecil, membuang tanda baca, dan memotongnya menjadi token kata-kata unik (tokenization).
- Sistem menyaring kata umum atau kata henti (stop words) seperti "dan", "dki", "area", "yth", "kepada", "jalan", "raya", "kelurahan", "kecamatan".
- Token tersebut kemudian diiriskan (intersection) dengan seluruh data toko yang terdaftar di database
store_master. - Toko yang memiliki kecocokan minimal 2 token dengan skor bobot tertinggi dipilih secara otomatis. Alamat resmi dan nama toko dari database kemudian disematkan pada kolom
orderUntukdanalamat.
D. Sistem Validasi Barang Pintar (Intelligent Triple-Check Matcher)
Baris barang pada tabel DO rentan mengalami kesalahan pembacaan kode SKU maupun nama item. Next.js mengatasinya melalui mekanisme Triple-Check Matcher:
- Sistem memuat seluruh master barang dari database
sku_master(meliputi nomor SKU, nama item, standar jumlah inner, dan jenis kemasan outer). - Setiap baris barang hasil pembacaan tabel OCR dibandingkan dengan master menggunakan bobot gabungan (Weighted Combined Score):
- Bobot SKU (50%): Skor kemiripan antara kode SKU hasil pembacaan dan SKU master menggunakan algoritma Levenshtein Distance. Jika ditemukan kecocokan SKU 100% presisi, sistem langsung menetapkan item tersebut sebagai kecocokan mutlak.
- Bobot Nama Barang (40%): Skor kemiripan string nama barang hasil pembacaan dengan nama barang master.
- Bobot Kemasan & Satuan (10%): Bonus kecocokan jika satuan kuantitas yang dibaca (misal:
KRG,BOX,BAGsebagai kemasan luar/outer) atau harga unit (PAC,PC,KGsebagai kemasan dalam/inner) sesuai dengan definisi jenis kemasan item tersebut di database master.
- Penyelarasan & Pembersihan:
- Jika skor kecocokan gabungan mencapai
\ge0.6, baris tersebut dianggap valid. Sistem otomatis mengganti nomor SKU dan nama barang dengan data master yang resmi, serta menstandardisasi satuan kuantitasnya (contoh: kuantitas angka murni"15"diautocomplete menjadi"15 KRG"berdasarkan jenis kemasan luar item bebek/ayam). - Jika skor kecocokan di bawah 0.6 tetapi nomor SKU yang terbaca merupakan angka valid 8 digit, baris item tetap dipertahaman (untuk mendukung pengenalan SKU baru yang belum terdaftar di database master).
- Jika tidak ada kecocokan dan SKU tidak valid 8-digit, baris tersebut langsung dibuang karena diidentifikasi sebagai kebisingan layout tabel (table noise seperti garis pembatas tabel, tanda tangan supir, atau coretan kupon).
- Jika skor kecocokan gabungan mencapai
5. Alur Kerja Deteksi & Klasifikasi Produk (Scan Produk Tunggal)
Selain mengolah dokumen DO utuh, aplikasi mobile juga mendukung pemindaian produk/kemasan secara individual untuk memverifikasi kecocokan barang dan mendeteksi tanggal kedaluwarsa (expiry date).
graph TD
StartScan([Mulai: Scan Produk Tunggal]) --> SendImg[POST /api/scan-pfm dengan Base64 Gambar]
SendImg --> ForwardAPI[Next.js Meneruskan ke Python FastAPI :8120]
subgraph PyServer [FastAPI Classify-OCR Server]
ForwardAPI --> YOLO[1. YOLO Classification: Prediksi Kelas Produk]
YOLO --> Paddle[2. PaddleOCR: Deteksi & Ekstraksi Seluruh Baris Teks]
Paddle --> ExpExtract[3. extract_expired_date: Regex Pencarian Tanggal]
ExpExtract --> VisualDraw[4. Menggambar Bounding Box: Teal=Teks, Amber=EXP]
VisualDraw --> CropExp[5. Crop Region Tanggal Exp sebagai Base64]
CropExp --> SpotAPI[6. Call Layout-Parsing untuk Spotting Image]
end
PyServer --> ReturnData[Kembalikan Hasil OCR & Visualisasi ke Next.js]
ReturnData --> FuzzyMatch[Levenshtein Match: Hasil YOLO vs sku_master]
FuzzyMatch --> Top5[Ambil Top 5 Hasil dengan Skor Sim > 0.1]
Top5 --> RespondMobile[Kirim Hasil Akhir JSON ke Flutter Client]
RespondMobile --> EndScan([Selesai])
A. Klasifikasi YOLO & Deteksi OCR
- Aplikasi Flutter mengambil foto produk tunggal dan mengirimkannya ke endpoint Next.js
/api/scan-pfm, yang diteruskan ke server FastAPI khusus (classify_ocr_server.pypada port8120). - YOLO Classification: Server memuat bobot model YOLO yang telah dilatih (
produk-pfm-classifier-26n-*e-*.pt) untuk memprediksi kelas produk (nama produk) beserta probabilitas keyakinannya (confidence score). - PaddleOCR Text Extraction: Server menjalankan deteksi teks untuk mengambil seluruh baris tulisan yang tercetak pada label/kemasan produk.
B. Ekstraksi & Pembersihan Tanggal Kedaluwarsa (Expiry Date Spotting)
Pendeteksian tanggal kedaluwarsa pada kemasan produk sangat menantang karena kualitas cetakan dot-matrix pada plastik kemasan sering kali buruk. Server FastAPI menggunakan serangkaian aturanRegex berlapis:
- Pencarian Kata Kunci EXP: Mencari kata kunci kedaluwarsa seperti
EXP,EXPIRY,TGL EXP,BBD,BEST BEFORE, atauBB. - Regex Format Tanggal:
- Pola tanggal rapat tanpa spasi/karakter pembatas (contoh:
05032027viaDDMMYYYY_RE). - Pola tanggal dengan pembatas spasi, titik, hubung, atau garis miring (contoh:
05-03-2027viaDD_MM_YYYY_RE). - Pola tanggal langsung setelah kata kunci (contoh:
BB05032027viaBB_ATTACHED_DATE_RE).
- Pola tanggal rapat tanpa spasi/karakter pembatas (contoh:
- Pembersihan Noise Karakter Khusus:
- Mengganti noise cetakan tanda kurung
()atau karakter tidak sengaja1)menjadi angka0. - Memperbaiki kesalahan interpretasi huruf/angka kembar seperti
B8,8B, atau88menjadiBB(Best Before) jika diikuti oleh digit angka. - Mengoreksi kegagalan bacaan bulan cetak rapat seperti
012atau112di belakang tanggal menjadi bulan02(Februari) (contoh:020122027dikoreksi menjadi02/02/2027).
- Mengganti noise cetakan tanda kurung
- Visualisasi & Pemotongan Area (Visual Cropping):
- Server memotong poligon area koordinat teks kedaluwarsa yang berhasil diidentifikasi dan mengembalikannya sebagai gambar thumbnail terpotong berformat Base64 (
expired_date_crop_base64). Hal ini berguna untuk validasi visual oleh pengguna pada aplikasi mobile. - Menggambar kotak pembatas (bounding box) pada gambar produk: kotak Teal untuk tulisan biasa, dan kotak Amber (oranye) dengan label "EXP" untuk menyoroti letak teks tanggal kedaluwarsa.
- Server memotong poligon area koordinat teks kedaluwarsa yang berhasil diidentifikasi dan mengembalikannya sebagai gambar thumbnail terpotong berformat Base64 (
C. Fuzzy Similarity Matching (Next.js)
Begitu Next.js menerima hasil klasifikasi YOLO dan ekstraksi OCR:
- Sistem menghitung kemiripan string menggunakan jarak Levenshtein antara prediksi nama produk YOLO dengan data
nama_itempada tabelsku_master. - Mengembalikan Top 5 kecocokan terbaik yang memiliki skor kemiripan
>0.1, dengan menetapkan item teratas sebagaiisBestMatch = true. - Seluruh hasil klasifikasi produk, kecocokan master SKU, teks kedaluwarsa yang dideteksi, beserta visualisasi gambar kotak pembatas dikirimkan kembali ke aplikasi mobile Flutter.
6. Spesifikasi Skema Database PostgreSQL
Berikut adalah spesifikasi detail tabel-tabel PostgreSQL yang digunakan dalam workflow aplikasi mobile dan backend:
A. Tabel documents
Menyimpan berkas informasi utama dokumen DO yang diunggah.
| Nama Kolom | Tipe Data | Deskripsi |
|---|---|---|
id |
SERIAL (PK) | ID unik dokumen (Auto-increment). |
filename |
VARCHAR(255) | Nama file unik yang tersimpan di /uploads (Unique). |
upload_time |
TIMESTAMP | Tanggal dan waktu pengunggahan dokumen. |
size |
INTEGER | Ukuran berkas gambar dalam satuan bytes. |
parsed |
BOOLEAN | Penanda status apakah dokumen telah selesai di-OCR (true/false). |
metadata |
JSONB | Menyimpan hasil ekstraksi terstruktur (PO, SO, DO, Tanggal, Plat nomor, Driver). |
layout_parsing_result |
JSONB | Menyimpan mentahan respons JSON dari kontainer Pipeline OCR FastAPI. |
is_sample |
BOOLEAN | Menandai apakah dokumen merupakan data contoh bawaan sistem (true/false). |
file_hash |
VARCHAR(64) | Hash SHA-256 berkas gambar untuk mencegah duplikasi data biner. |
processing_logs |
JSONB | Log jejak audit detail dari seluruh tahapan pemrosesan sistem OCR. |
latitude |
NUMERIC | Titik koordinat garis lintang (GPS) lokasi unggah dari perangkat mobile. |
longitude |
NUMERIC | Titik koordinat garis bujur (GPS) lokasi unggah dari perangkat mobile. |
B. Tabel ocr_items
Menyimpan baris item produk yang tertera pada tabel dokumen DO. Terikat relasi One-to-Many terhadap tabel documents.
| Nama Kolom | Tipe Data | Deskripsi |
|---|---|---|
id |
SERIAL (PK) | ID unik baris item (Auto-increment). |
document_id |
INTEGER (FK) | Relasi kunci asing merujuk ke documents(id) dengan aksi ON DELETE CASCADE. |
row_index |
INTEGER | Nomor urut baris tabel item dalam satu dokumen. |
kode_barang_original |
VARCHAR(255) | Kode SKU barang asli hasil pembacaan awal mesin OCR sebelum dicocokkan. |
kode_barang |
VARCHAR(255) | Kode SKU barang hasil verifikasi akhir / standardisasi master. |
nama_barang |
VARCHAR(255) | Nama/deskripsi barang yang dikirim. |
banyak_original |
VARCHAR(255) | Kuantitas barang asli hasil pembacaan awal OCR. |
banyak |
VARCHAR(255) | Kuantitas barang hasil standardisasi (misalnya: "15 KRG"). |
jumlah_original |
VARCHAR(255) | Nilai total barang asli hasil pembacaan awal OCR. |
jumlah |
VARCHAR(255) | Nilai total barang hasil standardisasi (misalnya: "450 PAC"). |
is_flagged |
BOOLEAN | Penanda bendera untuk perhatian khusus / manual check (true/false). |
remark |
VARCHAR(1000) | Catatan koreksi atau alasan penandaan bendera pada baris item. |
Catatan: Terdapat constraint UNIQUE(document_id, row_index) untuk mencegah tumpang tindih indeks baris.
C. Tabel sku_master
Menyimpan daftar master barang PFM untuk validasi Triple-Check.
| Nama Kolom | Tipe Data | Deskripsi |
|---|---|---|
id |
SERIAL (PK) | ID unik master SKU. |
no_sku |
VARCHAR(255) | Nomor SKU barang sepanjang 8 digit angka unik (Unique). |
nama_item |
VARCHAR(255) | Deskripsi nama resmi barang. |
standar_jumlah |
VARCHAR(255) | Satuan kemasan dalam/inner (contoh: PAC, PC, KG). |
jenis_outer |
VARCHAR(255) | Satuan kemasan luar/outer (contoh: Karung, Box, Bag). |
created_at |
TIMESTAMP | Tanggal pendaftaran SKU ke database. |
D. Tabel store_master
Menyimpan data master toko Prima Fresh Mart untuk pencocokan tujuan pengiriman DO.
| Nama Kolom | Tipe Data | Deskripsi |
|---|---|---|
id |
SERIAL (PK) | ID unik master toko. |
nama_toko |
VARCHAR(255) | Nama resmi outlet/toko PFM. |
kode_toko |
VARCHAR(255) | Kode unik toko (Unique, contoh: 02-ANC2). |
alamat |
TEXT | Alamat lengkap toko PFM untuk tujuan pengiriman. |
created_at |
TIMESTAMP | Tanggal pendaftaran toko ke database. |