Skip to content
Santekno.com | Level Up Your Engineering Skills
ID
📖 0%
21 Aug 2026 · 20 mnt baca ·Artikel 28 / 208
Go

speckit.plan: Cara AI Generate Rencana Teknis Golang dari Spesifikasi

Panduan lengkap speckit.plan untuk membuat technical implementation plan Golang dari spesifikasi fungsional. Cara membaca, memvalidasi, dan memanfaatkan plan.md untuk implementasi yang efisien.

IH
Ihsan Arif
Penulis di Santekno · Backend Engineer

speckit.plan: Dari Spec Fungsional ke Rencana Teknis Go

Perintah speckit plan adalah jembatan antara “apa yang user butuhkan” dan “bagaimana cara membangunnya”. Inilah perintah yang mengubah spec.md yang bersih dari teknis menjadi plan.md yang kaya keputusan arsitektural — file structure, SQL schema, API design, dan implementation order untuk fitur Golang kamu.

Di artikel ini kita bahas anatomy technical implementation plan golang yang dihasilkan, cara memvalidasi kualitasnya, dan bagaimana memodifikasinya sebelum implementasi dimulai agar tim tidak salah arah sejak awal.


08.1 Menjalankan specify plan

Untuk menghasilkan rencana teknis, jalankan specify plan terhadap fitur yang specnya sudah di-clarify. Perintah berikut menargetkan fitur product-search.

bash
1specify plan product-search

Sebelum menghasilkan output, Spec Kit membaca empat sumber konteks agar rencananya konsisten dengan aturan dan kode yang sudah ada. Daftar berikut merangkum apa saja yang dibaca.

text
11. constitution.md — architecture rules, conventions
22. spec.md — business requirements (updated setelah clarify)
33. clarifications.md — keputusan dari Q&A
44. Kode existing di internal/ — untuk consistency dengan pattern yang ada

Karena plan dibangun di atas keempat sumber ini, hasilnya bukan template generik melainkan rencana yang sadar konteks proyekmu. Setelah proses selesai, Spec Kit menuliskan ringkasan seperti berikut.

text
 1⚙️  Generating Technical Plan: product-search
 2
 3Analyzing constitution... ✓
 4Analyzing spec and clarifications... ✓
 5Scanning existing code patterns... ✓
 6  Found: internal/product/domain/entity.go (reference)
 7  Found: internal/product/repository/postgres_repository.go (reference)
 8Generating plan...
 9
10Plan created: .specify/features/product-search/plan.md
11   Estimated complexity: Medium (3-4 days)
12   Phases: 4
13   Files to create: 8
14   Files to modify: 3

Perhatikan bagian “Scanning existing code patterns” — di sinilah Spec Kit menemukan file referensi yang akan ditiru gaya penulisannya. Inilah alasan plan-nya terasa “nyambung” dengan codebase, bukan asing.


08.2 Anatomy plan.md yang Komprehensif

File plan.md yang dihasilkan terdiri dari beberapa bagian terstruktur. Berikut header-nya sebagai penanda versi dan basis pembuatan plan.

text
 1# Technical Implementation Plan: Product Search
 2# Based on: spec.md v1.3, clarifications.md v1.0, constitution v1.1
 3# Generated: 2025-07-02
 4# Architecture: Clean Architecture (per constitution)
 5
 6## Executive Summary
 7Implement full-text product search using PostgreSQL's built-in text search.
 8Search indexes product name and description, ranks results by relevance (ts_rank),
 9and supports category filtering and pagination. Stock=0 products remain visible
10with "Out of Stock" badge (clarification Q1). Caching delegated to Phase 2 (Q6).

Executive summary di atas langsung mengaitkan keputusan clarify (Q1, Q6) ke rencana teknis — bukti bahwa plan adalah kelanjutan langsung dari spec. Sekarang mari bedah bagian-bagian intinya satu per satu.

Architecture Diagram

Bagian pertama adalah diagram arsitektur berbentuk Mermaid class diagram yang memetakan relasi antar layer. Diagram berikut memperlihatkan bagaimana handler bergantung pada usecase, dan usecase pada repository.

classDiagram
    class SearchHandler {
        -usecase SearchUseCase
        +SearchProducts(c echo.Context) error
    }
    class SearchUseCase {
        <>
        +SearchProducts(ctx, query SearchQuery) (SearchResult, error)
    }
    class ProductRepository {
        <>
        +SearchProducts(ctx, filter SearchFilter) ([]Product, int, error)
    }
    class SearchUseCaseImpl {
        -repo ProductRepository
        +SearchProducts(ctx, query SearchQuery) (SearchResult, error)
    }
    SearchHandler --> SearchUseCase
    SearchUseCase <|.. SearchUseCaseImpl
    SearchUseCaseImpl --> ProductRepository

