Elixir untuk Technical Leader — Bab 11 (Bonus)
Kompetitor record data. LabaBersih harus record + analyze + recommend + act. Bab ini tentang bagaimana Elixir membuat itu mungkin dalam satu runtime — dan kapan lebih baik pakai Claude API.
Setiap hari, LabaBersih memproses 6.300 order. Dari setiap order, kita tahu:
Semua data ini sudah ada di database. Tapi data mentah itu gak ada gunanya kalau cuma disimpan.
Ada 4 level kematangan data:
| Level | Apa yang Dilakukan | Contoh LabaBersih |
|---|---|---|
| 1. Record | Simpan data | Order masuk ke database |
| 2. Analyze | Hitung metrik, lihat pattern | "RTS rate naik 3% minggu ini" |
| 3. Recommend | Kasih saran berdasarkan data | "Restock Forbest 200 unit, habis 5 hari lagi" |
| 4. Act | Otomatis ambil tindakan | Auto-hold paket RTS, auto-create PO draft |
Kebanyakan SaaS Indonesia masih di Level 1-2. Kalau LabaBersih bisa sampai Level 3-4, itu moat yang susah ditiru. Bukan karena teknologinya sulit — tapi karena butuh data historis + domain knowledge yang sudah kamu punya.
Sebelum kita bicara Elixir untuk intelligence, kita harus jujur tentang Python. Kenapa Python jadi bahasa #1 untuk AI/ML?
| Tahun | Apa yang Terjadi | Dampak |
|---|---|---|
| 2005 | NumPy rilis | Python jadi bahasa kalkulasi numerik yang accessible |
| 2007 | scikit-learn mulai | ML jadi bisa dipakai non-PhD |
| 2015 | TensorFlow (Google) | Deep learning jadi mainstream |
| 2016 | PyTorch (Facebook) | Peneliti pindah ke Python massal |
| 2020 | HuggingFace Transformers | Pre-trained model bisa dipakai siapa saja |
| 2022 | ChatGPT | LLM = new paradigm, Python tetap jadi interface utama |
20 tahun ekosistem. Puluhan ribu library. Jutaan tutorial. Ratusan ribu model pre-trained.
Tapi di sini ada nuansa penting yang sering diabaikan:
Python itu "glue language". Python sendiri lambat. Yang cepat adalah C, C++, dan CUDA di balik layar. NumPy ditulis di C. TensorFlow di C++. PyTorch di C++ dan CUDA. Python hanya memanggil kode yang sudah ditulis di bahasa lain.
# Python: "Hitung matriks 1000x1000"
# NumPy: [panggil C code yang sudah dioptimasi]
# Hasilnya: cepat, tapi bukan karena Python-nya
# Ini persis seperti:
# Python/Elixir: "Tolong bikinin jurnal"
# PostgreSQL: [query execution di C]
# Keduanya cuma pengirim instruksi ke engine yang lebih cepat
Insight ini penting karena: kalau bahasa lain bisa juga jadi "glue" ke engine yang sama, maka Python bukan satu-satunya pilihan untuk menjalankan model. Dan di sinilah cerita Nx dimulai.
Tahun 2021, Jose Valim (pencipta Elixir) mulai Nx — Numerical Elixir. Logikanya sederhana:
"Kalau Python bisa jadi glue ke C/CUDA, kenapa Elixir gak bisa jadi glue ke XLA (compiler yang sama yang dipake TensorFlow)?"
Dan ternyata bisa. Nx tidak mencoba menulis ulang engine numerik di Elixir. Nx memanggil engine yang sama yang dipakai Python:
# Python approach:
# Python code → NumPy → C/BLAS → CPU/GPU
# Python code → TensorFlow → XLA → CPU/GPU
# Elixir approach:
# Elixir code → Nx → EXLA → XLA → CPU/GPU
# Persis engine yang sama! Beda glue language doang.
Yang bikin ini menarik bukan kecepatan komputasinya (sama aja, karena engine-nya sama). Yang menarik adalah: satu runtime untuk web + ML.
Phoenix (Elixir) = web server
Flask/FastAPI (Python) = ML microservice
gRPC/HTTP = bridge antara keduanya
Docker = containerize Python service
Redis = cache/queue antara 2 service
5 moving parts.
Phoenix (Elixir) = web server
Nx.Serving = ML inference, jalan di process yang sama
1 runtime. 1 deploy. 0 microservice.
Nx bukan satu library. Ini ekosistem yang mirror Python ecosystem, tapi di atas BEAM:
| Elixir (Nx Ecosystem) | Python Equivalent | Fungsi |
|---|---|---|
| Nx | NumPy | Tensor (array multi-dimensi), operasi matematika. Fondasi semua yang lain. |
| EXLA | TensorFlow backend | Compiler ke XLA. Bikin komputasi Nx jalan di CPU/GPU dengan optimasi. |
| Explorer | Pandas | DataFrame. Analisis data tabular: filter, group, aggregate, join. |
| Axon | PyTorch | Definisi dan training neural network. Layer, optimizer, training loop. |
| Bumblebee | HuggingFace Transformers | Pre-trained model siap pakai: text classification, sentiment, summarization. |
| Scholar | scikit-learn | ML klasik: linear regression, clustering, PCA, normalization. |
| Nx.Serving | TorchServe / TF Serving | Inference server. Load model, batch request, serve prediction via HTTP. |
Explorer adalah library yang paling langsung berguna untuk LabaBersih. Ini seperti Pandas di Python — library untuk mengolah data tabular (tabel, spreadsheet, CSV).
Kenapa ini penting? Karena SEMUA analitik bisnis LabaBersih pada dasarnya adalah: ambil data dari database, olah, tampilkan insight.
alias Explorer.DataFrame, as: DF
alias Explorer.Series
# Ambil data order items dari database
order_data = Repo.all(
from oi in OrderItem,
join: o in Order, on: oi.order_id == o.id,
where: o.org_id == ^org_id and o.status == "selesai",
select: %{
sku: oi.sku,
product_name: oi.product_name,
quantity: oi.quantity,
revenue: oi.price
}
)
# Masukkan ke Explorer DataFrame
df = DF.new(order_data)
# Analisis: top 10 produk by total revenue
top_products =
df
|> DF.group_by("sku")
|> DF.summarise(
product_name: first("product_name"),
total_qty: sum("quantity"),
total_revenue: sum("revenue")
)
|> DF.sort_by(desc: "total_revenue")
|> DF.head(10)
# Output: DataFrame dengan 10 produk tertinggi revenue
# +-------+------------------+----------+--------------+
# | sku | product_name | total_qty| total_revenue|
# +-------+------------------+----------+--------------+
# | FRB01 | Forbest New 1kg | 2,340 | 105,300,000 |
# | RTN01 | Ritrina 1 Liter | 1,890 | 85,050,000 |
# | ... | ... | ... | ... |
# +-------+------------------+----------+--------------+
# Data: semua order yang sudah shipped
shipment_data = Repo.all(
from o in Order,
where: o.org_id == ^org_id and o.status in ["selesai", "rts"],
select: %{
courier: o.courier,
status: o.status,
total_harga: o.total_harga
}
)
df = DF.new(shipment_data)
rts_by_courier =
df
|> DF.group_by("courier")
|> DF.summarise(
total_orders: count("status"),
rts_count: sum(equal("status", "rts")),
total_value: sum("total_harga")
)
|> DF.mutate(rts_rate: divide("rts_count", "total_orders"))
|> DF.sort_by(desc: "rts_rate")
# Output:
# +---------+-------------+----------+-----------+----------+
# | courier | total_orders | rts_count| total_val | rts_rate |
# +---------+-------------+----------+-----------+----------+
# | ID Exp | 450 | 38 | 20,250,000| 8.4% | <-- MASALAH
# | SiCepat | 1,200 | 72 | 54,000,000| 6.0% |
# | JNE | 2,100 | 84 | 94,500,000| 4.0% |
# | J&T | 2,550 | 76 | 114,750,000| 3.0% | <-- BAGUS
# +---------+-------------+----------+-----------+----------+
# Combine: revenue (dari jurnal pendapatan) - HPP (dari jurnal HPP) - fees
monthly_data = Repo.all(monthly_summary_query)
df = DF.new(monthly_data)
margin_trend =
df
|> DF.group_by("month")
|> DF.summarise(
revenue: sum("revenue"),
hpp: sum("hpp"),
fees: sum("platform_fees")
)
|> DF.mutate(
gross_profit: subtract("revenue", "hpp"),
net_profit: subtract(subtract("revenue", "hpp"), "fees"),
margin_pct: divide("net_profit", "revenue")
)
# Output: tren margin 6 bulan terakhir
# Kalau margin turun dari 18% ke 12% → ada masalah yang harus di-investigate
Bumblebee adalah library Elixir untuk menjalankan pre-trained model dari HuggingFace. Artinya kamu bisa menjalankan model AI (text classification, sentiment analysis, summarization) langsung di Elixir, tanpa Python, tanpa API call.
# Contoh: sentiment analysis di Elixir
{:ok, model} = Bumblebee.load_model({:hf, "finiteautomata/bertweet-base-sentiment-analysis"})
{:ok, tokenizer} = Bumblebee.load_tokenizer({:hf, "vinai/bertweet-base"})
serving = Bumblebee.Text.text_classification(model, tokenizer)
# Jalankan sebagai Nx.Serving (GenServer) di Phoenix app
Nx.Serving.run(serving, "Produk bagus, pengiriman cepat!")
# => %{predictions: [%{label: "POS", score: 0.97}]}
Kedengarannya keren. Tapi saya harus jujur.
| Skenario | Cocok? | Alasan |
|---|---|---|
| Klasifikasi high-volume (1000+ req/detik) | Cocok | Gak bayar per-call. Model jalan lokal. Latency rendah. |
| Offline / air-gapped environment | Cocok | Gak butuh internet. Model di-download sekali. |
| Simple classification (spam/not spam, sentiment +/-) | Cocok | Model kecil (BERT-base) cukup. Gak butuh GPT-level intelligence. |
| Complex reasoning, natural language insights | Kurang | Model kecil gak bisa "mikir". Butuh LLM besar (Claude, GPT). |
| LabaBersih: "kenapa margin turun?" insights | Kurang | Ini butuh reasoning + domain knowledge. Bumblebee gak bisa. |
| LabaBersih: 6.300 order/hari analysis | Overkill | 6.300 = kecil. SQL + Elixir cukup. Gak butuh ML model. |
Untuk LabaBersih, pendekatan yang paling masuk akal untuk Level 3 intelligence (recommend) adalah: kumpulkan data terstruktur, kirim ke Claude API, dapat insight natural language.
# Flow:
# 1. Elixir query database → data terstruktur
# 2. Format jadi prompt yang jelas
# 3. Kirim ke Claude API via Req (HTTP client)
# 4. Dapat response natural language
# 5. Tampilkan di dashboard LiveView
# Gak butuh GPU. Gak butuh Python. Gak butuh Docker.
# Cuma HTTP call dari Elixir ke API endpoint.
defmodule Lababersih.Intelligence.WeeklyInsight do
@moduledoc "Generate weekly business insight via Claude API"
def generate(org_id) do
# 1. Kumpulkan data minggu ini
data = collect_weekly_data(org_id)
# 2. Format jadi prompt
prompt = """
Kamu adalah analis bisnis untuk toko online Indonesia.
Analisis data 7 hari terakhir dan berikan 3-5 insight actionable.
Jawab dalam Bahasa Indonesia. Fokus pada:
- Tren yang perlu diperhatikan
- Masalah yang harus segera ditangani
- Peluang yang bisa dimanfaatkan
DATA:
Total order: #{data.total_orders}
Revenue: Rp #{data.revenue}
RTS count: #{data.rts_count} (#{data.rts_rate}%)
Top produk: #{inspect(data.top_products)}
Kurir bermasalah: #{inspect(data.worst_couriers)}
Margin rata-rata: #{data.avg_margin}%
Stok rendah: #{inspect(data.low_stock_products)}
Perbandingan minggu lalu: revenue #{data.revenue_change}%
"""
# 3. Kirim ke Claude API
{:ok, response} = call_claude_api(prompt)
# 4. Return insight
{:ok, response.body["content"]}
end
defp call_claude_api(prompt) do
Req.post("https://api.anthropic.com/v1/messages",
headers: [
{"x-api-key", System.get_env("ANTHROPIC_API_KEY")},
{"anthropic-version", "2023-06-01"},
{"content-type", "application/json"}
],
json: %{
"model" => "claude-sonnet-4-20250514",
"max_tokens" => 1024,
"messages" => [%{"role" => "user", "content" => prompt}]
}
)
end
defp collect_weekly_data(org_id) do
# Query semua metrik dari database
# Return struct dengan semua angka yang dibutuhkan
%{
total_orders: Orders.count_this_week(org_id),
revenue: Orders.revenue_this_week(org_id),
rts_count: Returns.count_this_week(org_id),
# ... dst
}
end
end
| Penggunaan | Estimasi Token | Biaya (Claude Sonnet) |
|---|---|---|
| Weekly insight (1x/minggu) | ~2.000 token | ~$0.02/call = $0.08/bulan |
| Daily alert (1x/hari) | ~1.000 token | ~$0.01/call = $0.30/bulan |
| On-demand analysis (10x/bulan) | ~3.000 token | ~$0.03/call = $0.30/bulan |
| Total | ~$0.70/bulan = Rp 11.000 |
Sebelas ribu rupiah per bulan untuk insight yang bisa save Rp 3.8 juta dari RTS saja. ROI-nya absurd.
Gak semua intelligence butuh AI. Ini arsitektur berlapis yang pragmatis:
Ini fondasi. Gak butuh library tambahan. Cuma query database + logic Elixir biasa.
# Contoh: Reorder alert
def products_needing_reorder(org_id) do
from(p in Product,
where: p.org_id == ^org_id,
where: p.stok <= 10, # threshold sederhana
where: p.is_active == true,
order_by: [asc: p.stok],
select: %{name: p.name, sku: p.sku, stok: p.stok}
)
|> Repo.all()
end
# Contoh: ABC classification
def abc_classification(org_id) do
products = list_products_by_revenue(org_id)
total_revenue = Enum.sum(Enum.map(products, & &1.revenue))
products
|> Enum.reduce({[], 0}, fn product, {acc, cumulative} ->
new_cumulative = cumulative + product.revenue
pct = new_cumulative / total_revenue * 100
class = cond do
pct <= 80 -> "A" # Top 80% revenue
pct <= 95 -> "B" # Next 15%
true -> "C" # Bottom 5%
end
{[Map.put(product, :class, class) | acc], new_cumulative}
end)
|> elem(0)
|> Enum.reverse()
end
Apa yang bisa dilakukan Level 1:
Satu level di atas. Pakai Explorer untuk analisis yang lebih sophisticated:
# Moving average untuk demand forecasting
def demand_forecast(org_id, product_id, window \\ 14) do
# Ambil demand 30 hari terakhir
daily_demand = get_daily_demand(org_id, product_id, 30)
df = Explorer.DataFrame.new(daily_demand)
# Hitung 14-day moving average
df
|> DF.mutate(
ma_14: window_mean("qty_sold", window),
std_14: window_standard_deviation("qty_sold", window)
)
|> DF.mutate(
# Safety stock = 2 standard deviations
safety_stock: multiply("std_14", 2),
# Reorder point = (daily avg * lead time) + safety stock
reorder_point: add(
multiply("ma_14", 7), # lead time 7 hari
multiply("std_14", 2)
)
)
end
Apa yang bisa dilakukan Level 2:
Paling atas. Kirim data terstruktur dari Level 1-2, dapat insight natural language.
# Combine semua data → kirim ke Claude → dapat insight
def generate_daily_brief(org_id) do
# Level 1 data
low_stock = products_needing_reorder(org_id)
rts_alert = courier_rts_rates(org_id)
abc = abc_classification(org_id)
# Level 2 data
margin_trend = margin_trend_30d(org_id)
demand_spikes = detect_demand_spikes(org_id)
# Level 3: Claude bikin narasi dari semua data
prompt = build_daily_brief_prompt(%{
low_stock: low_stock,
rts_alert: rts_alert,
abc: abc,
margin_trend: margin_trend,
demand_spikes: demand_spikes
})
call_claude_api(prompt)
end
Yang paling penting: ketiga level ini jalan di satu Phoenix application. Level 1 = Ecto query. Level 2 = Explorer di proses Elixir. Level 3 = HTTP call ke API. Gak ada microservice, gak ada Python server terpisah, gak ada Docker container tambahan.
Ini bagian yang paling penting di bab ini. Intelligence yang bagus butuh data yang bagus. Dan struktur data harus benar dari awal — bukan di-retrofit nanti.
# Rekam demand harian per produk per gudang
# Ini bahan baku untuk forecasting, ABC-XYZ, spike detection
create table(:demand_snapshots) do
add :org_id, # siapa
add :product_id, # produk apa
add :warehouse_id, # gudang mana
add :date, # tanggal berapa
add :qty_ordered, # berapa yang dipesan
add :qty_shipped, # berapa yang dikirim
add :source_breakdown, :map # %{"tiktok" => 15, "shopee" => 8}
add :is_spike, # true kalau > 2x moving average
end
# Unique per org + product + warehouse + date
# Diisi oleh Oban job setiap malam (23:59 WIB)
Kenapa penting: Tanpa tabel ini, setiap kali mau analisis demand, kamu harus query orders + order_items + aggregate on-the-fly. Dengan snapshot, datanya sudah pre-computed dan bisa di-query langsung.
# SETIAP event penting harus punya timestamp yang jelas:
orders:
:platform_order_date # kapan customer pesan (dari platform)
:imported_at # kapan masuk ke LabaBersih
:shipped_at # kapan dikirim (event date, bukan process date!)
:delivered_at # kapan sampai
:settled_at # kapan uang cair
return_records:
:rts_detected_at # kapan RTS terdeteksi
:rts_resolved_at # kapan RTS selesai (returned / saved)
# SEMUA dalam WIB. SEMUA diisi. JANGAN ada yang null
# kalau event-nya sudah terjadi.
Kenapa penting: "Days to cash" = settled_at - shipped_at. "RTS response time" = rts_resolved_at - rts_detected_at. Kalau salah satu timestamp kosong, metrik ini gak bisa dihitung.
# Di tabel customers (sudah di-design):
customers:
:total_orders # gak perlu COUNT(*) setiap query
:total_spent # gak perlu SUM() setiap query
:total_rts # langsung tau RTS rate per customer
:last_order_at # langsung tau kapan terakhir beli
# Di tabel products:
products:
:stok # sudah denormalized (sum dari lots)
:reserved_stock # sudah di-design
# Aturan: update counter saat event terjadi (bukan query saat butuh)
# Order masuk → customer.total_orders += 1
# RTS terdeteksi → customer.total_rts += 1
Kenapa penting: Untuk dashboard real-time dan sorting (top customers, worst RTS rate), denormalized counter = instant query. Tanpa ini, setiap dashboard load = heavy aggregation.
# Saat ini: fee estimasi dihitung on-the-fly dari store.fee_mapping
# Problem: kalau fee_mapping berubah, estimasi lama ikut berubah
# Solusi: simpan fee breakdown per order saat ship
# Di journal_entry_lines (sudah ada order_id field):
# Setiap line punya: account_code, debit, credit, order_id
# Dari sini bisa reconstruct: per order, fee apa saja, berapa
# Ini sudah di-design di daily summary journal architecture:
# 1 jurnal per toko per hari, lines per order
# Jadi fee breakdown per order = gratis dari journal lines
# Setiap order HARUS punya source:
orders:
:source # "xlsx" / "api_tiktok" / "api_shopee" / "manual" / "webhook_scalev"
# Kenapa: attribution analysis
# "Berapa % order masuk dari XLSX vs API?"
# "Apakah order dari API lebih akurat (kurang RTS)?"
# "Channel mana yang paling banyak cancel?"
Ini bukan debat "mana yang lebih baik secara umum" (gak ada gunanya). Ini penilaian spesifik untuk apa yang LabaBersih butuh:
| Kebutuhan | Python | Elixir | Untuk LabaBersih |
|---|---|---|---|
| Training model baru (bikin model custom) |
Menang telak PyTorch, paper implementation, GPU toolkit |
Kalah Axon ada tapi ekosistemnya kecil |
Gak butuh. LabaBersih gak training model. |
| Inference (jalankan model) (serve prediction) |
Bisa Flask/FastAPI + TorchServe |
Menang Nx.Serving = GenServer, jalan bareng web |
Kalau butuh nanti, Nx.Serving lebih simple (1 runtime). |
| Business analytics (SQL + aggregation) |
Bisa Pandas + SQLAlchemy |
Menang Ecto + Explorer, sudah ada di stack |
Elixir sudah di stack. Gak perlu tambah Python. |
| LLM integration (Claude/GPT API) |
Bisa requests + anthropic SDK |
Sama bagusnya Req HTTP client |
HTTP call. Bahasa apapun bisa. Elixir sudah di stack. |
| Real-time dashboard (live update) |
Kalah Butuh WebSocket tambahan (Socket.io dll) |
Menang telak LiveView = built-in real-time |
LiveView advantage. Dashboard update tanpa page refresh. |
| Background jobs (nightly batch, sync) |
Bisa Celery + Redis |
Menang Oban = built-in, 0 external dependency |
Oban sudah di stack. Demand snapshot = Oban job. |
Kamu pernah bilang "kamu jangan asal iya." Berikut penilaian jujur tentang apa yang hype dan apa yang nyata di ekosistem ini:
| Klaim | Status | Penjelasan |
|---|---|---|
| "Nx akan menggantikan Python untuk ML" | HYPE | Gak akan terjadi. Python punya 20 tahun ekosistem, jutaan model, ratusan ribu tutorial. Nx itu bagus, tapi menggantikan Python untuk ML research = delusi. |
| "Nx.Serving untuk production inference" | REAL | Sudah dipakai perusahaan seperti Veeps (streaming video), Hugging Face sendiri pakai Elixir untuk demo mereka. Inference di BEAM = proven. |
| "Explorer untuk business analytics" | REAL | Library solid, API mirip Pandas, maintainer aktif (Jose Valim sendiri). Untuk analisis data di Elixir app, ini pilihan terbaik. |
| "Bumblebee untuk SEMUA use case AI" | HYPE | Bumblebee bagus untuk offline inference model kecil. Tapi untuk reasoning, insights, natural language = Claude API 100x lebih pintar. Jangan pakai model 100MB kalau API call $0.01 kasih hasil 100x lebih bagus. |
| "Satu runtime untuk web + ML" | REAL | Ini genuine BEAM advantage. Gak ada bahasa lain yang bisa: web server + real-time WebSocket + background job + ML inference di satu process. Ini bukan marketing — ini arsitektur yang benar-benar lebih sederhana. |
| "Elixir lebih cepat dari Python untuk ML" | MISLEADING | Kecepatan compute = sama (keduanya glue ke C/CUDA). Yang lebih cepat = arsitekturnya. Gak ada network hop ke microservice terpisah = latensi lebih rendah. Tapi compute-nya identik. |
| "LabaBersih butuh ML model custom" | HYPE | 6.300 order/hari itu kecil untuk ML. SQL query + rule-based logic sudah cukup untuk 90% use case. Claude API untuk 10% sisanya. Custom model = Phase yang sangat jauh. |
Berdasarkan penilaian jujur di atas, ini timeline yang pragmatis:
Gak ada intelligence code. Tapi struktur data harus benar:
demand_snapshots table design + migration (sudah di blueprint)Implementasi analitik sederhana yang langsung berguna:
Semua ini = SQL query + Elixir logic. Zero ML. Zero API call. Zero tambahan cost.
Upgrade analitik dengan Explorer:
Layer teratas — natural language insight dari data:
Estimasi cost: < $1/bulan. ROI: berpotensi save jutaan rupiah per bulan dari insight yang actionable.
Kalau di masa depan LabaBersih butuh ML on-device (misal: real-time classification untuk 100.000 order/hari), begini caranya di Elixir:
# Di application.ex (startup)
children = [
# Web server
LababersihWeb.Endpoint,
# Background jobs
{Oban, Application.fetch_env!(:lababersih, Oban)},
# ML model serving (jalan di proses yang SAMA)
{Nx.Serving,
serving: build_sentiment_serving(),
name: Lababersih.SentimentServing,
batch_size: 16,
batch_timeout: 100
}
]
# Panggil dari mana saja di app:
Nx.Serving.batched_run(Lababersih.SentimentServing, "Produk bagus!")
# => %{label: "positive", score: 0.97}
# Auto-batching: kalau 50 request masuk dalam 100ms,
# Nx.Serving otomatis batch jadi 1 inference call.
# Ini optimasi yang di Python butuh setup TorchServe + queue.
Ini yang dimaksud "satu runtime." Web server, background jobs, dan ML inference jalan di application supervisor yang sama. Kalau model crash, supervisor restart. Kalau web server sibuk, ML serving tetap jalan di proses terpisah. BEAM handle semua ini secara native.
Di satu bab ini, kamu sudah tau lebih banyak tentang data intelligence daripada 99% SaaS founder di Indonesia. Bukan karena kamu baca teori — tapi karena kamu punya context yang gak dimiliki orang lain.
Kamu tau bahwa setiap RTS = Rp 80k-125k rugi. Kamu tau bahwa fee platform bisa berubah tanpa notice. Kamu tau bahwa seller Indonesia pecah bisnis ke beberapa entitas untuk tax planning. Kamu tau bahwa Mengantar itu COD offline, beda total dari Shopee.
Domain knowledge itu gak bisa di-copy. Kompetitor bisa copy fitur, tapi gak bisa copy pemahaman tentang kenapa fitur itu ada.
Dan sekarang kamu punya stack teknologi yang mendukung visi itu:
| Kemampuan | Stack | Status |
|---|---|---|
| Record data | Ecto + PostgreSQL | Sudah jalan (133+ tests) |
| Process data | Phoenix + Oban | Sudah jalan (daily journal batch) |
| Analyze data | Explorer (DataFrame) | Ready to use (Phase 3) |
| Serve predictions | Nx.Serving | Ready when needed |
| Generate insights | Claude API + Req | ~$1/bulan (Phase 4) |
| Display real-time | Phoenix LiveView | Sudah jalan |
| All in one runtime | BEAM/OTP | Already the foundation |
Path ke intelligence bukan tentang AI yang canggih. Ini tentang:
Setiap level dibangun di atas level sebelumnya. Gak ada shortcut. Tapi juga gak ada blocker teknologi — stack-nya sudah siap.
Fondasi sudah dibangun. Data mengalir. Intelligence tinggal dinyalakan. Ini jalan panjang, tapi kamu sudah di track yang benar.