Skip to content
Santekno.com | Level Up Your Engineering Skills
ID
📖 0%
15 Sep 2026 · 23 mnt baca ·Artikel 45 / 208
Go

Claude Code untuk Golang: Setup, Best Practice, dan Workflow Optimal

Deep dive Claude Code untuk Go developer. Setup CLAUDE.md optimal, best practice harian, kekuatan dan kelemahan dibanding tools lain, tips untuk maximize output quality.

IH
Ihsan Arif
Penulis di Santekno · Backend Engineer

Claude Code untuk Golang: Strength, Weakness, Best Practice

Memahami Claude Code best practice untuk Golang adalah kunci untuk mendapat output berkualitas senior dari AI. Kita sudah familiar dengan Claude Code dari Topik 1 (SDD) dan Topik 2 (Spec Kit). Tapi di artikel ini kita melihatnya dari sudut pandang yang berbeda: sebagai salah satu dari enam tools yang perlu dievaluasi secara kritis. Apa yang membuatnya unggul? Di mana batas kemampuannya? Dan bagaimana menggunakannya secara optimal dalam Go development sehari-hari?


05.1 Mengapa Claude Code Berbeda dari Tools Lain

Claude Code bukan hanya “AI coding assistant” — ini adalah agentic coding environment yang dibangun dari prinsip berbeda: reason first, act second. Berbeda dari Cursor yang langsung generate code setelah prompt, Claude Code secara default berpikir sebelum bertindak. Sesi berikut memperlihatkan bagaimana Claude memetakan konteks dan menyusun plan sebelum menyentuh satu baris kode pun.

bash
 1claude
 2> Implementasikan fitur CancelOrder dengan semua edge cases
 3
 4Claude Code:
 5"Sebelum mulai implementasi, izinkan saya memahami konteks:
 6
 71. Saya baca CLAUDE.md dan melihat pattern error handling yang digunakan
 82. Saya perlu check existing Order entity untuk tahu method yang sudah ada
 93. Plan implementasi:
10   - Entity: tambah CanBeCancelled() method
11   - Repository: tambah CancelWithStockRestore() + interface update
12   - Usecase: CancelOrderUseCase dengan semua AC
13   - Handler: DELETE /orders/:id dengan auth middleware
14   - Router: tambah route
15   
164. Mulai dari entity layer dulu?
17   (ya/tidak)"

Pola “rencanakan dulu, konfirmasi, baru eksekusi” ini terasa lambat untuk task kecil, tapi sangat valuable untuk task complex yang memerlukan koordinasi antar banyak file.


05.2 Kekuatan Claude Code untuk Go Development

Kekuatan 1: Go Idiom Correctness yang Konsisten

Dari benchmark Artikel 3, Claude Code score 94/100 dan tidak pernah melanggar rules di CLAUDE.md dalam 15 runs. Ini bukan kebetulan — kode di bawah menunjukkan pola error handling yang selalu Claude hasilkan, berikut pola yang tidak pernah ia hasilkan.

go
 1// Claude Code selalu generate ini untuk error handling:
 2func (uc *CancelOrderUseCase) Execute(ctx context.Context, input CancelOrderInput) error {
 3    order, err := uc.orderRepo.GetByIDAndUserID(ctx, input.OrderID, input.UserID)
 4    if err != nil {
 5        return fmt.Errorf("cancelOrder.Execute: %w", err)  // ← selalu wrap
 6    }
 7    if order == nil {
 8        return ErrOrderNotFound  // ← domain error, bukan wrapped error
 9    }
10    // ...
11}
12
13// Dan TIDAK PERNAH generate ini (meski tool lain kadang generate):
14result, _ := operation()  // ← ignore error
15return err  // ← no context wrap
16if err != nil { panic(err) }  // ← panic di production code

Konsistensi ini datang dari CLAUDE.md retention yang superior dan kemampuan Claude untuk “internalize” rules sebagai bagian dari proses generasinya, bukan sekadar mengingat instruksi sesaat.

Kekuatan 2: Layered Architecture Awareness

Claude Code secara default sangat aware dengan Clean Architecture. Sesi berikut menunjukkan bagaimana Claude memeriksa layer mana yang harus menangani setiap concern sebelum menulis kode.

bash
 1claude
 2> Implement data fetching untuk CancelOrder
 3
 4Claude Code:
 5"Implementasi ini akan menyentuh beberapa layer:
 6
 7Repository Interface (di domain/usecase layer):
 8  - GetByIDAndUserID: verifikasi ownership
 9  - CancelWithStockRestore: atomic operation
10
11Repository Implementation (di repository/postgres layer):
12  - Perlu transaction untuk atomic cancel + restore
13
14Saya tidak akan import pgx langsung di usecase layer.
15Mulai dari repository interface definition?"

Kesadaran layer ini mencegah pelanggaran arsitektur yang biasanya baru terdeteksi saat code review — tools lain kadang langsung generate kode yang import DB driver di usecase.

Kekuatan 3: CLAUDE.md Memory yang Persistent