Dari diagram ini jelas terlihat arah dependency selalu satu arah (handler → usecase → repository), sesuai clean architecture di constitution. Reviewer bisa memvalidasi kepatuhan arsitektur hanya dari melihat panahnya.

File Structure

Berikutnya plan merinci file mana yang harus dibuat dan dimodifikasi. Cuplikan berikut menampilkan daftar file baru.

text
1internal/product/
2├── usecase/
3│   ├── search_usecase.go          # SearchUseCase implementation
4│   ├── search_usecase_test.go     # Unit tests (7 test cases)
5│   └── dto.go                     # ADD SearchQuery, SearchResult, SearchFilter
6├── handler/
7│   ├── search_handler.go          # SearchProducts HTTP handler
8│   └── search_handler_test.go     # Handler tests (5 test cases)

Selain file baru, plan juga menandai file existing yang perlu diubah beserta infrastruktur migration-nya.

text
1# Files to MODIFY
2internal/product/
3├── usecase/interface.go               # ADD SearchUseCase interface
4├── repository/postgres_repository.go  # ADD SearchProducts method
5└── handler/router.go                  # ADD GET /api/v1/products/search route
6
7# Files to CREATE (infrastructure)
8migrations/
9└── 20250702001_add_search_index.sql   # GIN index for full-text search

Daftar file yang eksplisit ini menghilangkan tebak-tebakan saat implementasi: developer tahu persis berapa file yang tersentuh, sehingga estimasi dan review PR jadi lebih presisi.

Database Schema Changes

Bagian schema menjelaskan perubahan database yang dibutuhkan. SQL berikut membuat GIN index untuk full-text search dengan dictionary bahasa Indonesia.

sql
 1-- 20250702001_add_search_index.sql
 2-- Full-text search index for product name and description
 3CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_products_fts
 4ON products
 5USING gin(
 6    to_tsvector('indonesian', name || ' ' || COALESCE(description, ''))
 7);
 8
 9-- Verify index was created
10SELECT indexname, indexdef
11FROM pg_indexes
12WHERE tablename = 'products' AND indexname = 'idx_products_fts';

Kata kunci CONCURRENTLY di sini bukan detail sepele: ia memastikan index dibuat tanpa mengunci tabel, sehingga migration aman dijalankan di production dengan traffic hidup. Detail seperti inilah yang membedakan plan yang matang dari sekadar draft.

New Types and Structs

Plan mendefinisikan tipe-tipe Go baru yang akan dipakai lintas layer. Karena ini adalah kode Go sesungguhnya, ia layak dibaca dengan cermat — struct berikut memetakan request, opsi sort, dan bentuk response.

go
 1// internal/product/usecase/dto.go (additions)
 2
 3// SearchQuery merepresentasikan request pencarian dari customer.
 4// Dipetakan langsung dari HTTP query parameter.
 5type SearchQuery struct {
 6    Keyword    string     `validate:"required,min=2,max=100"`
 7    CategoryID *uuid.UUID // optional
 8    SortBy     SortOption `validate:"oneof=relevance newest price_asc price_desc"`
 9    Page       int        `validate:"min=1"`
10    PerPage    int        `validate:"min=1,max=50"`
11}
12
13// SortOption mendefinisikan urutan sort yang valid untuk product search.
14type SortOption string
15
16const (
17    SortByRelevance SortOption = "relevance"
18    SortByNewest    SortOption = "newest"
19    SortByPriceAsc  SortOption = "price_asc"
20    SortByPriceDesc SortOption = "price_desc"
21)
22
23// SearchResult adalah response berpaginasi untuk product search.
24type SearchResult struct {
25    Products   []ProductSearchItem
26    TotalItems int
27    Page       int
28    PerPage    int
29    TotalPages int
30}
31
32// ProductSearchItem adalah satu produk di hasil pencarian.
33// IsAvailable menangani kasus stock=0 sesuai clarification Q1.
34type ProductSearchItem struct {
35    ID           uuid.UUID
36    Name         string
37    PriceCents   int64
38    Stock        int
39    IsAvailable  bool // false ketika stock=0 (tampilkan badge "Out of Stock")
40    CategoryID   *uuid.UUID
41    ThumbnailURL string
42    Rank         float64 // skor ts_rank untuk debugging
43}

