8.8 KiB
POSMANT — Technical Overview
Point of Sale Manajemen Aset Niaga Terpadu
Aplikasi POS + manajemen stok native Android, offline-first, untuk UMKM daerah terpencil.
Tech Stack
Mobile → Flutter (Android-first)
Local DB → SQLite via Drift
Background → WorkManager (via flutter_workmanager)
Backend → Node.js + Fastify
Server DB → PostgreSQL + Prisma ORM
Bahasa → Dart (mobile) + TypeScript (backend)
Kenapa Flutter, bukan PWA
| PWA | Flutter (dipilih) | |
|---|---|---|
| Startup | Load browser dulu | Langsung buka |
| Offline storage | IndexedDB — bisa dihapus sistem | SQLite — permanen |
| Background sync | Tidak reliable | WorkManager — reliable |
| Printer Bluetooth | Terbatas | Native, mudah |
| Low-end device | Oke | Lebih baik |
Risiko kritis PWA: Android otomatis hapus cache browser saat storage penuh. 7 hari transaksi yang belum sync bisa hilang seketika — tidak bisa ditoleransi untuk warung terpencil.
Arsitektur Umum
[Device Android] [Server] [Data Layer]
┌──────────────────┐ ┌──────────────┐ ┌─────────────────┐
│ Flutter App │ sync │ Fastify API │ proses │ Operational DB │
│ - UI/UX │ ────────► │ │ ───────► │ (per warung) │
│ - SQLite/Drift │ (silent, │ Agregasi │ │ retensi 12 bln │
│ - WorkManager │ malam) │ per │ ├─────────────────┤
│ │ │ kecamatan │ │ Agregat DB │
└──────────────────┘ └──────────────┘ │ (permanen) │
└─────────────────┘
Platform
Flutter — Android-first
- Target device: Android kelas menengah ke bawah
- Distribusi: APK sideload (via pengabdian masyarakat) atau Play Store
- iOS: tidak dalam scope awal, namun codebase Flutter siap bila diperlukan
Struktur Proyek
posmant/
├── mobile/ ← Flutter app (Android)
│ ├── lib/
│ │ ├── features/
│ │ │ ├── pos/
│ │ │ ├── stok/
│ │ │ ├── laporan/
│ │ │ └── sync/
│ │ ├── core/ ← database, network, shared logic
│ │ └── main.dart
│ └── pubspec.yaml
├── server/ ← Node.js + Fastify backend
│ ├── src/
│ │ ├── routes/
│ │ ├── jobs/ ← agregasi & cleanup scheduler
│ │ └── prisma/
│ └── package.json
└── README.md
Strategi Offline-First
Prinsip Dasar
App dirancang untuk berjalan tanpa internet sebagai kondisi default. Koneksi internet hanya dibutuhkan untuk sync.
Teknologi Offline
| Komponen | Package | Fungsi |
|---|---|---|
| SQLite | drift |
Database lokal permanen — menyimpan semua transaksi |
| WorkManager | flutter_workmanager |
Jadwalkan sync otomatis tengah malam |
| HTTP Client | dio |
Kirim data ke server saat online |
| Connectivity | connectivity_plus |
Deteksi status jaringan |
Alur Sync
Seharian → Transaksi tersimpan di SQLite lokal
Tengah malam → WorkManager cek koneksi → ada sinyal? sync otomatis, diam-diam
Pagi → Semua tersinkron, pengguna tidak perlu tahu
Sync Window (Batas Offline)
Hari 1-4 → Normal, tidak ada notifikasi
Hari 5 → Banner kuning: "Segera hubungkan ke internet"
Hari 7 → Banner merah: "Harap sinkron hari ini"
Hari 8+ → Mode read-only: hanya bisa lihat data, tidak bisa input transaksi baru
Conflict Resolution
Jika dua device edit data yang sama saat offline:
- Strategi: last-write-wins dengan audit log
- Semua perubahan dicatat dengan timestamp
Template Bisnis (Onboarding)
Saat registrasi, pengguna memilih jenis usaha. App otomatis menyiapkan data awal yang relevan.
| Template | Pre-fill Kategori | Satuan Default | Mode |
|---|---|---|---|
| Warung | Sembako, snack, minuman | pcs, sachet, kg, liter | Produk |
| Kafe | Menu minuman, makanan ringan | gelas, porsi, cup | Produk |
| Katering | Paket nasi box, prasmanan | porsi, paket, orang | Produk* |
| Laundry | Cuci reguler, express, setrika | kg, pcs, paket | Produk* |
| Umum | Kosong | pcs | Produk |
*Katering dan Laundry menggunakan model produk disederhanakan di MVP. Mode order dengan status (masuk → proses → selesai) masuk fase berikutnya.
Template juga memperkaya data riset — setiap agregat per kecamatan diketahui distribusi jenis usahanya.
Data Architecture
Lapis 1 — Operational (Private per Warung)
Entitas utama:
- Warung (nama, jenis usaha, lokasi kecamatan)
- Produk (nama, kategori, harga, satuan, stok)
- Transaksi (waktu, produk, jumlah, total)
- StokOpname (penyesuaian stok manual + alasan)
- Hanya bisa diakses oleh pemilik warung sendiri
- Disimpan di server maksimal 12 bulan
- Setelah 12 bulan: di-aggregate lalu raw data dihapus otomatis
Lapis 2 — Research (Agregat per Kecamatan)
Contoh data agregat:
- Total transaksi per kategori produk per kecamatan per bulan
- Rata-rata harga jual per kategori per wilayah
- Distribusi jenis usaha per kecamatan
- Pola stok (kelangkaan, kelebihan) per kategori
- Tidak dapat mengidentifikasi warung atau individu manapun
- Disimpan permanen — aset riset utama
- Jadi bahan laporan, dataset, jurnal, dan produk data
Alur Agregasi (Server)
Raw data masuk → disimpan di Operational DB
Setiap malam → job agregasi → update Agregat DB per kecamatan
Setiap bulan → cek data > 12 bulan → hapus raw (pastikan agregat sudah tersimpan)
Fitur Inti (MVP)
Modul Onboarding
- Pilih template bisnis (warung, kafe, katering, laundry, umum)
- Data produk awal ter-pre-fill sesuai template
- Tutorial singkat alur penggunaan
Modul POS
- Input transaksi penjualan
- Pilih produk dari daftar
- Hitung total otomatis
- Struk digital (simpan di app)
- Dukungan printer thermal Bluetooth
Modul Stok
- Daftar produk dengan stok real-time
- Notifikasi stok menipis
- Stok opname manual
- Riwayat perubahan stok
Modul Laporan
- Ringkasan penjualan harian / mingguan / bulanan
- Produk terlaris
- Export CSV (backup darurat)
Modul Sync
- Background sync otomatis tengah malam (WorkManager)
- Status sync terakhir
- Warning sistem (hari ke-5, ke-7, mode read-only hari ke-8)
- Manual sync (tombol opsional)
Privasi & Keamanan
- Enkripsi data in-transit (HTTPS)
- Enkripsi data at-rest di server
- Consent eksplisit saat registrasi (penggunaan data untuk riset)
- Hak hapus data (right to erasure) — pengguna bisa hapus akun + data
- Data retention policy otomatis (12 bulan raw → hapus)
- Kepatuhan UU PDP No. 27/2022
- Ethical clearance institusi untuk jalur publikasi akademik
Yang Masih Perlu Didiskusikan
- User roles — apakah ada perbedaan akses kasir vs pemilik warung?
- Multi-device — satu warung bisa pakai lebih dari satu HP?
- Satuan lokal — ikat, kodi, pak — bagaimana sistem satuannya?
- Infrastruktur — hosting di mana? (VPS, Railway, dll.)
- Distribusi app — APK sideload via pengabdian, atau Play Store?
- Printer struk — model printer thermal Bluetooth yang disupport?
- Fitur fase 2 — mode order untuk laundry/katering, multi-outlet, dll.
Deploy — Landing Page (Coolify)
Landing page statis di-serve via nginx dalam Docker container.
File
index.html ← landing page
Dockerfile ← build config untuk Coolify
Dockerfile
FROM nginx:alpine
COPY index.html /usr/share/nginx/html/index.html
EXPOSE 80
HEALTHCHECK --interval=30s --timeout=5s CMD wget -qO- http://localhost/ || exit 1
Langkah Deploy di Coolify
- Push repo ke GitHub/Gitlab (pastikan
DockerfiledanPosmant Landing Page.htmlikut ter-commit) - Buka Coolify → New Resource → Application
- Pilih repo dan branch
- Build Pack: Dockerfile (Coolify akan auto-detect)
- Port:
80 - Klik Deploy
Environment
Tidak ada environment variable yang dibutuhkan — ini halaman statis murni.
Update Landing Page
Ganti file index.html → push → Coolify auto-redeploy (aktifkan auto-deploy di settings).
Status
v0.2 — Perencanaan (stack dikonfirmasi)
README ini adalah dokumen hidup yang akan diperbarui seiring diskusi pengembangan.