roadmap / tahapan pembuatan aplikasi
# Roadmap — laundrai.id
Tahapan dari kondisi saat ini menuju produksi. Disusun berurutan, bukan paralel — kritikal path adalah Fase 1.
## Status saat ini
- ✅ Konsep produk final ([app-concept.md](app-concept.md))
- ✅ Skema SQL live di Postgres lokal (`laundrai_id`) — lihat [db/](db/) dan [CLAUDE.md](CLAUDE.md)
- ❌ Backend, web, mobile, landing page, deployment — belum ada
Rekomendasi titik mulai: **Fase 1 (backend)**. Web dan mobile sama-sama bergantung padanya; kalau API belum stabil, dua klien akan dibangun di atas pasir.
---
## Fase 1 — Backend spine (~1–2 minggu)
Fondasi yang semua fase berikutnya bergantung padanya.
- Scaffold `backend/` dengan Hono + Bun + Drizzle
- Drizzle schema yang match dengan SQL: `drizzle-kit introspect` lalu rapikan manual
- Auth phone+password untuk 3 principal (`saas_owner`, `tenant`, `outlet`) — pilih salah satu: JWT atau session cookie, jangan dua-duanya
- **Idempotency middleware**: baca header `Idempotency-Key` → isi ke `client_request_id` di tabel yang mendukungnya. Fondasi offline-sync; jauh lebih mahal di-retrofit belakangan
- CRUD dasar: tenants, outlets, customers, services
- Request logging, error handler, healthcheck endpoint
**Exit criteria:** bisa signup tenant via API, login sebagai tenant/outlet, CRUD customers.
## Fase 2 — POS order flow (~1–2 minggu)
Fitur inti yang membuat produk "hidup".
- Create order dengan nested items dalam satu transaksi DB
- Status transitions: `masuk` → `proses` → `selesai` → `diambil` (dengan `order_status_history`)
- Pembayaran cash
- Generator WA deep-link (`https://wa.me/{phone}?text={urlencoded}`) dengan template nota; simpan ke `whatsapp_notification_logs`
- Laporan dasar: omset harian/mingguan/bulanan — **pakai `client_created_at`** kalau ada, fallback ke `created_at` (kritikal untuk shift yang sync besok paginya)
**Exit criteria:** outlet bisa terima order, ubah status, kirim nota WA, lihat omset hari ini via API.
## Fase 3 — Web (Nuxt 4) + landing + signup (~2–3 minggu)
- Landing page sesuai spec: card warna-warni, background terang, animasi, hero + features + testimonial + FAQ + pricing + CTA
- Self-service signup: form dengan checkbox "copy HP/password ke outlet 1"
- Verifikasi phone lewat WA deep-link berisi kode OTP
- Dashboard tenant (read-only, cross-outlet aggregation — **tidak bisa** langsung input order di sini per aturan produk)
- UI outlet POS: orders, customers, services, laporan
- Halaman pricing + subscription status (countdown trial)
**Exit criteria:** pengunjung bisa signup dari web sampai masuk ke dashboard outlet pertamanya.
## Fase 4 — Billing & admin panel (~1–2 minggu)
- Free trial 30 hari otomatis dipasang saat signup
- Generator invoice subscription (scheduled job per outlet, bulanan)
- Integrasi pembayaran subscription: **pilih satu gateway dulu — Midtrans Snap**. Paling umum di Indonesia, approval lebih cepat. Xendit bisa ditambah pasca-launch
- Admin panel `saas_owner`: konfirmasi pembayaran manual, perpanjang membership, dashboard tenant/revenue/churn
**Exit criteria:** tenant bisa bayar perpanjangan via Midtrans; saas_owner bisa lihat daftar tenant aktif, trial yang akan habis, dan MRR.
## Fase 5 — Soft launch (web-only, ~1 minggu)
- Deploy: VPS (Hetzner / DigitalOcean / Biznet / Niagahoster) — **jangan langsung ke Kubernetes**, YAGNI
- Domain `laundrai.id` + TLS Let's Encrypt
- Backup Postgres harian (`pg_dump` → S3-compatible storage seperti Wasabi / Cloudflare R2)
- Monitoring minimal: logs terpusat + uptime ping (Uptime Kuma self-hosted atau BetterStack free tier)
- **Onboard 5–10 pilot tenant secara manual** sebelum buka publik
Fase ini paling banyak belajarnya — banyak bug UX yang tidak kelihatan tanpa user nyata. Jangan lewati.
**Exit criteria:** minimal 5 tenant pilot aktif memakai web setiap hari selama 2 minggu tanpa bug blocker.
## Fase 6 — Flutter mobile (~3–4 minggu)
API sudah teruji di lapangan → aman membangun mobile.
- SQLite lokal (Drift atau sqflite) sebagai staging offline
- Sync engine pakai outbox pattern: setiap write offline ditulis ke outbox lokal dengan UUID `client_request_id`, dikirim ke server saat online, dihapus dari outbox setelah 2xx
- Feature parity dengan POS web
- QRIS scanner untuk pembayaran customer (Pro)
- Publish ke Play Store — **Android dulu**, iOS belakangan (spec menyebut "aplikasi Android")
**Exit criteria:** staff bisa input order di mode pesawat, buka koneksi, data nyampai ke server tanpa duplikat.
## Fase 7 — Fitur Pro lanjutan
Dibangun satu-per-satu, bukan bareng, supaya bisa diukur dampaknya ke konversi Starter→Pro.
- Expenses
- Promos & diskon
- Inventory management
- Attendance Android (butuh GPS permission flow matang + unique open-session index yang sudah ada)
- Laporan lanjutan: laba rugi, forecast, perbandingan cabang — ini yang justifikasi harga Pro
## Fase 8 — Hardening sebelum skala penuh
Sebelum marketing agresif ke target 5000 outlet.
- Load test ke 125k tx/hari (k6 / vegeta / locust)
- Partition `orders` by month kalau sudah lambat — schema sudah partition-ready
- Rate limiting + Redis untuk session cache
- Security review: SQL injection, auth bypass, **tenant leakage** (uji `WHERE tenant_id=` di semua query — paling sering bocor di sini)
- Compliance **UU PDP Indonesia**: privacy policy, data retention, hak hapus data pelanggan
- DR test: restore dari backup sungguhan, bukan sekadar asumsi backup-nya jalan
---
## Estimasi total
- **Fase 1–5 (soft launch web-only)**: ~3–4 bulan
- **+ Fase 6 (mobile siap)**: +1–2 bulan
- **+ Fase 7–8 (Pro + hardening)**: +1–2 bulan
Total sampai produksi penuh: ~5–8 bulan tergantung pace.
## Prinsip yang memandu urutan ini
1. **Backend dulu, klien kemudian.** Dua klien di atas API yang berubah-ubah = 3× pekerjaan.
2. **Web sebelum mobile.** Signup tenant baru ada di web; mobile butuh onboarding dulu. Iterasi web juga lebih cepat.
3. **Satu gateway pembayaran dulu.** Midtrans. Xendit belakangan.
4. **Pilot sebelum publik.** 5–10 tenant yang bisa dihubungi langsung akan menemukan bug yang test suite tidak bisa.
5. **YAGNI pada infra.** VPS + pg_dump + Uptime Kuma cukup sampai 500 tenant. Kubernetes, Redis cluster, dll. ditunda sampai benar-benar sakit.
Comments
Post a Comment