Perhatikan tag validate pada SearchQuery dan field IsAvailable pada ProductSearchItem — keduanya adalah terjemahan langsung dari acceptance criteria dan keputusan clarify menjadi kontrak tipe. Struct yang sudah membawa aturan validasi ini membuat implementasi usecase jauh lebih ringan.

Repository Implementation Plan

Bagian repository menyertakan SQL query lengkap yang akan diimplementasikan. Query berikut melakukan full-text search dengan filter kategori, sort dinamis, dan pagination.

sql
 1-- Full-text search dengan category filter, sort, dan pagination
 2-- Memakai ts_rank untuk relevance scoring sesuai clarification Q2
 3SELECT
 4    p.id, p.name, p.price_cents, p.stock,
 5    p.stock > 0 AS is_available,
 6    p.category_id, p.thumbnail_url,
 7    ts_rank(
 8        to_tsvector('indonesian', p.name || ' ' || COALESCE(p.description, '')),
 9        plainto_tsquery('indonesian', $1)
10    ) AS rank
11FROM products p
12WHERE
13    p.status = 'ACTIVE'
14    AND p.deleted_at IS NULL
15    AND to_tsvector('indonesian', p.name || ' ' || COALESCE(p.description, ''))
16        @@ plainto_tsquery('indonesian', $1)
17    AND ($2::uuid IS NULL OR p.category_id = $2)
18ORDER BY
19    CASE $3
20        WHEN 'relevance' THEN rank
21        WHEN 'newest' THEN EXTRACT(EPOCH FROM p.created_at)
22        WHEN 'price_asc' THEN p.price_cents::float
23        WHEN 'price_desc' THEN -p.price_cents::float
24    END DESC
25LIMIT $4 OFFSET $5

Query ini mengandung tiga keputusan clarify sekaligus: is_available dari Q1, ts_rank dari Q2, dan filter kategori opsional. GIN index yang dibuat sebelumnya akan meng-cover bagian @@ plainto_tsquery, jadi query ini seharusnya efisien — tapi tetap wajib diverifikasi dengan EXPLAIN ANALYZE sebelum di-commit.

API Design

Plan mendefinisikan kontrak API secara eksplisit. Tabel berikut merangkum query parameter beserta constraint dan default-nya.

ParameterTypeRequiredConstraintsDefault
qstringYESmin=2, max=100-
category_idUUIDNovalid UUIDnull
sortstringNorelevance / newest / price_asc / price_descrelevance
pageintNomin=11
per_pageintNomin=1, max=5020

Tabel parameter ini menjadi kontrak yang harus dipatuhi handler maupun test — setiap constraint di kolom “Constraints” akan menjadi satu test case validasi. Bentuk response sukses-nya diperlihatkan oleh JSON berikut.

json
 1{
 2  "data": {
 3    "products": [
 4      {
 5        "id": "550e8400-e29b-41d4-a716-446655440000",
 6        "name": "Laptop ASUS VivoBook",
 7        "price_cents": 750000000,
 8        "stock": 0,
 9        "is_available": false,
10        "category_id": "...",
11        "thumbnail_url": "https://cdn.santekno.com/products/...",
12        "rank": 0.0759904
13      }
14    ],
15    "pagination": { "page": 1, "per_page": 20, "total_items": 47, "total_pages": 3 }
16  }
17}

Contoh response dengan stock: 0 dan is_available: false di atas mengkonfirmasi bahwa keputusan clarify Q1 benar-benar terwujud sampai ke bentuk JSON. Sisi error-nya dipetakan ke error_code yang spesifik, seperti pada tabel berikut.

ScenarioHTTP Statuserror_code
Keyword < 2 chars422SEARCH_KEYWORD_TOO_SHORT
Keyword > 100 chars422SEARCH_KEYWORD_TOO_LONG
Invalid sort option422INVALID_SORT_OPTION
Invalid category_id422INVALID_CATEGORY_ID
per_page > 50422PER_PAGE_EXCEEDS_MAXIMUM
Database error500INTERNAL_ERROR

Pemetaan error_code yang eksplisit ini penting karena frontend akan bergantung pada kode-kode tersebut untuk menampilkan pesan yang tepat. Tanpa tabel ini, error handling cenderung diimprovisasi dan tidak konsisten.

Implementation Order

Plan menetapkan urutan implementasi yang menghormati dependency antar layer. Daftar bernomor berikut menjadi peta jalan pengerjaan.