Di session panjang (30+ exchanges), Claude Code tetap mengikuti rules di CLAUDE.md. Transkrip berikut membuktikan retensi itu: aturan yang dikonfirmasi di awal sesi masih dipatuhi 25 exchange kemudian tanpa perlu diingatkan.

bash
 1# Awal session:
 2claude > Read CLAUDE.md dan konfirmasi top 3 rules
 3Claude: "Top 3 rules:
 4  1. Error handling: fmt.Errorf('pkg.Method: %w', err) always
 5  2. Repository not-found: return nil, nil (never error)
 6  3. Monetary: int64 cents, NEVER float64"
 7
 8# 25 exchanges kemudian:
 9claude > Implement get product price
10Claude: [generate dengan int64 cents, tidak perlu diingatkan lagi]
11# ✅ Still following rule #3

Retensi jangka panjang inilah yang membedakan Claude Code dari tools lain yang kerap “lupa” konvensi setelah 10-15 exchange, memaksa kamu mengulang instruksi yang sama.

Kekuatan 4: Deep Debugging Capability

Untuk debugging complex issues seperti race condition, deadlock, atau memory leak, Claude Code menunjukkan reasoning yang sangat structured. Sesi berikut memperlihatkan bagaimana Claude mengidentifikasi dua race condition sekaligus dari satu output go test -race, lengkap dengan dua alternatif solusi.

bash
 1claude
 2> go test -race ./... menghasilkan:
 3> WARN: DATA RACE
 4> Write at 0x00c0001a4b88 by goroutine 45 (ProcessOrders.func1):
 5> Read at 0x00c0001a4b88 by goroutine 12 (ProcessOrders.func1):
 6>
 7> Kode:
 8> func ProcessOrders(orders []*Order) []Result {
 9>     results := make([]Result, 0)
10>     for _, order := range orders {
11>         go func() {
12>             result := process(order)
13>             results = append(results, result)
14>         }()
15>     }
16>     wg.Wait()
17>     return results
18> }
19
20Claude Code:
21"Ada DUA race condition di kode ini, bukan satu:
22
23Race 1: Variable capture di goroutine
24  Problem: Variable 'order' di-capture by reference oleh semua goroutines.
25  Semua goroutines akan process 'order' terakhir di loop.
26  Fix: explicit parameter ke goroutine function
27
28Race 2: Concurrent slice append
29  Problem: results = append(results, result) dari multiple goroutines
30  tanpa synchronization.
31  Fix: gunakan channel atau pre-allocated slice dengan index
32
33Implementasi fix yang correct:
34
35Option A (channel-based, more idiomatic):
36func ProcessOrders(orders []*Order) []Result {
37    resultCh := make(chan Result, len(orders))
38    var wg sync.WaitGroup
39    
40    for _, order := range orders {
41        wg.Add(1)
42        go func(o *Order) {
43            defer wg.Done()
44            resultCh <- process(o)  // send to channel
45        }(order)  // explicit copy
46    }
47    
48    go func() {
49        wg.Wait()
50        close(resultCh)
51    }()
52    
53    results := make([]Result, 0, len(orders))
54    for r := range resultCh {
55        results = append(results, r)
56    }
57    return results
58}
59
60Option B (pre-allocated slice, simpler):
61func ProcessOrders(orders []*Order) []Result {
62    results := make([]Result, len(orders))  // pre-allocate
63    var wg sync.WaitGroup
64    
65    for i, order := range orders {
66        wg.Add(1)
67        go func(idx int, o *Order) {
68            defer wg.Done()
69            results[idx] = process(o)  // index assignment, no contention
70        }(i, order)
71    }
72    
73    wg.Wait()
74    return results
75}"

Level kedalaman ini sangat jarang di tools lain — Cursor mengidentifikasi masalah tapi explanation dan alternative solutions jarang se-comprehensive ini.

Kekuatan 5: Plan Mode untuk Complex Tasks

Plan Mode adalah fitur unik Claude Code yang memungkinkan review sebelum eksekusi. Sesi berikut memperlihatkan bagaimana Claude memaparkan seluruh rencana refactoring — file yang tersentuh, jenis perubahan, dan estimasi dampak — sebelum satu file pun diubah.

bash
 1claude --plan
 2> Refactor seluruh error handling di order service
 3
 4Claude Code (Plan Mode):
 5"Plan untuk refactoring error handling di order service:
 6
 7Files yang akan dimodifikasi (12 total):
 81. internal/usecase/order/create_order.go (8 changes)
 92. internal/usecase/order/cancel_order.go (5 changes)
103. internal/usecase/order/get_order.go (3 changes)
11...
12
13Type of changes:
14- Wrap all 'return err' dengan fmt.Errorf context
15- Update repository calls yang tidak ada error wrap
16- Ensure domain errors propagate correctly
17
18Estimated impact:
19- Tidak ada behavior change
20- All existing tests should pass
21- Better debugging trace di production logs
22
23Proceed? [y/n/detail]"
24
25# Kamu review plan dulu, baru approve

