LOTUSEA — User Journey vs Backend Complexity

Apa yang dilihat user (kiri) vs apa yang terjadi di backend (kanan)

Flow 1: User Journey (Booking Experience)

Dari sisi user, prosesnya terlihat simple dan linear. Ini yang client bayangkan.

flowchart TD A["User membuka website"] --> B["Browse katalog wellness"] B --> C["Filter by kategori / lokasi"] C --> D["Klik experience menarik"] D --> E["Lihat detail & gallery"] E --> F["Pilih tanggal & jumlah"] F --> G["Klik 'Book Now'"] G --> H["Isi data diri"] H --> I["Bayar via Xendit"] I --> J["Terima email konfirmasi"] J --> K["Datang ke lokasi"] style A fill:#D8ECEE,stroke:#2F7F83,stroke-width:2px style K fill:#D1FAE5,stroke:#059669,stroke-width:2px style I fill:#FEF3C7,stroke:#F59E0B,stroke-width:2px
User sees: 10 steps Waktu: ~3-5 menit Perceived complexity: LOW

Flow 2: Backend Reality (Behind 'Book Now')

Satu klik 'Book Now' memicu 30+ proses di backend. Setiap kotak = logic yang harus ditulis, di-test, dan di-maintain.

flowchart TD subgraph FRONTEND["1. Frontend Layer"] F1["Validasi form input
(email, phone, date, qty)"] F2["Cek session/login status"] F3["Rate limiting check
(anti spam)"] F4["Loading state UI"] end subgraph API["2. API Gateway"] A1["Auth middleware
verify JWT token"] A2["Request validation
(Zod schema)"] A3["Rate limit middleware"] A4["CORS & security headers"] end subgraph BUSINESS["3. Business Logic Layer"] B1["Check product availability
for selected date"] B2["Inventory lock
(prevent double-booking)"] B3["Calculate pricing
(base + qty + promo)"] B4["Validate minimum deposit rules"] B5["Create order record
status: PENDING"] B6["Generate unique order ID"] end subgraph PAYMENT["4. Payment Processing (Xendit)"] P1["Create Xendit Invoice
(amount + metadata)"] P2["Store invoice metadata"] P3["Return invoice_url to FE"] P4["User redirected to Xendit page"] P5["User bayar (VA / QRIS / Card / E-wallet)"] P6["Xendit processes payment"] P7["Xendit sends callback (webhook)"] end subgraph WEBHOOK["5. Callback Handler"] W1["Verify Xendit callback signature
(callback token)"] W2["Idempotency check
(prevent duplicate callback)"] W3["Update order status
PENDING → PAID"] W4["Release inventory lock
→ CONFIRMED"] W5["Generate invoice/receipt"] end subgraph NOTIFICATIONS["6. Notification System"] N1["Send email to customer
(confirmation + receipt)"] N2["Send email to admin
(new booking alert)"] N3["Send WhatsApp notif
(opsional)"] N4["Update real-time dashboard"] end subgraph FAILURE["7. Failure Handling"] X1["Card declined →
update status: FAILED"] X2["Release inventory lock"] X3["Send failure email"] X4["Log for audit trail"] X5["Webhook timeout →
retry mechanism"] X6["Inventory conflict →
race condition handler"] end F1 --> F2 --> F3 --> F4 F4 --> A1 A1 --> A2 --> A3 --> A4 A4 --> B1 B1 --> B2 --> B3 --> B4 --> B5 --> B6 B6 --> P1 P1 --> P2 --> P3 --> P4 --> P5 --> P6 --> P7 P7 --> W1 W1 --> W2 --> W3 --> W4 --> W5 W5 --> N1 --> N2 --> N3 --> N4 B1 -.->|"Sold out"| X4 B2 -.->|"Conflict detected"| X6 P6 -.->|"Card declined"| X1 --> X2 --> X3 --> X4 W1 -.->|"Invalid signature"| X4 W1 -.->|"Webhook timeout"| X5 --> X4 style B1 fill:#FEF3C7,stroke:#F59E0B,stroke-width:2px style B2 fill:#FEF3C7,stroke:#F59E0B,stroke-width:2px style W1 fill:#FEF3C7,stroke:#F59E0B,stroke-width:2px style W2 fill:#FEF3C7,stroke:#F59E0B,stroke-width:2px style X1 fill:#FEE2E2,stroke:#DC2626,stroke-width:2px style X4 fill:#FEE2E2,stroke:#DC2626,stroke-width:2px style X6 fill:#FEE2E2,stroke:#DC2626,stroke-width:2px style N1 fill:#D1FAE5,stroke:#059669,stroke-width:2px
Backend steps: 30+ Failure paths: 6+ Actual complexity: HIGH

Kontras: User vs Backend

Satu aksi user = banyak proses tersembunyi.

User melihat:

  • 1 klik "Book Now"
  • 1 form pengisian
  • 1 pembayaran
  • 1 email konfirmasi
  • ~3-5 menit total

Backend eksekusi:

  • 7+ validation checks
  • 4+ middleware layers
  • 6+ business logic steps
  • 7+ Xendit API calls
  • 6+ callback handlers
  • 4+ notification triggers
  • 6+ failure scenarios
  • ~500ms - 3s response time

Audit Trail & Compliance

Setiap transaksi harus bisa di-trace. Ini requirement untuk financial audit dan dispute resolution.

flowchart TD subgraph AUDIT["Data yang harus tercatat untuk setiap booking"] D1["Timestamp setiap state change"] D2["User ID + IP address + user agent"] D3["Product ID + harga + qty saat pembelian"] D4["Xendit Invoice ID + payment ID"] D5["Callback event ID + signature"] D6["Error logs kalau ada failure"] D7["Email delivery status"] D8["Admin action logs
(siapa ubah status order)"] end D1 --> LOG["Centralized Log Storage"] D2 --> LOG D3 --> LOG D4 --> LOG D5 --> LOG D6 --> LOG D7 --> LOG D8 --> LOG LOG --> RETENTION["Log Retention:
7 tahun (Indonesia tax)"] style LOG fill:#FEF3C7,stroke:#F59E0B,stroke-width:2px style RETENTION fill:#FEE2E2,stroke:#DC2626,stroke-width:2px

Kenapa audit trail penting:

  • Tax compliance: DJP bisa minta data transaksi 7 tahun ke belakang
  • Dispute resolution: Customer klaim tidak pernah booking → butuh proof
  • Fraud detection: Pattern pembayaran aneh → butuh traceable logs
  • Reconciliation: Xendit payout vs internal records harus match
  • Debug: Kalau ada bug, harus bisa replay exact sequence of events

What Could Go Wrong (Edge Cases)

Platform tidak cuma handle "happy path". Harus support semua scenario ini.

1
Double booking: 2 user klik "Book Now" untuk slot terakhir secara bersamaan. Harus ada inventory lock dengan timeout.
2
Callback timeout/delay: Xendit kirim callback tapi server down 10 menit. Order stuck di PENDING. Butuh retry mechanism + polling fallback.
3
Card declined setelah inventory lock: Slot di-lock tapi pembayaran gagal. Lock harus auto-release dalam 15 menit.
4
Callback duplicate: Xendit kirim callback 2x untuk 1 event. Butuh idempotency key check sebelum process.
5
Harga berubah saat checkout: Owner update harga setelah user klik "Book Now" tapi sebelum bayar. Sistem harus snapshot harga saat order dibuat.
6
Refund parsial: User booking untuk 3 orang, 1 orang cancel. Butuh partial refund logic + update inventory.
7
Timezone chaos: User booking dari London (GMT) untuk experience di Bali (WIB). Semua timestamp harus UTC storage + local display.
8
Email tidak terkirim: Konfirmasi email masuk spam atau SMTP down. Butuh email queue + retry + fallback.

Effort Breakdown per Component

Distribusi kerja teknis untuk build platform e-commerce.

flowchart LR subgraph EFFORT["Effort Distribution"] direction TB E1["Frontend UI
~30%"] E2["Auth & Security
~10%"] E3["Payment & Callbacks
~25%"] E4["Admin Dashboard
~20%"] E5["Testing & Edge Cases
~15%"] end style E3 fill:#FEF3C7,stroke:#F59E0B,stroke-width:2px style E5 fill:#FEE2E2,stroke:#DC2626,stroke-width:2px

Key insight untuk client:

  • 40% effort bukan fitur "kelihatan" — tapi payment, security, edge cases, testing
  • Xendit integration = 25% effort total (bukan cuma "pasang tombol"); termasuk callback handler, retry, idempotency, multi-payment method (VA/QRIS/Card/E-wallet), audit trail
  • Testing edge cases = 15% effort; tanpa ini, production bisa kacau
  • User lihat 10 langkah simple → sistem jalankan 30+ logic blocks + 8+ failure scenarios