text
11. Database migration → Create GIN index (safe, concurrent, no downtime)
22. DTO additions → SearchQuery, SearchResult, ProductSearchItem, SortOption
33. Interface additions → SearchUseCase + SearchFilter ke ProductRepository
44. Repository implementation → SearchProducts dengan full SQL
55. UseCase implementation → SearchProducts dengan validation dan mapping
66. Handler → SearchProducts dengan query param parsing
77. Route registration → Register GET /api/v1/products/search
88. Integration → Wire dependencies di main.go

Urutan ini bukan sembarang: migration dan tipe data harus ada lebih dulu sebelum repository, dan repository sebelum usecase. Mengikuti urutan ini mencegah kondisi “kode tidak bisa di-compile karena dependensi belum ada”.

Test Plan

Setiap acceptance criteria dipetakan ke test yang konkret. Tabel berikut memperlihatkan test usecase beserta AC yang di-cover.

TestCovers
TestSearchProducts_ValidKeyword_ReturnsResultsAC1, AC3
TestSearchProducts_DeactivatedProduct_NotInResultsAC2
TestSearchProducts_OutOfStockProduct_ShowsBadgeAC2a
TestSearchProducts_WithCategoryFilter_FiltersCorrectlyAC4
TestSearchProducts_NoResults_ReturnsEmptyAC6
TestSearchProducts_EmptyCategory_ReturnsEmptyWithMessageAC6a
TestSearchProducts_ShortKeyword_ReturnsValidationErrorAC7

Pemetaan 1:1 antara test dan AC ini membuat verifikasi spec compliance menjadi mekanis, bukan subjektif — cukup cek apakah semua AC punya baris di tabel. Test handler mengikuti pola serupa untuk lapisan HTTP.

Risks and Mitigations

Plan yang matang selalu jujur soal risiko. Cuplikan berikut menampilkan tiga risiko utama beserta mitigasinya.

text
 1Risk 1: Indonesian Full-Text Search Quality
 2  Risk: dictionary 'indonesian' mungkin tidak menangani semua kata dengan baik
 3  Mitigation: test dengan data produk nyata. Fallback: 'simple' dictionary
 4              atau custom synonym dict. Track: SHOP-300.
 5
 6Risk 2: Sort Performance
 7  Risk: CASE expression di ORDER BY mungkin tidak memakai index efisien
 8  Mitigation: EXPLAIN ANALYZE setelah implementasi. Pertimbangkan query terpisah
 9              per sort option jika performa kurang.
10
11Risk 3: Concurrent Index Creation
12  Risk: CREATE INDEX CONCURRENTLY pada tabel besar bisa makan waktu menit
13  Mitigation: jalankan saat low-traffic. Monitor pg_stat_progress_create_index.

Risiko yang disertai mitigasi konkret seperti ini jauh lebih berguna daripada sekadar “mungkin lambat, nanti dioptimasi”. Setiap mitigasi menunjuk aksi spesifik yang bisa dieksekusi, bahkan dengan nomor tiket tracking.

Dependencies and Assumptions

Bagian terakhir mendokumentasikan asumsi yang mendasari plan. Daftar berikut membuat asumsi tersebut eksplisit.

text
1Assumes:
2- Tabel products punya kolom: id, name, description, status, stock,
3  category_id, thumbnail_url, deleted_at
4- Index idx_products_category sudah ada (dari fitur product create)
5- Authentication middleware sudah terdaftar di router
6
7Dependencies on other features:
8- None (standalone feature, self-contained)

Menuliskan asumsi secara eksplisit mencegah kejutan: jika ternyata idx_products_category belum ada, kamu tahu itu blocker sejak membaca plan, bukan saat runtime. Inilah bagian yang paling sering diabaikan padahal paling menyelamatkan.


08.3 Memvalidasi Kualitas plan.md

Setelah plan dihasilkan, jangan langsung percaya. Jalankan validasi otomatis dengan flag --validate seperti berikut.

bash
1specify plan product-search --validate
2
3# Output:
4# All spec ACs accounted for in test plan
5# All spec error cases have error_code mappings
6# Database schema consistent with constitution (uuid, timestamptz, deleted_at)
7# Risk section has 3 risks but only 2 have concrete mitigations
8# Implementation order respects layer dependencies
9# No ORM references (constitution compliant)

Selain validasi otomatis, lakukan pengecekan manual terhadap aspek yang tidak bisa dinilai mesin. Checklist berikut memandu review manualmu.