Plan Mode mengubah refactoring skala besar dari “lompat iman” menjadi keputusan sadar — kamu tahu persis apa yang akan berubah sebelum menyetujuinya.


05.3 Kelemahan Claude Code

Kelemahan 1: CLI-Only — Tidak Ada Visual Diff

Ini adalah kelemahan terbesar untuk banyak developer. Sesi berikut menggambarkan situasinya: Claude melaporkan file mana saja yang diubah, tapi kamu tidak tahu persis isi perubahannya sampai membuka diff secara manual.

bash
 1claude
 2> Refactor create_order.go — pisahkan validation ke domain entity
 3
 4Claude Code:
 5"Saya telah mengupdate:
 6- internal/domain/order/entity.go (added Validate() method)
 7- internal/usecase/order/create_order.go (removed inline validation)
 8- internal/usecase/order/create_order_test.go (updated test)"
 9
10# Kamu tidak tahu persis apa yang berubah sampai:
11git diff  # atau buka file satu per satu

Dibandingkan Cursor yang menunjukkan unified diff sebelum apply, ini friction nyata untuk refactoring multi-file. Untungnya git bisa menutup gap ini; perintah berikut adalah mitigasi standar sebelum dan sesudah sesi.

bash
 1# Setup git tracking sebelum Claude Code session
 2git add -A
 3git commit -m "checkpoint before AI session"
 4
 5# Setelah Claude selesai:
 6git diff HEAD  # lihat semua perubahan
 7git diff HEAD internal/usecase/order/  # per directory
 8
 9# Atau gunakan difftool:
10git difftool HEAD  # opens visual diff tool

Dengan checkpoint commit sebelum sesi, git diff HEAD memberi kamu visual review yang setara — sekaligus tombol undo instan bila hasilnya tidak memuaskan.

Kelemahan 2: Per-Token Cost yang Bisa Mengejutkan

Berbeda dari flat-rate, cost Claude Code proporsional dengan token. Cuplikan berikut menunjukkan cara melacak biaya per sesi sekaligus tiga strategi menekannya.

bash
 1# Tracking cost:
 2claude --show-cost
 3# Output: "Session cost: $0.14 (input: 45K tokens, output: 8K tokens)"
 4
 5# Daily estimate untuk heavy user:
 6# 10-15 complex tasks × $0.10-0.20 = $1.50-3.00/hari
 7# Monthly: $30-60/bulan (API cost saja)
 8
 9# Tips budget management:
10# 1. Gunakan claude-haiku untuk task sederhana
11claude --model claude-haiku-4-5-20251001 > Add godoc comment ke function ini
12
13# 2. Start session baru untuk task yang tidak related
14# (tidak ada carry-over context = less token overhead)
15
16# 3. Budget alert: set AWS billing alert jika pakai via Bedrock

Kunci mengelola biaya adalah mencocokkan model dengan kompleksitas task dan memisahkan sesi yang tidak berkaitan agar tidak menyeret context yang tidak perlu.

Kelemahan 3: Tidak Ada IDE Integration

Tidak ada inline suggestion seperti Copilot, tidak ada file tree navigation, tidak ada integrated test runner UI. Mitigasi: combine dengan Copilot atau VS Code untuk daily coding, dan gunakan Claude Code hanya untuk complex tasks — ini adalah multi-tool strategy yang banyak developer pakai.

Kelemahan 4: Lambat untuk Task Kecil

Untuk rename sebuah variable, tambah satu import, atau fix typo, Claude Code terlalu heavyweight karena akan membaca CLAUDE.md dan memikirkan approach lebih dulu. Mitigasi: gunakan editor built-in atau Copilot untuk task kecil, dan simpan Claude Code untuk task yang membutuhkan reasoning atau multi-file coordination.


05.4 CLAUDE.md yang Optimal untuk Go Project

CLAUDE.md yang baik adalah investasi dengan ROI tertinggi dalam pemakaian Claude Code. Template lengkap berikut menunjukkan struktur dan urutan section yang terbukti menghasilkan output paling konsisten untuk proyek Go — dari architecture rules hingga daftar “NEVER”.

