Elixir untuk Technical Leader — Bab 10 dari 11
Kamu bukan coder. Kamu CEO yang punya senior engineer 24/7. Bab ini ngajarin cara ngasih arahan yang bikin hasil-nya bagus — dan cara nangkep kalau hasilnya jelek.
Hubungan kamu dengan Claude bukan "user dan chatbot". Ini hubungan kerja antara CEO dan senior engineer. Bedakan perannya:
| Peran Kamu (CEO) | Peran Claude (Senior Engineer) |
|---|---|
| Tentukan APA yang harus dibangun | Tentukan BAGAIMANA cara membangunnya |
| Review apakah hasilnya benar | Tulis code + test + deploy |
| Tangkap red flag di kualitas | Ikuti rules yang sudah kamu tetapkan |
| Keputusan bisnis final | Eksekusi keputusan teknis |
| Tau KENAPA fitur ini penting | Tau CARA implementasi yang benar |
Tiga keterampilan inti yang kamu perlu kuasai:
Ketiga hal ini gak butuh kemampuan coding. Ini butuh kemampuan berpikir sistematis — yang kamu sudah punya sebagai founder yang ngerti bisnisnya.
Instruksi yang bagus = hasil yang bagus. Instruksi yang vague = hasil yang asal. Ini perbedaannya:
Kamu gak perlu diktein code-nya. Tapi kamu HARUS spesifik soal business requirement-nya.
"bikin fitur order"
Terlalu vague. Order apa? CRUD? Import? Ship? Claude bakal asumsi sendiri — dan asumsinya belum tentu bener.
"bikin function ship_order yang atomic:
1. validasi status = dikemas
2. update status jadi dikirim
3. potong stok pakai FEFO
4. generate jurnal penjualan + HPP
5. insert audit trail
Return {:ok, result} atau {:error, reason}
Harus ada test untuk happy path
dan edge case (status bukan dikemas,
stok gak cukup)."
5 langkah jelas. Error handling jelas. Test requirement jelas. Claude tau persis apa yang harus dibangun.
"fix bug di pesanan"
Bug yang mana? Di function apa? Behavior-nya gimana?
"ship_order crash kalau order gak punya
items. Error: (Ecto.QueryError) ...
Tambah validasi: kalau items kosong,
return {:error, :no_items} SEBELUM
mulai transaction. Jangan sampai
stok terpotong tanpa ada items."
Bug spesifik. Error message ada. Solusi yang diharapkan jelas. Edge case dicegah.
"update halaman produk, tambah
field harga jual"
Claude harus cari sendiri file-nya, bisa salah file.
"baca lib/lababersih/inventory/product.ex
dulu. Tambah field :harga_jual (decimal)
di schema + changeset. Lalu update
produk_form_live.ex, tambah input field
harga jual di bawah harga modal.
Baca design-system.md untuk pattern
CurrencyInput."
File path jelas. Field name + type jelas. UI placement jelas. Reference ke design system.
"bikin halaman laporan keuangan"
Claude mungkin bikin logic kalkulasi di LiveView (melanggar aturan).
"bikin halaman laporan keuangan.
Backend sudah ada: income_statement/3
dan balance_sheet/2 di Accounting.
UI HANYA panggil function dari context.
JANGAN bikin logic kalkulasi di LiveView.
JANGAN bikin query langsung di LiveView.
Ikuti pattern tree view dari
design-system-pages.md section 8a."
Apa yang sudah ada. Apa yang perlu dibangun. Apa yang DILARANG. Reference ke design system.
"bikin fitur opname stok, pemusnahan,
mutasi, dan monitoring. Sekalian
tambah stat cards di semua halaman.
Oh iya, fix juga bug di dashboard."
4+ hal sekaligus. Claude bakal kacau, output gak fokus, susah di-review.
"Kita kerjakan opname stok dulu.
Step 1: bikin migration untuk tabel
opname_sessions dan opname_items.
Baca gap-closure-plan.md section Part B
untuk schema yang sudah di-design.
Setelah migration jalan, baru lanjut
ke step 2 (schema)."
1 fitur. 1 step. Jelas kapan selesai. Reference ke plan yang sudah ada.
Ini senjata rahasia kamu. CLAUDE.md dan file-file di .claude/rules/ adalah instruksi permanen yang Claude baca SETIAP kali session dimulai. Ini kayak SOP perusahaan — karyawan baca dan ikuti.
# File yang Claude SELALU baca:
CLAUDE.md # "Undang-undang" utama
.claude/rules/business-rules.md # Detail layer, status, FIFO
.claude/rules/design-system.md # Aturan UI/UX
.claude/rules/naming-convention.md # Aturan penamaan
.claude/rules/journal-formulas.md # 14 formula jurnal
.claude/rules/id-generation.md # Format ID + advisory lock
.claude/rules/pipeline-design.md # 3-track status pipeline
.claude/rules/gap-closure-plan.md # Plan migrasi v1 ke v2
... dan lainnya
Tanpa CLAUDE.md, setiap kali kamu mulai session baru, kamu harus ulang semua instruksi dari awal. Dengan CLAUDE.md:
Kalau kamu nemuin masalah berulang (misal: Claude terus bikin badge pakai Tailwind class padahal harusnya inline style), tambahin ke CLAUDE.md atau rules file yang relevan:
# Contoh penambahan di design-system.md:
JANGAN:
- Badge pakai Tailwind classes (badge-success dll) - HARUS inline style
- Badge pakai warna di luar 5 emerald-harmonic
# Setelah ini ditambahkan, Claude gak akan ulangi kesalahan itu lagi.
Ini perbaikan sistemik, bukan perbaikan per-kasus. Satu kali tulis, selamanya berlaku.
Setiap kali Claude selesai bikin sesuatu, jalankan checklist ini. Kamu gak perlu baca code-nya baris per baris — cukup tanya pertanyaan-pertanyaan ini:
| # | Pertanyaan | Jawaban yang Benar | Red Flag |
|---|---|---|---|
| 1 | Ada test-nya? | Ya, happy path + edge case | "Belum, nanti aja" |
| 2 | Test pass? | mix test → 0 failures |
Ada failure yang di-skip |
| 3 | Compile clean? | mix compile → 0 warnings |
Ada warning yang diabaikan |
| 4 | Pakai Repo.transaction? | Ya, untuk semua operasi multi-step | Multi-step tanpa transaction |
| 5 | org_id di query? | Semua query filter by org_id | Query tanpa org_id = data bocor |
| 6 | Logic di mana? | Di context (lib/lababersih/...) | Logic di LiveView file |
| 7 | Return format? | {:ok, result} atau {:error, reason} |
Pakai raise/throw untuk bisnis logic |
| 8 | Status pakai apa? | Pattern matching (def + def) | if-else bertingkat |
| 9 | Money pakai tipe apa? | Decimal | Float (bisa kehilangan presisi) |
| 10 | Ada @doc / @moduledoc? | Ya, di setiap module dan function publik | Function tanpa dokumentasi |
| 11 | Naming convention? | snake_case functions, PascalCase modules | Nama inkonsisten atau gak jelas |
| 12 | Error message jelas? | Bahasa user: "Stok tidak cukup (ada: 3, butuh: 5)" | "constraint violation" atau pesan teknis |
| 13 | Baca source dulu? | "Saya sudah baca file X sebelum mulai" | Nulis ulang dari ingatan |
| 14 | Sesuai design system? | Pakai shared components, badge inline style | Style custom per halaman |
| 15 | Idempotent? | Operasi yang sama 2x = aman (skip, bukan error) | Operasi yang sama 2x = data ganda |
Kamu gak perlu baca semua code. Tapi kamu harus bisa mengenali pola yang salah. Ini red flags yang harus bikin kamu bilang "STOP, ini salah":
# Kamu baca nama file: lib/lababersih_web/live/app/order_live.ex
# Di dalamnya ada kode kayak gini:
def handle_event("ship", _, socket) do
order = Repo.get!(Order, id) # SALAH! Query langsung di LiveView
lots = Repo.all(from l in Lot, ...) # SALAH! Logic FEFO di LiveView
# ... 50 baris logic kalkulasi ...
end
# Ini SALAH. Logic harus di context.
# Yang BENAR:
def handle_event("ship", _, socket) do
case Orders.ship_order(id, email) do # Panggil context, 1 baris
{:ok, result} -> ...
{:error, reason} -> ...
end
end
*_live.ex). Kalau ada kata Repo. di dalam file itu → STOP. LiveView gak boleh sentuh database langsung. Semua lewat context.
# Claude bilang: "function create_opname_session sudah jadi"
# Kamu tanya: "ada test-nya?"
# Claude bilang: "belum, saya tambahkan nanti"
# STOP. "Nanti" = gak pernah.
# Suruh bikin test SEKARANG sebelum lanjut.
# Ini BAHAYA (data bocor antar organisasi):
def list_orders do
Repo.all(Order) # SEMUA order dari SEMUA org! Security hole.
end
# Yang BENAR:
def list_orders(org_id) do
Order
|> where([o], o.org_id == ^org_id) # Filter by org
|> Repo.all()
end
# BAHAYA: floating point gak presisi untuk uang
total = 0.1 + 0.2 # = 0.30000000000000004 (BUKAN 0.3!)
# Yang BENAR: pakai Decimal
total = Decimal.add(~d"0.1", ~d"0.2") # = 0.3 (tepat)
# BAHAYA: kalau step 3 gagal, step 1-2 sudah kejalankan!
def ship_order(id) do
update_status(id, "dikirim") # step 1 - sudah jalan
deduct_stock(id) # step 2 - sudah jalan
create_journal(id) # step 3 - GAGAL! Tapi stok sudah terpotong!
end
# Yang BENAR: semua dalam 1 transaction
def ship_order(id) do
Repo.transaction(fn ->
update_status(id, "dikirim")
deduct_stock(id)
create_journal(id)
# Kalau APAPUN gagal → SEMUA rollback. Aman.
end)
end
# JELEK: if-else chain — susah dibaca, mudah bug
if status == "dibuat" do
if payment == "unpaid" do
if items != [] do
# nested 3 level... masih ada lagi?
end
end
end
# BAGUS: pattern matching — flat, jelas, exhaustive
case {status, payment, items} do
{"dibuat", "unpaid", [_ | _]} -> # ada items
{"dibuat", "unpaid", []} -> {:error, :no_items}
{"dibuat", _, _} -> {:error, :already_paid}
{status, _, _} -> {:error, {:invalid_status, status}}
end
Repo. di file *_live.ex → logic harus pindah ke contextorg_id → security hole multi-tenantFloat untuk uang → harus DecimalRepo.transaction → data corruption riskif-else bertingkat untuk status → harus pattern matchingraise / throw untuk business logic → harus {:error, reason}Ini urutan yang WAJIB diikuti setiap kali bikin fitur baru. Gak boleh loncat.
# Urutan per fitur (WAJIB sequential):
1. SCHEMA # Database migration + Ecto schema
2. CONTEXT # Business logic functions
3. TEST # ExUnit tests (happy + error + edge)
4. SEED # Test data untuk development
5. REVIEW # Kamu review — cocokkan dengan business rules
6. LIVEVIEW # UI (TERAKHIR, bukan pertama)
# Kenapa urutan ini?
# - Schema dulu: fondasi. Kalau struktur salah, semua salah.
# - Context sebelum UI: logic HARUS jalan tanpa UI.
# - Test sebelum UI: bukti bahwa logic benar.
# - UI terakhir: UI cuma "kulit". Kalau logic benar, UI tinggal panggil.
# Session 1: Schema + Context
Kamu: "Kita bikin fitur stok opname. Baca gap-closure-plan.md Part B.
Mulai dari step B1: migration."
Claude: [bikin migration file]
Kamu: "Jalankan mix ecto.migrate, tunjukin hasilnya."
Claude: [migration success]
Kamu: "Lanjut step B2: schema files."
Claude: [bikin 4 schema files]
Kamu: "mix compile, tunjukin hasilnya."
Claude: [compile clean]
Kamu: "Lanjut step B3: context functions."
# Session 2: Test + Review
Kamu: "Bikin test untuk semua function opname. Baca checklist di Part B."
Claude: [bikin test file]
Kamu: "Jalankan mix test, tunjukin hasilnya."
Claude: [7 tests, 0 failures]
Kamu: "Review: complete_opname yang selisih kurang — jurnal-nya
Dr. Beban Selisih Stok / Cr. Persediaan kan? Tunjukin."
Claude: [tunjukin code jurnal]
Kamu: "Oke benar. Lanjut UI."
# Session 3: UI
Kamu: "Bikin halaman opname list dan opname detail.
Baca design-system.md untuk pattern list page.
Jangan bikin logic di LiveView."
Hal-hal akan break. Bug pasti muncul. Ini cara kerja sama dengan Claude untuk fix:
Jangan parafrase error. Copy-paste persis seperti yang muncul.
"mix test gagal di test opname"
Gagal yang mana? Error-nya apa?
"mix test gagal:
1) test complete_opname/2 adjusts
stock for shortage
(WarehouseOperationsTest)
** (Ecto.ConstraintError)
constraint error when attempting
to insert struct:
* opname_items_session_id_fkey
at test/warehouse_operations_test
.exs:142"
Error lengkap. File. Line number. Constraint name. Claude bisa langsung diagnosa.
# Template debug yang bagus:
"Masalah: setelah complete_opname, stok produk gak berubah.
Expected: stok dari 100 jadi 95 (selisih -5)
Actual: stok tetap 100
Function yang dipanggil: Inventory.WarehouseOperations.complete_opname/2
File: lib/lababersih/inventory/warehouse_operations.ex
Baca file itu dan trace logic-nya. Kenapa stok gak turun?"
# Kalau bug complex (misal: HPP salah):
"HPP untuk order PS2603-00042 harusnya Rp 135.000 tapi ternyata Rp 90.000.
Trace alur FEFO consume untuk order ini:
1. Produk apa yang di-order?
2. Lot mana yang di-consume?
3. Cost per unit tiap lot berapa?
4. Total HPP dihitung dari mana?
Baca consume_lots di inventory.ex dan lot_consumption di order context."
Jangan kirim 5 bug sekaligus. Fix satu, test, baru lanjut ke berikutnya. Kalau gak, fix yang satu bisa bikin bug baru di yang lain.
| Kesalahan | Kenapa Terjadi | Cara Mencegah |
|---|---|---|
| Over-engineering Menambahkan fitur yang gak diminta |
Claude cenderung "helpful" berlebihan — nambah caching, pagination, sorting yang belum perlu | "HANYA bikin yang saya minta. Jangan tambah fitur lain. Kalau menurutmu perlu sesuatu tambahan, TANYA dulu." |
| Skip test "Test-nya nanti ya" |
Claude prioritaskan kecepatan deliver, kadang skip test | "Setiap function WAJIB punya test. Tunjukin mix test result sebelum lanjut." |
| Nulis dari ingatan Gak baca source file yang ada |
Claude kadang "ingat" versi lama dari file — tapi file sudah berubah | "BACA file X dulu sebelum mulai. JANGAN tulis ulang dari ingatan." |
| Gak cek pattern existing Bikin pattern baru padahal sudah ada |
Claude gak selalu cek bagaimana function serupa sudah di-implement | "Baca function list_orders di orders.ex — ikuti pattern yang sama untuk list_customers." |
| Asumsi tanpa data "Harusnya sekitar 10 kolom..." |
Claude kadang asumsi angka, jumlah, format tanpa verifikasi | "JANGAN asumsi angka. Tanya saya. Berapa kolom di XLSX TikTok? Berapa fee Shopee?" |
| Amend commit yang salah Kehilangan commit sebelumnya |
Setelah test gagal, Claude amend commit padahal seharusnya bikin commit baru | "Jangan amend. Selalu bikin commit baru setelah fix." |
Kalau kamu sudah nyaman dengan dasar-dasarnya, ini teknik yang bikin kolaborasi lebih efektif:
Force Claude membaca context sebelum nulis code. Ini mencegah dia nulis dari ingatan (yang bisa outdated).
# Contoh:
"Baca lib/lababersih/orders/orders.ex dulu.
Perhatikan function ship_order.
Sekarang bikin function cancel_order yang pattern-nya SAMA:
Repo.transaction, validasi status, update, audit trail."
Jangan percaya "sudah jadi" tanpa bukti. Minta output mix test.
# Contoh:
"Jalankan: mix test test/lababersih/inventory/warehouse_operations_test.exs
Tunjukin output-nya. Kalau ada failure, fix dulu baru lanjut."
Point Claude ke rules spesifik supaya dia gak improvisasi.
# Contoh:
"Baca rules/journal-formulas.md bagian A3 (RTS reverse penjualan).
Bikin function generate_rts_journal berdasarkan formula itu.
JANGAN improvisasi — ikuti formula persis."
Sebelum refactor, pastikan kamu tau dampaknya.
# Contoh:
"Cari semua tempat ship_order dipanggil di codebase.
Saya mau ubah parameter-nya — tunjukin semua caller yang perlu diupdate."
Enforce review di setiap layer boundary.
# Contoh:
"STOP. Sebelum bikin UI, saya mau review:
1. Tunjukin semua function baru yang kamu bikin
2. Tunjukin test coverage (berapa test, apa yang di-test)
3. Compile + test result
4. Baru kita lanjut ke LiveView"
Save progress secara berkala. Kalau langkah berikutnya gagal, kamu bisa rollback.
# Contoh:
"Migration dan schema sudah jadi. Commit sekarang dengan pesan:
'feat: add opname_sessions and opname_items tables'
Baru kita lanjut ke context functions."
Template siap pakai untuk situasi umum. Copy, ganti yang di dalam [kurung], paste ke Claude.
# TEMPLATE: FITUR BARU
Kita bikin fitur [NAMA FITUR].
Baca [FILE REFERENSI, misal: gap-closure-plan.md Part X].
Urutan:
1. Migration: [deskripsikan tabel/kolom baru]
2. Schema: [file path yang perlu dibuat/diupdate]
3. Context function:
- [function_name_1]: [apa yang dilakukan]
- [function_name_2]: [apa yang dilakukan]
4. Test: happy path + edge cases:
- [test case 1]
- [test case 2]
- [test case 3]
5. UI: [halaman apa, route apa]
Rules:
- Logic di context, BUKAN LiveView
- Semua function return {:ok, _} atau {:error, _}
- org_id di setiap query
- Repo.transaction untuk multi-step
- Ikuti naming convention di naming-convention.md
Mulai dari step 1 (migration). Tunjukin mix ecto.migrate result.
# TEMPLATE: BUG FIX
Bug: [deskripsi singkat]
Expected behavior: [apa yang seharusnya terjadi]
Actual behavior: [apa yang terjadi sekarang]
Error message (kalau ada):
[paste error message VERBATIM]
File yang relevan:
- [file path 1]
- [file path 2]
Langkah:
1. Baca file-file di atas DULU
2. Diagnosa kenapa bug terjadi
3. Fix
4. Tambah test case untuk bug ini (supaya gak terulang)
5. Jalankan mix test, tunjukin result
# TEMPLATE: UI BARU
Bikin halaman [NAMA HALAMAN].
Route: /app/[route]
File: lib/lababersih_web/live/app/[nama]_live.ex
Backend sudah ada:
- [Context.function_1] — sudah tested
- [Context.function_2] — sudah tested
Layout (ikuti design-system.md):
- Page header: "[Title]" + [Action buttons]
- Stat cards: [card 1] | [card 2] | [card 3] | [card 4]
- Tab filter: [tab 1] | [tab 2] | [tab 3]
- Table (max 7 kolom): [col1] | [col2] | ... | [col7]
- Pagination
Rules:
- ZERO logic di LiveView — semua panggil context
- Pakai shared components dari CoreComponents
- Badge pakai inline style (design-system.md section 6b)
- Bahasa Indonesia semua label
- Tambah nav link di sidebar
# TEMPLATE: REVIEW
Saya baru aja bikin [FITUR/PERUBAHAN]. Review dong:
1. Compile clean? (jalankan mix compile)
2. Test pass? (jalankan mix test)
3. Logic ada di context, bukan LiveView?
4. Semua function punya test?
5. Repo.transaction untuk multi-step?
6. org_id di setiap query?
7. Error message bahasa Indonesia?
8. Naming convention konsisten?
Kalau ada yang salah, list semua dan fix sekaligus.
Tunjukin mix test result setelah fix.
# TEMPLATE: REFACTOR
Refactor: [apa yang diubah]
Alasan: [kenapa perlu diubah]
Sebelum mulai:
1. Cari SEMUA tempat [function/module lama] dipanggil
2. List semua file yang akan terpengaruh
3. Tunjukin ke saya SEBELUM mulai ubah
Rules:
- JANGAN ubah behavior — hanya struktur
- Semua existing test HARUS tetap pass
- Bikin commit SEBELUM mulai refactor (safety net)
- Test setelah setiap perubahan, jangan batch
Ini bukan teori — ini instruksi yang benar-benar sudah kamu pakai dalam development LabaBersih v2:
# Instruksi aktual ke Claude:
"Bikin function ship_order(order_id, actor_email) di Orders context.
Atomic transaction, 5 langkah:
1. Get order, validasi status = dikemas
2. Update status jadi dikirim, set shipped_at = sekarang (WIB)
3. Per item: consume lots FEFO (potong stok)
4. Generate 2 jurnal:
- Penjualan: Dr. Piutang + Dr. Fees / Cr. Pendapatan (formula A1)
- HPP: Dr. HPP / Cr. Persediaan (dari lot consumption)
5. Insert audit trail
Kalau gagal di step manapun, rollback SEMUA.
Return {:ok, %{order, journal}} atau {:error, reason}.
Edge cases yang HARUS di-handle:
- Status bukan dikemas → {:error, {:invalid_status, status}}
- Items kosong → {:error, :no_items}
- Stok gak cukup → {:error, {:insufficient_stock, product, has, need}}
- Jurnal gak balance → {:error, :journal_not_balanced}
Baca journal-formulas.md section A1 untuk formula exact.
Baca business-rules.md section ship order untuk business rules."
Hasil: function yang sekarang handle 300 order/hari di production. Tested. Atomic. Zero data corruption.
# Setelah Claude bikin badge yang SALAH (pakai Tailwind class):
"STOP. Badge yang kamu bikin SALAH. Kamu pakai:
class='badge badge-success rounded-full text-xs'
Ini melanggar design-system.md section 6b.
Badge HARUS pakai inline style:
style='display:inline-flex;align-items:center;padding:4px 10px;
border-radius:999px;font-size:13px;font-weight:600;
background:#BCF1DD;color:#004E38;'
Baca design-system.md section 6b. Fix SEMUA badge di file ini.
Cari juga di file lain yang mungkin salah."
Hasil: setelah ini, aturan badge ditambahkan ke CLAUDE.md sebagai "JANGAN" permanent. Claude gak pernah ulangi lagi.
| Situasi | Gaya Instruksi | Contoh |
|---|---|---|
| Fitur baru yang complex | Panjang, detail, step-by-step | Template fitur baru di atas |
| Bug fix yang jelas | Pendek, langsung | "Error di line 42 file X: undefined function. Fix." |
| UI yang sudah ada pattern-nya | Referensi ke pattern | "Bikin halaman Y, ikuti pattern yang sama dengan halaman X." |
| Refactor | 2 step: analisis dulu, baru eksekusi | "Cari semua caller dulu, tunjukin, baru kita decide." |
| Lanjutkan session sebelumnya | Pendek, kontekstual | "Lanjut dari kemarin. Step terakhir: schema. Sekarang context." |
mix test dulu."mix compile → 0 warningsmix test → 0 failures@doc yang jelas{:ok, _} / {:error, _}Setiap kali kamu menemukan masalah yang berulang, jangan fix per kasus — fix di level sistem.
# Siklus perbaikan:
1. Claude bikin kesalahan (misal: badge pakai Tailwind class)
2. Kamu koreksi di session ini
3. Kamu tambahkan aturan di CLAUDE.md atau rules file:
"JANGAN: badge pakai Tailwind classes. HARUS inline style."
4. Session berikutnya: Claude baca aturan itu, gak ulangi kesalahan
# Ini COMPOUNDING IMPROVEMENT.
# Setiap minggu, CLAUDE.md makin lengkap.
# Claude makin jarang bikin kesalahan.
# Output makin konsisten.
10 bab sudah selesai. Ini yang sekarang kamu punya:
| Bab | Yang Kamu Tau |
|---|---|
| 1 | Kenapa Elixir + BEAM cocok untuk LabaBersih |
| 2 | Tipe data + pattern matching = cara baca code Elixir |
| 3 | Functions, modules, pipe = struktur code LabaBersih |
| 4 | Ecto = bagaimana data disimpan dan di-query |
| 5 | Phoenix + LiveView = bagaimana UI bekerja |
| 6 | OTP + concurrency = kenapa BEAM handle scale |
| 7 | Testing = jaminan kualitas |
| 8 | Deploy + ops = bagaimana code sampai ke production |
| 9 | Ecosystem + risk = dependency dan exit strategy |
| 10 | Driving Claude = cara efektif kolaborasi dengan AI |
Kamu bukan coder. Kamu technical leader. Dan itu artinya:
Kamu sekarang siap memimpin pengembangan LabaBersih. Selamat, Hafish.