text
 1Architecture Compliance:
 2- Interface di usecase package (bukan domain)?
 3- Dependency direction: handler → usecase → repository?
 4- Tidak ada ORM di plan?
 5
 6Completeness:
 7- Semua AC di spec punya test yang mapped?
 8- Semua error case punya error_code?
 9- Database migration disertakan jika ada schema change?
10
11Consistency:
12- Types konsisten dengan constitution (uuid.UUID, int64 untuk harga)?
13- Error wrapping sesuai constitution pattern?
14- Package names sesuai convention?
15
16Risk Assessment:
17- Risks identified?
18- Mitigations concrete?

Kombinasi validasi otomatis dan checklist manual ini menutup dua celah berbeda: mesin menangkap inkonsistensi mekanis, sementara mata manusia menilai apakah keputusan arsitektural benar-benar masuk akal untuk konteksmu.


08.4 Memodifikasi plan.md

Plan yang dihasilkan AI bukan dokumen final — kamu harus review dan modify sesuai kebutuhan. Perintah berikut menunjukkan tiga cara memodifikasi plan.

bash
1# Regenerate dengan instruksi tambahan
2specify plan product-search --add-instruction "Include Redis cache as Phase 5 after benchmarking"
3
4# Edit langsung (valid untuk perubahan minor)
5vim .specify/features/product-search/plan.md
6
7# Verifikasi perubahan tidak merusak consistency
8specify plan product-search --validate

Ada tiga hal yang paling sering perlu dimodifikasi, dan daftar berikut merangkumnya.

text
11. SQL query — AI menghasilkan query valid tapi mungkin bukan yang paling optimal
22. Implementation order — kadang urutan AI kurang tepat vs real dependency
33. Risk assessment — tambahkan risk spesifik yang kamu tahu dari pengalaman

Kunci di sini adalah selalu jalankan --validate setelah edit manual, karena perubahan kecil pun bisa memutus konsistensi antara plan dan spec. Plan yang diedit tanpa validasi ulang berisiko menyesatkan tahap tasks berikutnya.


08.5 Plan untuk Fitur dengan Kafka Integration

Untuk fitur yang melibatkan Kafka, plan menjelaskan event apa yang diproduce maupun diconsume. Cuplikan berikut memperlihatkan struktur bagian Kafka pada plan dan layout file konsumernya.

text
 1## Kafka Integration Plan
 2
 3### Event Produced: (none)
 4Product search tidak produce event (read-only operation).
 5Per constitution: Kafka hanya untuk event yang perlu diproses service lain.
 6
 7### Event Consumed: ProductUpdated
 8Search index harus di-update ketika product diupdate.
 9
10internal/product/consumer/
11├── product_updated_consumer.go       # Listens to product.updated Kafka topic
12└── product_updated_consumer_test.go

Pola consumer yang direkomendasikan constitution kemudian ditunjukkan sebagai kode Go nyata berikut, lengkap dengan error wrapping yang benar.

go
1// Consumer pattern sesuai constitution
2func (c *ProductUpdatedConsumer) Handle(ctx context.Context, event ProductUpdatedEvent) error {
3    // Update entri search index
4    if err := c.updateSearchIndex(ctx, event); err != nil {
5        return fmt.Errorf("Handle: updateSearchIndex: %w", err)
6    }
7    return nil
8}

Yang perlu dicermati: plan secara eksplisit menyatakan search TIDAK memproduce event karena bersifat read-only, sesuai constitution. Keputusan “tidak melakukan sesuatu” seperti ini justru sering terlupa didokumentasikan, padahal sama pentingnya dengan yang dilakukan.


08.6 Plan untuk Fitur yang Memodifikasi Schema yang Ada

Ketika plan melibatkan perubahan tabel existing, ia menyertakan strategi migrasi yang aman. Cuplikan berikut memperlihatkan strategi zero-downtime dengan langkah verifikasi dan rollback.

text
 1## Schema Migration Strategy
 2
 3Current State: tabel products belum punya full-text search support.
 4Target State: tambah GIN index untuk full-text search.
 5
 6Step 1: Create index CONCURRENTLY (zero-downtime)
 7Step 2: Verify index exists sebelum deploy kode baru
 8Step 3: Deploy application code (memakai index baru)
 9
10Estimated: ~30-60 detik untuk 100K produk.

SQL untuk verifikasi dan rollback-nya dipisahkan agar mudah dieksekusi terpisah, seperti berikut.

sql
1-- Verifikasi sebelum deploy
2SELECT indexname FROM pg_indexes
3WHERE tablename = 'products' AND indexname = 'idx_products_fts';
4-- Harus return 1 row sebelum deployment
5
6-- Rollback plan
7DROP INDEX CONCURRENTLY IF EXISTS idx_products_fts;