markdown
  1# CLAUDE.md — [Project Name]
  2## Go [version] | [Framework] | [Database] | [Architecture]
  3
  4---
  5
  6## CRITICAL: Architecture (NEVER violate)
  7
  8Layer hierarchy (strict):
  9```
 10delivery/http/handler → usecase → repository → domain
 11```
 12
 13Rules:
 14- handler: ONLY imports usecase interfaces (never concrete types)
 15- usecase: ONLY imports domain types + repository interfaces
 16- repository: ONLY imports domain types + DB/infra drivers  
 17- domain: ZERO external imports (pure Go standard library only)
 18
 19Violation examples (NEVER do these):
 20```go
 21// WRONG — repository imported in usecase:
 22import "github.com/santekno/santekno-shop/internal/repository/postgres"
 23
 24// WRONG — pgx error exposed from repository:
 25return pgx.ErrNoRows  // use nil, nil instead
 26
 27// CORRECT — interface at consumer side:
 28// In usecase package:
 29type OrderRepository interface {
 30    GetByIDAndUserID(ctx context.Context, orderID, userID uuid.UUID) (*Order, error)
 31}
 32```
 33
 34---
 35
 36## CRITICAL: Error Handling (follow exactly)
 37
 38### Repository Layer
 39```go
 40// Not found → return nil, nil (NEVER return error for not-found)
 41if err == pgx.ErrNoRows {
 42    return nil, nil  // CORRECT
 43}
 44// DB error → wrap and return
 45if err != nil {
 46    return nil, fmt.Errorf("orderRepo.GetByIDAndUserID: %w", err)
 47}
 48```
 49
 50### Usecase Layer
 51```go
 52// Check nil first (means not-found from repo):
 53if order == nil {
 54    return ErrOrderNotFound  // domain error, not wrapped
 55}
 56// Infrastructure errors → wrap with usecase context:
 57if err != nil {
 58    return fmt.Errorf("cancelOrder.Execute: %w", err)
 59}
 60```
 61
 62### Handler Layer  
 63```go
 64// Map domain errors to HTTP:
 65switch {
 66case errors.Is(err, domain.ErrOrderNotFound):
 67    return c.JSON(http.StatusNotFound, ErrorResponse{Error: "ORDER_NOT_FOUND"})
 68case errors.As(err, &notCancellable):
 69    return c.JSON(http.StatusConflict, ErrorResponse{Error: "ORDER_NOT_CANCELLABLE"})
 70}
 71// HTTP error codes: ALWAYS UPPERCASE_SNAKE_CASE
 72```
 73
 74---
 75
 76## CRITICAL: Types
 77
 78```go
 79// Monetary: ALWAYS int64 cents
 80type Order struct {
 81    TotalPrice int64  // 50000 = Rp 500.00 (NOT 5.00, NOT 500.00)
 82}
 83// NEVER: float64, float32, decimal for money
 84
 85// IDs: ALWAYS uuid.UUID
 86import "github.com/google/uuid"
 87type Order struct {
 88    ID uuid.UUID
 89}
 90// NEVER: string, int for IDs
 91
 92// Time: time.Time (UTC in DB, local for display)
 93```
 94
 95---
 96
 97## External Packages (exact import paths — no alternatives)
 98
 99```
100PostgreSQL:    github.com/jackc/pgx/v5         (NEVER database/sql)
101Redis:         github.com/redis/go-redis/v9    
102HTTP:          github.com/labstack/echo/v4      
103Mocking:       go.uber.org/mock/gomock          (NEVER testify mock)
104Test suite:    github.com/stretchr/testify/suite
105UUID:          github.com/google/uuid           
106Kafka:         github.com/confluentinc/confluent-kafka-go/v2
107```
108
109---
110
111## Go Version Constraint: Go 1.22
112
113NEVER use features from Go 1.23+:
114- range-over-func (1.23+): NOT available
115- iter.Seq (1.23+): NOT available
116- slices.Collect (1.23+): NOT available
117
118---
119
120## Testing Standards
121
122```go
123// Suite structure:
124type CancelOrderSuite struct {
125    suite.Suite
126    ctrl     *gomock.Controller
127    mockRepo *mock.MockOrderRepository
128    uc       *usecase.CancelOrderUseCase
129}
130
131func (s *CancelOrderSuite) SetupTest() {
132    s.ctrl = gomock.NewController(s.T())
133    s.mockRepo = mock.NewMockOrderRepository(s.ctrl)
134    s.uc = usecase.NewCancelOrderUseCase(s.mockRepo)
135}
136
137func (s *CancelOrderSuite) TearDownTest() {
138    s.ctrl.Finish()
139}
140
141// Test naming: Test{Subject}_{Scenario}_{ExpectedResult}
142// Example: TestCancelOrder_PendingWithinWindow_Success
143//          TestCancelOrder_WindowExpired_ReturnsCancelWindowExpired
144```
145
146---
147
148## HTTP Response Standards
149
150```go
151type ErrorResponse struct {
152    Error string `json:"error"`  // UPPERCASE_SNAKE_CASE always
153}
154
155// Success: HTTP 2xx, body as specified per endpoint
156// Not found: 404 + {"error": "RESOURCE_NOT_FOUND"}
157// Conflict: 409 + {"error": "SPECIFIC_CONFLICT_REASON"}
158// Server error: 500 + {"error": "INTERNAL_SERVER_ERROR"}
159```
160
161---
162
163## NEVER do these (absolute rules)
164
165```go
166// 1. NEVER ignore errors:
167result, _ := operation()  // FORBIDDEN
168
169// 2. NEVER panic in business logic:
170if err != nil { panic(err) }  // FORBIDDEN
171
172// 3. NEVER float64 for money:
173price := 50.00  // FORBIDDEN
174
175// 4. NEVER string for IDs:
176func GetOrder(id string)  // FORBIDDEN — use uuid.UUID
177
178// 5. NEVER raw error return from usecase:
179return err  // FORBIDDEN — always wrap with context
180
181// 6. NEVER import across layers incorrectly:
182import "internal/repository/postgres"  // FORBIDDEN in usecase
183
184// 7. NEVER use goroutine without termination condition:
185go func() { doForever() }()  // FORBIDDEN
186```

