Elixir untuk Technical Leader — Bab 10 dari 11

Driving Claude — The Collaboration Playbook

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.


Mindset: CEO + Senior Engineer

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 dibangunTentukan BAGAIMANA cara membangunnya
Review apakah hasilnya benarTulis code + test + deploy
Tangkap red flag di kualitasIkuti rules yang sudah kamu tetapkan
Keputusan bisnis finalEksekusi keputusan teknis
Tau KENAPA fitur ini pentingTau CARA implementasi yang benar
Yang kamu TIDAK perlu lakukan Kamu gak perlu bisa nulis code Elixir. Kamu gak perlu hafal syntax. Kamu perlu bisa: (1) menjelaskan apa yang kamu mau, (2) membaca output dan paham apakah masuk akal, (3) mengenali tanda-tanda kode yang buruk.

Tiga keterampilan inti yang kamu perlu kuasai:

  1. Define WHAT — jelaskan business requirement dengan detail yang cukup
  2. Review WHETHER — cek apakah hasil Claude sesuai harapan
  3. Catch RED FLAGS — kenali tanda-tanda code quality buruk

Ketiga hal ini gak butuh kemampuan coding. Ini butuh kemampuan berpikir sistematis — yang kamu sudah punya sebagai founder yang ngerti bisnisnya.


Cara Ngasih Instruksi yang Efektif

Instruksi yang bagus = hasil yang bagus. Instruksi yang vague = hasil yang asal. Ini perbedaannya:

Prinsip #1: Spesifik soal APA, bukan soal BAGAIMANA

Kamu gak perlu diktein code-nya. Tapi kamu HARUS spesifik soal business requirement-nya.

BURUK
"bikin fitur order"

Terlalu vague. Order apa? CRUD? Import? Ship? Claude bakal asumsi sendiri — dan asumsinya belum tentu bener.

BAGUS
"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.

Prinsip #2: Sebutin constraint dan edge case

BURUK
"fix bug di pesanan"

Bug yang mana? Di function apa? Behavior-nya gimana?

BAGUS
"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.

Prinsip #3: Referensikan file yang relevan

BURUK
"update halaman produk, tambah
field harga jual"

Claude harus cari sendiri file-nya, bisa salah file.

BAGUS
"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.

Prinsip #4: Sebutin apa yang JANGAN dilakukan

BURUK
"bikin halaman laporan keuangan"

Claude mungkin bikin logic kalkulasi di LiveView (melanggar aturan).

BAGUS
"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.

Prinsip #5: Satu instruksi, satu scope

BURUK
"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.

BAGUS
"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.


Sistem CLAUDE.md — Remote Control untuk AI

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.

Struktur file

# 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

Kenapa ini powerful

Tanpa CLAUDE.md, setiap kali kamu mulai session baru, kamu harus ulang semua instruksi dari awal. Dengan CLAUDE.md:

Analogi CLAUDE.md = buku pedoman karyawan. Rules files = SOP per departemen. Kamu tulis sekali, berlaku selamanya. Setiap "karyawan baru" (session Claude baru) langsung baca dan ikuti.

Cara update 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.


Review Checklist — 15 Pertanyaan Wajib

Setiap kali Claude selesai bikin sesuatu, jalankan checklist ini. Kamu gak perlu baca code-nya baris per baris — cukup tanya pertanyaan-pertanyaan ini:

#PertanyaanJawaban yang BenarRed 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
Tips: Cara tercepat pakai checklist ini Copy-paste kalimat ini ke Claude setelah dia selesai kerja: "Tunjukin hasil mix compile dan mix test. Lalu jawab checklist: (1) ada test? (2) pakai transaction? (3) org_id di query? (4) logic di context? (5) return {:ok}/{:error}?" — Lima pertanyaan ini sudah tangkap 80% masalah.

Red Flags — Tanda STOP dan Koreksi

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":

Red Flag #1: Logic di LiveView

# 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
Cara detect Buka file LiveView (*_live.ex). Kalau ada kata Repo. di dalam file itu → STOP. LiveView gak boleh sentuh database langsung. Semua lewat context.

Red Flag #2: Function tanpa test

# 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.

Red Flag #3: Query tanpa org_id

# 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

Red Flag #4: Float untuk uang

# 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)

Red Flag #5: Multi-step tanpa transaction

# 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

Red Flag #6: If-else bertingkat untuk status

# 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
Ringkasan Red Flags (cetak dan tempel di meja)

1. Repo. di file *_live.ex → logic harus pindah ke context
2. Function baru tanpa test → WAJIB bikin test sebelum lanjut
3. Query tanpa org_id → security hole multi-tenant
4. Float untuk uang → harus Decimal
5. Multi-step tanpa Repo.transaction → data corruption risk
6. if-else bertingkat untuk status → harus pattern matching
7. raise / throw untuk business logic → harus {:error, reason}
8. Hardcode warna/style di LiveView → harus pakai shared component