Urutan “buat index → verifikasi → baru deploy kode” ini kritikal: deploy kode yang mengandalkan index sebelum index-nya benar-benar ada akan menyebabkan query gagal di production. Rollback plan yang tersedia membuat migrasi ini reversible dengan aman.


08.7 Plan Complexity Indicator

Plan menyertakan indikator kompleksitas sebagai input estimasi. Cuplikan berikut menunjukkan bagaimana kompleksitas dihitung.

text
 1Estimated complexity: Medium
 2Estimation basis:
 3- 8 new files + 3 modified files
 4- 1 database migration
 5- 1 SQL query dengan full-text search
 6- 12 test case untuk ditulis
 7- No new external dependencies
 8
 9Time estimate: 3-4 developer days
10(Termasuk: implementasi + unit test + integration review)

Perlakukan angka ini sebagai input sprint planning, bukan sebagai commitment — ini estimate AI, bukan jaminan. Estimasi cenderung meleset ke bawah karena AI tidak tahu “hidden complexity” seperti legacy code atau ketidakfamiliaran tim.


08.8 Membandingkan Plan dengan Kode Existing

Sebelum mulai implementasi, verifikasi bahwa plan konsisten dengan pattern yang sudah ada. Perintah berikut membandingkan signature fungsi di plan dengan repository existing.

bash
 1# Lihat pattern di repository yang sudah ada
 2cat internal/product/repository/postgres_repository.go
 3
 4# Compare dengan plan
 5cat .specify/features/product-search/plan.md | grep "func "
 6
 7# Pastikan:
 8# 1. Function signatures konsisten
 9# 2. Error types konsisten
10# 3. Return types konsisten
11# 4. Package structure konsisten

Langkah perbandingan ini penting karena plan yang menyimpang dari pattern existing akan menghasilkan kode yang terasa “asing” di codebase. Menyamakan signature sejak tahap plan jauh lebih murah daripada refactor setelah kode ditulis.


08.9 Plan Review: Pertanyaan untuk Tech Lead

Saat plan disubmit untuk review lewat PR, tech lead perlu daftar pertanyaan yang terarah. Cuplikan berikut adalah pertanyaan review yang khas untuk fitur ini.

text
1Tech Lead Review Questions:
21. Apakah SQL full-text search sudah optimal? (ts_rank vs ts_rank_cd?)
32. Apakah ORDER BY dengan CASE expression akan dioptimasi planner?
43. Apakah dictionary 'indonesian' tersedia di PostgreSQL kita?
54. Apakah GIN index dibuat sebelum atau bersamaan dengan code deployment?

Pertanyaan-pertanyaan ini menyorot titik-titik keputusan yang paling berisiko: performa SQL, ketersediaan infrastruktur, dan strategi migrasi. Menjawabnya di tahap review plan mencegah surprise mahal saat implementasi.


08.10 Plan untuk API Gateway / Rate Limiting

Untuk endpoint yang butuh proteksi khusus, plan menempatkan rate limiting di layer middleware sesuai constitution. Kode Go berikut menunjukkan pendaftaran route dengan rate limiter spesifik untuk search.

go
1// handler/router.go
2// Rate limiting adalah tanggung jawab middleware, bukan handler.
3// Endpoint search butuh limit lebih ketat dari endpoint umum.
4productGroup.GET("/search", handler.SearchProducts,
5    middleware.RateLimitPerUser(60, time.Minute),  // 60 pencarian per menit per user
6    middleware.RateLimitGlobal(1000, time.Minute), // 1000 total pencarian per menit
7)

Menempatkan rate limiting sebagai middleware yang additive terhadap auth middleware menjaga handler tetap bersih dari cross-cutting concern. Plan yang menyebutkan angka konkret (60 dan 1000) juga memudahkan diskusi kapasitas dengan tim infrastruktur.


08.11 Plan Versioning

Plan harus di-update jika ada perubahan signifikan. Perintah berikut menunjukkan cara regenerate maupun update manual dengan version note.

bash
1# Ada perubahan spec setelah code review
2specify plan product-search --regenerate
3
4# Atau update manual untuk perubahan minor, tambahkan version note di header:
5# "Updated: 2025-07-05 — Added Redis cache as Phase 5 per team decision"

Version note di header plan berfungsi sebagai changelog mini yang menjelaskan mengapa plan berubah. Tanpa ini, tim akan bingung membedakan mana keputusan asli dan mana hasil revisi belakangan.