Semakin eksplisit contoh WRONG/CORRECT yang kamu tulis di CLAUDE.md, semakin sedikit koreksi yang perlu kamu lakukan atas kode generated — daftar “NEVER” di akhir berfungsi sebagai pagar terakhir yang jarang dilanggar Claude.


05.5 Daily Workflow yang Efektif dengan Claude Code

Pattern 1: Spec-Driven Implementation

Pola pertama meneruskan disiplin SDD dari Topik 1 & 2: minta Claude membaca spec dan tasks lebih dulu, konfirmasi cakupan, baru implement. Sesi berikut mencontohkannya.

bash
 1claude
 2> Kita implementasikan Task 04 dari .specify/features/cancel-order/tasks.md.
 3> Read spec.md dan tasks.md dulu, konfirmasi apa yang akan dikerjakan.
 4
 5Claude: "Task 04: Implement CancelOrderUseCase
 6  - File baru: internal/usecase/order/cancel_order.go
 7  - Dependency: OrderRepository interface (dari Task 02)
 8  - Cover: AC1-AC10 dari spec.md
 9  
10  Saya akan implement step by step. Mulai dari struct definition?"
11
12> Ya, lanjutkan.

Dengan meminta konfirmasi cakupan lebih dulu, kamu memastikan implementasi ter-anchor ke spec, bukan ke asumsi AI.

Pattern 2: Test-Driven AI Development

Pola kedua membalik urutan: berikan test yang harus pass, lalu minta Claude implement tanpa mengubah test. Sesi berikut menunjukkan strukturnya.

bash
1claude
2> Ini test yang harus pass (jangan ubah test, hanya implement):
3
4@internal/usecase/order/cancel_order_test.go
5
6> Implement CancelOrderUseCase.Execute yang membuat semua 8 tests ini pass.
7
8Claude: [implement berdasarkan test expectations yang sangat specific]

Karena test menjadi spesifikasi eksekutabel, output Claude terikat pada perilaku yang kamu inginkan — bukan interpretasi bebas.

Pattern 3: Review sebelum PR

Pola ketiga menjadikan Claude sebagai reviewer pertama sebelum PR dibuka. Format output yang diminta membuat temuan mudah ditindaklanjuti.

bash
 1claude
 2> Review files berikut sebelum saya buat PR.
 3> Check terhadap CLAUDE.md dan spec.md:
 4
 5[list files yang baru diimplementasikan]
 6
 7> Format output:
 8> CRITICAL — file:line — issue — fix
 9> SUGGESTION — file:line — improvement
10> SCORE — READY/NEEDS WORK
11
12Claude: [detailed review dengan findings]

Pre-review otomatis ini menangkap pelanggaran konvensi sebelum reviewer manusia menghabiskan waktu untuk hal mekanis.

Pattern 4: Interactive Debugging

Pola keempat memanfaatkan kekuatan reasoning Claude untuk debugging: tempel output error lengkap plus kode relevan, minta analisis dan fix.

bash
 1# Copy-paste error output langsung ke claude:
 2claude
 3> go test -race ./internal/usecase/order/... gagal:
 4>
 5> --- FAIL: TestCancelOrderSuite/TestExecute_AtomicRollback (0.15s)
 6>     cancel_order_test.go:89: Error: expected nil, got:
 7>         cancelOrder.Execute: cancel with stock restore: context deadline exceeded
 8>
 9> Kode:
10> @internal/usecase/order/cancel_order.go
11>
12> Analisis dan fix.

Semakin lengkap konteks error yang kamu berikan, semakin akurat diagnosis Claude — jangan pangkas stack trace atau kode yang relevan.


05.6 Advanced Patterns

Pattern: Cross-Layer Coordination

Untuk fitur yang menyentuh banyak layer, minta Claude bekerja berurutan dan verify compile di setiap layer. Sesi berikut mendefinisikan urutan itu secara eksplisit.

bash
 1claude
 2> Fitur baru butuh koordinasi di 4 layer:
 3> 
 4> 1. Domain: tambah method ValidateForCancellation() di Order entity
 5> 2. Repository interface: tambah CancelWithRestore(ctx, orderID) method
 6> 3. Usecase: implement CancelOrderUseCase menggunakan method baru
 7> 4. Handler: DELETE /orders/:id endpoint
 8>
 9> Implement dalam urutan ini, verify compile setiap layer sebelum lanjut.
10> Jangan skip verification — CLAUDE.md architecture harus terjaga.

Dengan instruksi ini, Claude akan menjalankan siklus implement-lalu-go build per layer sehingga error terdeteksi dini dan arsitektur tetap terjaga.

Pattern: Batch Refactoring