Development Cycle — Session by Session

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.

Contoh session flow

# 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."
Checkpoint review Setelah selesai 1 layer (misal: semua schema), kamu review sebelum lanjut ke layer berikutnya. Ini mencegah masalah menumpuk. Kalau ada yang salah di schema, lebih baik ketemu SEKARANG daripada setelah UI sudah jadi.

Cara Debug dengan Claude

Hal-hal akan break. Bug pasti muncul. Ini cara kerja sama dengan Claude untuk fix:

Aturan #1: Share error message VERBATIM

Jangan parafrase error. Copy-paste persis seperti yang muncul.

BURUK
"mix test gagal di test opname"

Gagal yang mana? Error-nya apa?

BAGUS
"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.

Aturan #2: Deskripsikan EXPECTED vs ACTUAL

# 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?"

Aturan #3: Minta Claude trace alur-nya

# 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."

Aturan #4: Satu bug per instruksi

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 Umum Claude — Yang Harus Kamu Waspadai

KesalahanKenapa TerjadiCara 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."

Power Moves — Teknik Lanjutan

Kalau kamu sudah nyaman dengan dasar-dasarnya, ini teknik yang bikin kolaborasi lebih efektif:

1. "Baca file X dulu sebelum mulai"

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."

2. "Tunjukin test result sebelum lanjut"

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."

3. "Baca business-rules.md section X"

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."

4. "Cari semua tempat function X dipanggil"

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."

5. "Jangan lanjut layer tanpa checkpoint"

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"

6. "Commit sekarang sebelum lanjut"

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 Instruksi — Copy-Paste

Template siap pakai untuk situasi umum. Copy, ganti yang di dalam [kurung], paste ke Claude.

Template: Fitur Baru

# 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

# 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: Halaman UI Baru

# 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 Request

# 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

# 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

Contoh Nyata dari LabaBersih

Ini bukan teori — ini instruksi yang benar-benar sudah kamu pakai dalam development LabaBersih v2:

Contoh 1: Ship Order (atomic 5 step)

# 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.

Contoh 2: Design System Enforcement

# 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.


Gaya Kerja yang Efektif

Kapan beri instruksi panjang vs pendek

SituasiGaya InstruksiContoh
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."

Kapan bilang "STOP"

Kapan bilang "Bagus, lanjut"


Feedback Loop — Cara Memperbaiki CLAUDE.md

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.
Ini keuntungan AI vs developer manusia Developer manusia bisa "lupa" SOP. Claude SELALU baca CLAUDE.md setiap session. Kalau kamu tulis aturannya dengan baik, compliance rate Claude = 100%. Yang kamu perlu lakukan: audit hasilnya, dan terus tambahkan aturan baru berdasarkan temuan.

Ringkasan — Bab 10

10 prinsip Driving Claude:

1. Kamu CEO, Claude senior engineer — kamu set direction, Claude eksekusi
2. Spesifik soal APA — business requirement detail, bukan instruksi coding
3. CLAUDE.md = remote control — aturan yang berlaku selamanya, bukan per-session
4. 15-point checklist — review setiap output tanpa perlu baca code
5. 8 red flags — kenali pola code yang salah dari nama file dan pattern
6. Schema, Context, Test, Seed, Review, LiveView — urutan WAJIB, gak boleh loncat
7. Share error verbatim — jangan parafrase, copy-paste exact
8. Waspadai over-engineering dan skip test — dua kesalahan Claude paling umum
9. Power moves — "baca file dulu", "tunjukin test result", "cari semua caller"
10. Perbaiki sistem, bukan kasus — setiap temuan masuk ke CLAUDE.md

Penutup — Kamu Siap

10 bab sudah selesai. Ini yang sekarang kamu punya:

BabYang Kamu Tau
1Kenapa Elixir + BEAM cocok untuk LabaBersih
2Tipe data + pattern matching = cara baca code Elixir
3Functions, modules, pipe = struktur code LabaBersih
4Ecto = bagaimana data disimpan dan di-query
5Phoenix + LiveView = bagaimana UI bekerja
6OTP + concurrency = kenapa BEAM handle scale
7Testing = jaminan kualitas
8Deploy + ops = bagaimana code sampai ke production
9Ecosystem + risk = dependency dan exit strategy
10Driving Claude = cara efektif kolaborasi dengan AI

Kamu bukan coder. Kamu technical leader. Dan itu artinya:

LabaBersih v2 sudah berjalan di production 133+ tests. 10 context modules. 36 migrations. Live di lababersih.id. Semua dibangun dengan pola yang kamu pelajari di 10 bab ini. Bukan magic — ini systematic collaboration antara founder yang tau bisnisnya dan AI yang tau teknologinya.

Kamu sekarang siap memimpin pengembangan LabaBersih. Selamat, Hafish.