08.12 Plan untuk Berbagai Tipe Fitur

Bentuk plan menyesuaikan tipe fitur. Cuplikan berikut memperlihatkan kerangka plan untuk background job dan Kafka consumer.

text
 1## Plan untuk Background Job
 2Framework: time.AfterFunc / cron library
 3Trigger: setiap hari 02:00 WIB
 4Implementation: cmd/jobs/cleanup_expired_carts.go
 5Monitoring: log job start/end + items processed
 6
 7## Plan untuk Kafka Consumer
 8Topic: order.created
 9Consumer Group: product-service-order-consumer
10Partition Strategy: proses tiap partition independen (parallel safe)
11Error Handling: retry 3x, lalu DLQ (Dead Letter Queue)

Dua kerangka ini menegaskan bahwa specify plan bukan hanya untuk endpoint HTTP — ia sama kompetennya merencanakan job terjadwal maupun consumer event. Elemen seperti partition strategy dan DLQ menunjukkan plan sudah memikirkan reliability sejak awal.


08.13 Mengintegrasikan Plan dengan Sprint Planning

Plan bisa langsung dipakai sebagai input sprint planning. Cuplikan berikut memetakan fase-fase plan ke assignment developer dan estimasi waktu.

text
1Sprint Planning Input dari plan.md:
2Phase 1 (Domain/Types): 1.5 jam → @andi
3Phase 2 (Repository):   3 jam   → @andi
4Phase 3 (UseCase):      2 jam   → @citra
5Phase 4 (Handler):      2.5 jam → @citra
6Phase 5 (Integration):  1 jam   → pair: @andi + @citra
7
8Total estimate: ~10 jam ≈ 1.5 hari
9Sprint: masuk ke Sprint 24, priority P2 (setelah P1 cancel order)

Karena plan sudah memecah pekerjaan per fase dengan estimasi, sprint planning menjadi tinggal menugaskan orang — bukan lagi menghabiskan waktu memecah task dari nol. Ini memindahkan sebagian besar kerja perencanaan ke AI.


08.14 Plan sebagai Documentation

Plan.md yang baik adalah dokumentasi teknikal yang bisa dibaca developer baru. Cuplikan berikut menunjukkan pertanyaan-pertanyaan yang jawabannya terekam permanen di plan.

text
1Setelah project selesai, plan.md menjelaskan:
2- Kenapa pakai GIN index dan bukan pg_trgm?
3- Kenapa sort pakai CASE expression dan bukan separate queries?
4- Kenapa Indonesian dictionary dan bukan simple?
5- Kenapa stock=0 masih muncul di search?
6
7Semua keputusan terdokumentasi di plan.md + clarifications.md.
8Developer baru tidak perlu archaeology di git blame.

Nilai dokumentasi ini baru terasa berbulan-bulan kemudian, saat developer yang berbeda mempertanyakan sebuah keputusan. Plan yang menyimpan “mengapa”, bukan hanya “apa”, menghemat berjam-jam investigasi git blame.


08.15 Plan Metrics

Untuk visibilitas yang lebih terukur, plan bisa mengeluarkan metrik. Perintah berikut menampilkan ringkasan metrik plan.

bash
 1specify plan product-search --metrics
 2
 3# Plan Metrics: product-search
 4# Files to create: 8
 5# Files to modify: 3
 6# Migration files: 1
 7# Test cases planned: 12
 8# Estimated complexity: Medium
 9# LOC estimate: ~450 lines of Go code
10# Coverage target: 87% (per constitution)
11# Risk items: 3 (1 high, 2 medium)

Metrik seperti LOC estimate dan coverage target berguna sebagai baseline: setelah implementasi selesai, kamu bisa membandingkan realita dengan prediksi untuk memperbaiki akurasi estimasi di fitur berikutnya.


08.16 Tips & Gotchas

Berikut kumpulan tips dan jebakan yang sering muncul saat bekerja dengan specify plan.

💡 Tip 1: Review SQL secara detail — AI menghasilkan SQL valid tapi tidak selalu optimal; cek EXPLAIN ANALYZE di local sebelum commit.

💡 Tip 2: Verifikasi interface signatures konsisten dengan existing code — sesuaikan sebelum tasks dibuat agar tidak divergen.

💡 Tip 3: Sertakan plan.md di PR spec — reviewer bisa verify bahwa translasi spec → plan sudah benar.