Untuk refactoring berskala, gabungkan bash tool dengan instruksi transformasi. Sesi berikut memakai grep untuk menemukan target lalu memerintahkan perbaikan seragam.

bash
1claude
2> Jalankan bash command ini dulu dan paste hasilnya:
3> grep -rn "return err$" internal/usecase/ --include="*.go" | grep -v "_test.go"
4
5[paste grep output]
6
7> Update semua instances ini dengan proper error wrapping.
8> Format: fmt.Errorf("[package].[function]: %w", err)
9> Gunakan package dan function name dari file context.

Pendekatan grep-lalu-transform ini memastikan tidak ada instance yang terlewat, sekaligus menjaga konsistensi format wrapping di seluruh package.

Pattern: Generate Mock dan Interface

Pola terakhir mengotomasi pembuatan interface dan mock untuk testing. Sesi berikut meminta Claude mengekstrak interface di sisi consumer dan menyiapkan directive generate.

bash
1claude
2> File internal/usecase/order/cancel_order.go butuh mocking untuk tests.
3> 
4> 1. Extract interface OrderRepository dari struct yang dipakai usecase
5>    (define interface di usecase package, bukan di repository package)
6> 2. Generate mock menggunakan go:generate directive
7> 3. Update usecase constructor untuk inject interface
8>
9> Setelah selesai, tunjukkan go generate command untuk re-generate mock.

Menempatkan interface di sisi consumer (usecase) menjaga prinsip dependency inversion, dan directive go:generate membuat mock selalu bisa disinkronkan ulang saat kontrak berubah.


05.7 Cost Management Strategies

Biaya per-token bisa dikendalikan dengan disiplin sederhana. Cuplikan berikut merangkum empat strategi: pilih model sesuai kompleksitas, batch prompt, monitor usage, dan manfaatkan caching.

bash
 1# Strategy 1: Pilih model sesuai task complexity
 2
 3# Task sederhana (rename, add comment, simple function):
 4claude --model claude-haiku-4-5-20251001
 5# ~10x lebih murah, cukup untuk simple tasks
 6
 7# Task medium (implement single usecase, write tests):
 8claude  # default claude-sonnet-4
 9
10# Task sangat complex (architecture decision, complex debugging):
11claude --model claude-opus-4
12# ~3x lebih mahal dari sonnet, untuk task yang truly need it
13
14# Strategy 2: Efficient prompting
15
16# INEFFICIENT — multiple small sessions:
17claude > Add error handling
18claude > Add test
19claude > Add godoc
20# 3 sessions = 3x overhead
21
22# EFFICIENT — batch dalam satu session:
23claude > Add error handling (wrap pattern dari CLAUDE.md), 
24        unit test (testify/suite), dan godoc comment 
25        untuk function ProcessOrder
26
27# Strategy 3: Monitor usage
28claude --usage-stats
29# Lihat token consumption per task type
30# Identify bottlenecks dan optimize
31
32# Strategy 4: Gunakan prompt caching
33# Claude secara otomatis cache CLAUDE.md content
34# Mulai sesi baru setiap 50+ exchanges untuk refresh cache

Intinya: jangan pakai Opus untuk pekerjaan Haiku, dan jangan pecah task terkait ke banyak sesi — dua kebiasaan itu saja bisa memangkas tagihan bulanan secara signifikan.


05.8 Troubleshooting Common Issues

Issue 1: Claude generate code yang tidak compile. Alur berikut menunjukkan cara memberi feedback error compile secara efektif agar Claude memperbaiki dengan tepat.

bash
 1# Langkah 1: Compile check
 2go build ./...
 3
 4# Langkah 2: Feed error ke Claude
 5claude
 6> Build error:
 7> ./internal/usecase/order/cancel_order.go:45:3:
 8>   undefined: domain.ErrOrderNotFound
 9> 
10> domain package ada di internal/domain/order/errors.go.
11> Import dan gunakan yang sudah ada.
12
13# Langkah 3: Jika masih salah, cek import
14claude > Read internal/domain/order/errors.go dan buat saya tahu
15        semua error types yang tersedia.

Memberi tahu Claude lokasi definisi yang benar (bukan sekadar pesan error) mempercepat perbaikan dan mencegah ia menghalusinasi tipe baru.

Issue 2: Claude “lupa” rules setelah session panjang. Ketika float64 mulai muncul atau error tidak di-wrap, dua fix berikut mengembalikan Claude ke jalur.

bash
1# Symptoms: float64 muncul, error tidak di-wrap, dll
2
3# Fix 1: Explicit reminder
4claude > Ingat: CLAUDE.md rule #1: NEVER float64 untuk monetary.
5        Tolong fix function yang baru kamu buat.
6
7# Fix 2: Mulai session baru dengan orientation
8claude  # new session
9> Read CLAUDE.md dan konfirmasi 5 rules terpenting sebelum kita mulai.

Jika reminder singkat tidak cukup, sesi baru dengan orientation ulang adalah reset paling andal — sekaligus me-refresh prompt cache.

Issue 3: Output yang terlalu verbose. Tambahkan section gaya kode ke CLAUDE.md agar Claude menahan komentar yang tidak perlu.

markdown
1# Tambahkan ke CLAUDE.md:
2## Code Style
3- Minimal comments: only explain WHY, never WHAT
4- No "// Implementation of X" comments
5- Function names should be self-documenting
6- Godoc only for exported functions that need explanation

Aturan gaya yang eksplisit ini membuat output lebih ringkas dan idiomatik, tanpa komentar basa-basi yang mengaburkan intent.

Issue 4: Claude menolak lanjut karena “ethics”. Untuk security testing yang legitimate, beri konteks bahwa ini test internal untuk memvalidasi pertahanan produksi.

bash
1# Ini kadang terjadi untuk security testing code yang legitimate
2
3claude > Kita sedang tulis integration test untuk verify SQL injection prevention.
4        Ini adalah test internal untuk validate bahwa parameterized queries
5        yang kita gunakan di production tidak vulnerable.
6        Implement test case ini:
7        [describe what you need]

Menjelaskan maksud defensif dari test biasanya cukup untuk melewati penolakan yang keliru, karena Claude memahami konteks keamanan yang sah.


05.9 Integrasi Claude Code dengan Go Toolchain

Claude Code paling efektif ketika dirangkai dengan verifikasi otomatis. Script berikut menjalankan build, vet, race test, dan lint sekaligus setelah setiap sesi.

bash
 1# Pre-session setup yang baik:
 2alias claude-go='claude && go build ./... && go vet ./... && go test -race ./...'
 3
 4# Atau buat script:
 5cat > scripts/ai-verify.sh << 'EOF'
 6#!/bin/bash
 7echo "=== Build Check ==="
 8go build ./... || exit 1
 9
10echo "=== Vet Check ==="
11go vet ./... || exit 1
12
13echo "=== Race Check ==="
14go test -race ./... || exit 1
15
16echo "=== Lint ==="
17golangci-lint run ./...
18
19echo "✅ All checks passed"
20EOF
21chmod +x scripts/ai-verify.sh
22
23# Run setelah setiap Claude Code session:
24./scripts/ai-verify.sh

Menjadikan verifikasi sebagai satu langkah wajib pasca-sesi memastikan kode generated selalu lolos gate yang sama dengan kode tulisan tangan.


05.10 Claude Code untuk Go Module Management

Claude Code juga membantu mengelola dependency, dari upgrade hingga audit. Sesi berikut mencontohkan tiga tugas manajemen modul yang sering muncul.

bash
 1# Update dependencies
 2claude
 3> go.mod menunjukkan pgx/v5 adalah v5.5.0 tapi ada v5.7.0 yang latest.
 4> Update semua pgx-related code untuk compatible dengan v5.7.0.
 5> Check changelog untuk breaking changes dulu.
 6
 7# Resolve dependency conflict
 8claude
 9> go mod tidy menghasilkan:
10> [paste error]
11> Bantu resolve ini.
12
13# Audit dependencies
14claude
15> Check go.sum dan identifikasi dependencies yang mungkin perlu di-update
16> untuk security reasons berdasarkan pengetahuan kamu.

Meminta Claude mengecek changelog sebelum upgrade adalah kebiasaan penting — ia bisa mengantisipasi breaking change sebelum kode kamu gagal compile.


05.11 Measuring Claude Code Effectiveness

Adopsi tool harus dibuktikan dengan angka, bukan perasaan. Daftar metrik berikut menunjukkan contoh before/after yang bisa kamu lacak untuk membuktikan dampak Claude Code.

text
 1Metrics yang bisa di-track:
 2
 31. Time per feature implementation
 4   Before AI: 4 hours average
 5   After AI: 2.5 hours average
 6   Improvement: 37.5%
 7
 82. PR review round trips
 9   Before: 2.3 round trips average
10   After: 1.4 round trips
11   Improvement: 39%
12
133. Test coverage
14   Before: 72% average
15   After: 88% average
16   Improvement: +16 percentage points
17
184. Error handling consistency
19   (via golangci-lint error handling rules)
20   Before: 8 violations per sprint
21   After: 1-2 violations per sprint
22
235. Time to onboard new developer
24   Before: 2 weeks to first meaningful PR
25   After: 1 week
26   Improvement: 50%

Metrik seperti waktu ke PR-ready dan jumlah round-trip review jauh lebih meaningful bagi bisnis daripada “berapa banyak kode yang di-generate” — lacak yang benar-benar berdampak.


05.12 Claude Code vs Alternatives: Head-to-Head

Setelah membahas kekuatan dan kelemahan, tabel berikut menyandingkan Claude Code dengan Cursor dan Copilot pada skenario Go yang paling sering muncul.

ScenarioClaude CodeCursorCopilot
Implement feature dari spec⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Go idiom correctness⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Visual diff review❌⭐⭐⭐⭐⭐⭐⭐⭐
Multi-file Composer⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Race condition debug⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
PR review automation❌❌⭐⭐⭐⭐⭐
Inline autocomplete❌⭐⭐⭐⭐⭐⭐⭐⭐⭐
SDD workflow native⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Cost predictability❌ (variable)✅ (flat)✅ (flat)
CLI comfortable✅❌❌