💡 Tip 4: Plan adalah dokumen hidup — update jika ada temuan saat implementasi; jangan biarkan plan dan kode diverge.

⚠️ Gotcha 1: Plan tidak pernah 100% akurat untuk codebase baru — semakin mature codebase, semakin baik plan.

⚠️ Gotcha 2: Complexity estimate bisa off — AI sering underestimate karena tidak tahu hidden complexity.

⚠️ Gotcha 3: Jangan langsung accept SQL tanpa review — bisa ada N+1, full table scan, atau index tidak terpakai.

⚠️ Gotcha 4: Plan yang outdated lebih berbahaya dari tidak ada plan — update plan dulu, baru generate tasks ulang.

Benang merah semua poin ini: plan adalah artefak yang harus dikawal, bukan diterima mentah-mentah. Review SQL dan sinkronisasi dengan pattern existing adalah dua aktivitas dengan return tertinggi.


08.17 Dari Plan ke Tasks: Smooth Transition

Setelah plan divalidasi dan di-approve, langkah berikutnya adalah generate tasks. Perintah berikut menunjukkan transisinya.

bash
1specify tasks product-search
2# Reads: constitution.md + spec.md + plan.md
3# Output: .specify/features/product-search/tasks.md dengan task granular
4
5# Pastikan plan sudah final sebelum generate tasks
6# Perubahan plan setelah tasks di-generate = tasks harus di-regenerate juga

Urutan ini menegaskan bahwa tasks adalah turunan langsung dari plan — jadi memfinalkan plan lebih dulu menghindari pekerjaan regenerate ganda. Plan yang stabil adalah prasyarat tasks yang akurat.


08.18 Plan untuk Complex Feature: Multi-Phase Approach

Untuk fitur yang sangat kompleks, plan bisa menyertakan fase spike terlebih dahulu. Cuplikan berikut memperlihatkan kerangka plan multi-fase dengan Phase 0 sebagai spike.

text
 1# Technical Plan: E-commerce Checkout Flow
 2
 3## Overview
 4Fitur kompleks yang mencakup 5 layer dan 3 service. Plan disusun dalam 7 fase.
 5
 6## Phase 0: Spike (TIDAK masuk tasks.md)
 71. Verifikasi PostgreSQL transaction isolation level
 82. Benchmark concurrent order creation dengan SELECT FOR UPDATE
 93. Verifikasi Kafka exactly-once delivery configuration
10
11Hasil spike Phase 0 harus mengupdate plan ini sebelum Phase 1 dimulai.

Menempatkan spike sebagai Phase 0 yang eksplisit — dan menegaskan bahwa ia tidak masuk tasks.md — mencegah tim mengunci keputusan arsitektural sebelum ketidakpastian teknis terjawab. Untuk fitur berisiko tinggi, ini adalah pengaman yang berharga.


08.19 Plan Review Approval

Plan yang siap implementasi biasanya melewati approval formal. Cuplikan berikut menunjukkan format status review dengan komentar reviewer.

text
 1# Plan Review Status
 2
 3## Reviewer 1: @budi (Tech Lead) — APPROVED
 4"SQL query looks good. Suggest adding index on (category_id, status)
 5for combined filter performance. Updated plan."
 6
 7## Reviewer 2: @andi (Senior Dev) — APPROVED
 8"Risk 1 (Indonesian dictionary) needs DBA verification.
 9Added pre-deployment checklist."
10
11## Final Status: APPROVED FOR IMPLEMENTATION (2025-07-03, by @budi)

Jejak approval seperti ini mengubah plan dari draft menjadi kontrak yang disepakati tim. Komentar reviewer yang tercatat juga menjadi konteks berharga bila keputusan dipertanyakan di kemudian hari.


08.20 Ringkasan

Perintah specify plan mengubah spec bisnis menjadi blueprint teknikal yang actionable — file structure, SQL schema, API design, test plan, dan risk assessment untuk fitur Golang kamu.

Output terpenting: SQL query yang bisa langsung di-review, interface signature yang konsisten dengan pattern existing, dan test plan yang mapped ke setiap AC.

Validasi wajib: architecture compliance (clean architecture), completeness (semua AC punya test), dan SQL review (bukan sekadar valid tapi optimal).

Plan adalah dokumen hidup: update jika ada perubahan selama implementasi. Plan dan implementasi yang diverge adalah technical debt.

Di artikel berikutnya, kita bahas bagaimana plan yang sudah matang ini dipecah menjadi task-task konkret yang bisa di-assign dan dikerjakan paralel.

Artikel Terkait

💬 Komentar