Pola dari tabel ini jelas: Claude Code unggul di kualitas Go idiom, SDD, dan deep debugging, tapi kalah di visual diff dan inline autocomplete — persis area yang bisa ditutup dengan multi-tool strategy.


05.13 Tips & Gotchas

💡 Tip 1: Start setiap session dengan orientation. Konfirmasi bahwa Claude memahami aturan inti sebelum mulai coding.

bash
1claude
2> Read CLAUDE.md dan konfirmasi kamu mengerti:
3> 1. Architecture rules
4> 2. Error handling pattern
5> 3. Monetary type rules

Orientation singkat ini memuat rules ke context aktif dan menurunkan drastis kemungkinan pelanggaran di tengah sesi.

💡 Tip 2: Gunakan --dangerously-skip-permissions dengan bijaksana. Flag ini melewati konfirmasi per-aksi — efisien tapi berisiko. Gunakan hanya di development environment, setelah review plan yang comprehensive, dan untuk task yang scope-nya jelas serta reversible.

💡 Tip 3: CLAUDE.md harus di-commit. Context file ini adalah team asset; commit ke repo dan update setiap kali ada convention baru atau pattern yang berubah agar seluruh tim mendapat manfaat yang sama.

💡 Tip 4: Pair dengan git worktree untuk parallel experiments. Worktree terpisah membuat kamu bisa bereksperimen tanpa mengganggu working directory utama.

bash
1# Experiment di worktree terpisah tanpa affect main working directory:
2git worktree add /tmp/experiment-cancel-order -b experiment/cancel-order
3cd /tmp/experiment-cancel-order
4claude > Try approach A untuk cancel order dengan outbox pattern
5# Jika approach bagus: git cherry-pick atau merge
6# Jika tidak: discard worktree

Dengan worktree, eksperimen berisiko jadi murah: approach yang bagus tinggal di-merge, yang gagal cukup dibuang tanpa jejak.

⚠️ Gotcha 1: Claude bisa terlalu eager untuk “improve”. Batasi scope secara eksplisit ketika kamu hanya ingin fix spesifik.

bash
1claude > Fix bug di line 45 dari cancel_order.go
2
3# Claude mungkin tidak hanya fix bug tapi juga "refactor" area lain
4# Mitigasi:
5claude > Fix ONLY the bug di line 45.
6        Jangan ubah anything else.
7        Jika kamu lihat improvements lain, report saja, jangan implement.

Membatasi scope secara eksplisit mencegah perubahan tak terduga yang memperbesar diff dan menyulitkan review.

⚠️ Gotcha 2: Large files memakan token banyak. File di atas 1000 baris sebaiknya tidak di-include utuh; kutip hanya bagian relevan.

bash
1# Kurang efisien:
2claude > [paste 2000 line file]
3
4# Lebih efisien:
5claude > File order_repository.go punya issue di implementasi GetByIDAndUserID.
6        Relevant code (lines 145-180):
7        [paste hanya bagian yang relevant]

Mengutip potongan yang relevan saja menghemat token sekaligus memfokuskan perhatian Claude pada area yang benar-benar bermasalah.

⚠️ Gotcha 3: Hallucination untuk package internal. Claude kadang “menciptakan” method yang tidak ada di struct kamu.

go
1// Claude mungkin generate:
2order.GetTotalWithTax()  // ← method ini tidak ada di struct Order kamu!
3
4// Prevention:
5// > Read entity.go dulu sebelum implement, supaya kamu tahu method yang ada.

Meminta Claude membaca definisi entity lebih dulu adalah pencegahan paling efektif terhadap halusinasi method internal.

⚠️ Gotcha 4: Per-token cost bisa spike unexpectedly. Long context ditambah task complex dan banyak revisi bisa membengkakkan biaya melebihi ekspektasi — monitor dengan flag --show-cost secara berkala.


05.14 Ringkasan

Claude Code adalah pilihan terbaik untuk Go developer yang memprioritaskan code quality dan Go idiom correctness, nyaman dengan terminal/CLI workflow, sudah invest di SDD approach (Topik 1 & 2), dan butuh deep reasoning untuk complex debugging.

Kelemahan utamanya — CLI-only, per-token cost, dan tidak ada visual diff — bisa di-mitigasi dengan kombinasi Copilot untuk inline suggestions, tracking token usage untuk budget, git diff sebagai pengganti visual diff, dan multi-tool strategy untuk task yang berbeda.

CLAUDE.md yang comprehensive adalah kunci: investasi 30 menit untuk CLAUDE.md yang baik bisa mengembalikan ratusan jam yang dihemat sepanjang lifetime proyek. Di artikel berikutnya kita pindah ke pendekatan yang sangat berbeda — Cursor, IDE yang menempatkan AI sebagai warga kelas satu.

Artikel Terkait

💬 Komentar