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

Studi Kasus Spec Kit: CRUD API Golang End-to-End dari Constitution ke Merge

Studi kasus lengkap menggunakan GitHub Spec Kit untuk membangun CRUD API Golang dari constitution sampai merge. Semua perintah, semua output, semua keputusan transparan.

IH
Ihsan Arif
Penulis di Santekno · Backend Engineer

Studi Kasus: CRUD API Golang dari Spec Kit End-to-End

Saatnya melihat semua yang sudah kita pelajari bekerja bersama dalam satu studi kasus Spec Kit untuk CRUD API Golang yang nyata. Kita akan membangun fitur Product Category Management untuk Santekno Shop — CRUD API yang memungkinkan admin mengelola kategori produk, dari constitution sampai PR yang di-merge.

Timeline: 1 hari kerja. Developer: @citra (mid-level Go developer).


11.1 Situasi Awal

Selasa, 09:00 WIB

@citra menerima ticket SHOP-456: Implement product category management API dengan business requirements berikut:

  • Admin bisa list, create, update, dan delete kategori
  • Customer bisa list kategori (tanpa auth)
  • Kategori tidak bisa didelete jika masih ada produk
  • Nama kategori harus unik

@citra mengecek .specify/constitution.md dan specify.config.json — keduanya sudah ada dan up-to-date. Setup lengkap, sehingga ia bisa langsung masuk ke tahap spec.


11.2 Step 1: specify feature

09:05 WIB — Langkah pertama adalah menerjemahkan ticket menjadi spec formal lewat perintah berikut.

bash
1specify feature category-management

Perintah ini bukan sekadar membuat file kosong — ia memulai sesi tanya-jawab terstruktur yang memaksa requirement ambigu menjadi eksplisit.

Sesi Q&A berlangsung sekitar 8 menit dan menggali siapa pengguna, apa yang boleh, dan apa yang tidak boleh terjadi.

text
 11. Describe in 2-3 sentences:
 2> Admin-facing API to manage product categories on Santekno Shop.
 3> Customer-facing API to list available categories for filtering.
 4> Categories are used to group products in the catalog.
 5
 62. Who uses it?
 7> Admin: Full CRUD
 8> Customer: Read-only (list only)
 9> Product Service: References category_id in products
10
113. Must be able to:
12> Admin: Create category (name, description, slug)
13> Admin: Update category details
14> Admin: Soft delete category (if no active products)
15> Admin: List all categories (including inactive ones)
16> Customer: List active categories
17
184. Must NOT happen:
19> Delete category that has active products
20> Duplicate category names
21> Customer accessing admin-only endpoints
22
235. Business rules:
24> Category name: 2-100 chars, unique across all categories
25> Slug: URL-safe, auto-generated from name
26> Soft delete: marks inactive, products remain linked
27> Cascade: If parent category deleted, children become root-level

Hasil sesi ini adalah .specify/features/category-management/spec.md — dan perhatikan bahwa aturan seperti “unique across all categories” sudah tertangkap di sini, bukan ditemukan belakangan saat coding.


11.3 Step 2: specify clarify

09:15 WIB — Spec awal masih menyimpan ambiguitas. Perintah clarify menyuruh AI mengajukan pertanyaan yang belum terjawab.

bash
1specify clarify category-management

Perintah ini adalah jaring pengaman: ia menangkap keputusan desain yang mudah terlewat kalau langsung loncat ke implementasi.

Empat pertanyaan diajukan, dan jawabannya langsung berdampak pada skema database dan logika.

text
 1Q1: Hierarchical categories?
 2> No. Flat structure only for Phase 1. Hierarchy tracked: SHOP-457.
 3
 4Q2: What if same name but different case ("Electronics" vs "electronics")?
 5> Case-insensitive unique check. "Electronics" and "electronics" are duplicates.
 6
 7Q3: Slug generation rule?
 8> Lowercase, spaces→dashes, remove special chars. "Smart Phones" → "smart-phones"
 9
10Q4: What happens to products when category is soft-deleted?
11> Products keep their category_id reference. They become "uncategorized" in UI.
12> No cascade change to products.

09:25 WIB — Clarify selesai dan spec.md di-update dengan empat keputusan ini. Jawaban Q2 khususnya nanti akan menjelma menjadi sebuah unique index case-insensitive di database.


11.4 Step 3: specify plan

09:26 WIB — Dengan spec yang sudah jelas, perintah plan menerjemahkannya menjadi blueprint teknis.

bash
1specify plan category-management

Plan dihasilkan dalam 45 detik dan memuat tiga bagian kunci: struktur file, skema database, dan daftar endpoint. Bagian pertama, struktur file, memetakan persis file mana yang dibuat dan dimodifikasi.

text
 1Files to CREATE:
 2- internal/category/domain/entity.go
 3- internal/category/domain/errors.go
 4- internal/category/usecase/interface.go
 5- internal/category/usecase/dto.go
 6- internal/category/usecase/category_usecase.go
 7- internal/category/usecase/category_usecase_test.go
 8- internal/category/repository/postgres_repository.go
 9- internal/category/handler/http_handler.go
10- internal/category/handler/http_handler_test.go
11
12Files to CREATE (infrastructure):
13- migrations/20250703001_create_categories.sql
14
15Files to MODIFY:
16- internal/delivery/http/router/router.go

Daftar file ini menjadi peta jalan implementasi: @citra tahu persis apa yang akan berubah bahkan sebelum satu baris kode ditulis. Bagian kedua adalah skema database, di mana keputusan case-insensitive dari clarify diterjemahkan menjadi index konkret.

sql
 1CREATE TABLE categories (
 2    id          UUID PRIMARY KEY DEFAULT gen_random_uuid(),
 3    name        VARCHAR(100) NOT NULL,
 4    slug        VARCHAR(120) NOT NULL UNIQUE,
 5    description TEXT,
 6    is_active   BOOLEAN NOT NULL DEFAULT true,
 7    created_at  TIMESTAMPTZ NOT NULL DEFAULT NOW(),
 8    updated_at  TIMESTAMPTZ NOT NULL DEFAULT NOW(),
 9    deleted_at  TIMESTAMPTZ
10);
11
12CREATE UNIQUE INDEX idx_categories_name_ci
13ON categories(LOWER(name)) WHERE deleted_at IS NULL;

Index idx_categories_name_ci di atas adalah wujud nyata jawaban clarify Q2 — LOWER(name) memastikan “Electronics” dan “electronics” dianggap duplikat oleh database, bukan oleh kode aplikasi yang mudah lupa. Bagian ketiga adalah kontrak API yang memisahkan endpoint publik dan admin.

MethodPathAuthDescription
GET/api/v1/categoriesPublicList active categories
GET/api/v1/admin/categoriesAdmin JWTList all (incl inactive)
POST/api/v1/admin/categoriesAdmin JWTCreate category
PATCH/api/v1/admin/categories/:idAdmin JWTUpdate category
DELETE/api/v1/admin/categories/:idAdmin JWTSoft delete

Tabel endpoint ini menegakkan pemisahan admin vs customer yang muncul di spec: pemisahan otorisasi sudah menjadi keputusan desain eksplisit, bukan tambahan di menit terakhir. Setelah review, @citra menemukan satu hal yang perlu dikoreksi dan menambahkan instruksi berikut.

bash
1# Tambahkan instruksi: slug harus generated otomatis, bukan dari input
2specify plan category-management --add-instruction "Slug must be auto-generated from name, NOT user input. User provides name only."
3# Plan di-update

Koreksi kecil ini di tahap plan jauh lebih murah daripada menemukannya setelah kode slug terlanjur menerima input user — investasi lima menit yang menghemat rework nanti.


11.5 Step 4: specify tasks

09:40 WIB — Plan yang sudah dikoreksi dipecah menjadi task-task yang executable.

bash
1specify tasks category-management

Perintah ini mengubah blueprint menjadi checklist kerja yang terurut dan bisa dieksekusi satu per satu.

Hasilnya 12 task yang diorganisasi dalam 4 phase dengan estimasi waktu per task.

text
 1Phase 1: Domain + Migration [2h]
 2  Task 1.1: Create categories migration [30 min]
 3  Task 1.2: Create Category entity [30 min]
 4  Task 1.3: Create domain errors [20 min]
 5  Task 1.4: Create DTOs [30 min]
 6
 7Phase 2: Repository [2h]
 8  Task 2.1: Create repository interface [20 min]
 9  Task 2.2: Implement all CRUD methods [90 min]
10
11Phase 3: UseCase [2h]
12  Task 3.1: Implement usecase [60 min]
13  Task 3.2: Write usecase tests [60 min]
14
15Phase 4: Handler + Integration [2h]
16  Task 4.1: Implement HTTP handler [60 min]
17  Task 4.2: Write handler tests [45 min]
18  Task 4.3: Register routes [15 min]
19  Task 4.4: Wire dependencies [20 min]

Pembagian per phase inilah yang nanti memberi checkpoint review alami: setelah tiap phase, @citra bisa berhenti dan memverifikasi arah sebelum lanjut. 09:45 WIB — spec, plan, dan tasks di-commit ke spec branch untuk review.

bash
 1git checkout -b spec/SHOP-456-category-management
 2git add .specify/features/category-management/
 3git commit -m "spec(SHOP-456): add category management specification
 4
 5Spec: .specify/features/category-management/spec.md (v1.1 after clarify)
 6Plan: .specify/features/category-management/plan.md
 7Tasks: .specify/features/category-management/tasks.md (12 tasks, ~8h estimated)"
 8
 9git push origin spec/SHOP-456-category-management
10# PR dibuat → review by @budi → approved 30 min kemudian

Dengan mem-push spec branch lebih dulu, @budi bisa mereview keputusan desain sebelum sebaris kode implementasi ditulis — feedback loop paling awal dan paling murah.


11.6 Step 5: Implementation

10:20 WIB — Spec PR merged. @citra membuat implementation branch dari develop.

bash
1git checkout -b feat/SHOP-456-category-management develop

Branch terpisah ini menjaga implementasi tetap terikat ke spec yang sudah approved. Phase pertama dijalankan dengan verbose logging agar setiap task terpantau.

bash
1specify implement category-management --phase=1 --verbose

Log real-time berikut menunjukkan keempat task Phase 1 selesai dalam waktu di bawah empat menit.

text
 1[10:21:00] Phase 1 started
 2[10:21:00] Task 1.1: Create categories migration...
 3[10:21:16] ✓ migrations/20250703001_create_categories.sql created
 4[10:21:16] Running: psql $LOCAL_DB_URL -f migrations/20250703001_create_categories.sql
 5[10:21:18] ✓ Migration applied locally
 6
 7[10:21:18] Task 1.2: Create Category entity...
 8[10:21:28] ✓ internal/category/domain/entity.go created (67 lines)
 9
10[10:21:28] Task 1.3: Create domain errors...
11[10:21:37] ✓ internal/category/domain/errors.go created (32 lines)
12
13[10:21:37] Task 1.4: Create DTOs...
14[10:21:52] ✓ internal/category/usecase/dto.go created (78 lines)
15
16[10:21:52] Running post_implement: go build ./...
17[10:21:55] ✓ Build OK

Phase 1 selesai dalam 3 menit 55 detik, tapi kecepatan tanpa review tidak bernilai — @citra memeriksa output entity berikut sebelum melanjutkan.

go
 1// internal/category/domain/entity.go — diperiksa @citra
 2
 3type Category struct {
 4    ID          uuid.UUID  `json:"id"`
 5    Name        string     `json:"name"`
 6    Slug        string     `json:"slug"`
 7    Description *string    `json:"description,omitempty"`
 8    IsActive    bool       `json:"is_active"`
 9    CreatedAt   time.Time  `json:"created_at"`
10    UpdatedAt   time.Time  `json:"updated_at"`
11    DeletedAt   *time.Time `json:"-"`
12}
13
14// ✅ Struktur sesuai plan
15// ✅ DeletedAt untuk soft delete
16// ✅ IsActive boolean (bukan status string)

Entity di atas lolos review karena cocok dengan plan: DeletedAt pointer untuk soft delete dan IsActive sebagai boolean — persis yang dirancang. Setelah review OK, Phase 1 di-commit.

bash
1# Review OK, commit Phase 1
2git add .
3git commit -m "feat(category): add domain layer and migration [SHOP-456 Phase 1]
4
5- Category entity with soft delete support
6- Domain errors: ErrCategoryNotFound, ErrCategoryNameExists, ErrCategoryHasProducts
7- DTOs: CreateCategoryInput, UpdateCategoryInput, CategoryResponse
8- Migration: idx_categories_name_ci (case-insensitive unique)"

Pesan commit yang mereferensikan phase dan daftar error domain membuat history bercerita sendiri. Lanjut ke Phase 2, repository.

bash
1specify implement category-management --phase=2

Output-nya adalah postgres_repository.go dengan lima method. @citra fokus pada method paling kompleks, yaitu SoftDelete, yang menegakkan aturan “tidak boleh delete jika ada produk”.

go
 1// SoftDelete — sesuai dengan business rule "tidak boleh delete jika ada produk"
 2func (r *postgresCategoryRepository) SoftDelete(ctx context.Context, id uuid.UUID) error {
 3    // Check apakah ada active products
 4    var productCount int
 5    err := r.db.QueryRow(ctx,
 6        `SELECT COUNT(*) FROM products WHERE category_id = $1 AND status = 'ACTIVE' AND deleted_at IS NULL`,
 7        id).Scan(&productCount)
 8    if err != nil {
 9        return fmt.Errorf("SoftDelete: check products: %w", err)
10    }
11    if productCount > 0 {
12        return domain.ErrCategoryHasProducts
13    }
14
15    // Soft delete
16    result, err := r.db.Exec(ctx,
17        `UPDATE categories SET deleted_at = NOW(), updated_at = NOW() WHERE id = $1 AND deleted_at IS NULL`,
18        id)
19    if err != nil {
20        return fmt.Errorf("SoftDelete: exec: %w", err)
21    }
22    if result.RowsAffected() == 0 {
23        return domain.ErrCategoryNotFound
24    }
25    return nil
26}

Kode ini logically correct, tapi @citra langsung menangkap masalah: “Race condition! Antara check productCount dan soft delete, bisa ada product yang masuk.” Perbaikannya membungkus keduanya dalam satu transaksi.

go
 1// Fix: wrap dalam transaction dengan FOR UPDATE
 2func (r *postgresCategoryRepository) SoftDelete(ctx context.Context, id uuid.UUID) error {
 3    tx, err := r.db.Begin(ctx)
 4    if err != nil {
 5        return fmt.Errorf("SoftDelete: begin tx: %w", err)
 6    }
 7    defer tx.Rollback(ctx)
 8
 9    // Lock category row
10    var productCount int
11    err = tx.QueryRow(ctx,
12        `SELECT COUNT(*) FROM products WHERE category_id = $1 AND status = 'ACTIVE' AND deleted_at IS NULL
13         -- Lock products check via NOWAIT to avoid deadlock`,
14        id).Scan(&productCount)
15    // ... rest of logic in transaction
16}

Inilah blind spot AI yang paling khas: kode yang benar secara logika sekuensial tapi rawan di skenario konkuren. Setelah fix, test dijalankan dan Phase 2 di-commit.

bash
 1# Edit manual, run test
 2go test ./internal/category/repository/...
 3# ✅ PASS
 4
 5git add .
 6git commit -m "feat(category): add repository with race condition fix [SHOP-456 Phase 2]
 7
 8Race condition fix: SoftDelete now uses transaction to prevent
 9concurrent product creation + category deletion race.
10Ref: clarification Q4 (product-category relationship)"

Commit ini mendokumentasikan bukan hanya apa yang berubah, tapi kenapa — referensi ke clarification Q4 membuat keputusan bisa ditelusuri di masa depan. Phase 3 dan 4 dijalankan berurutan.

bash
1specify implement category-management --phase=3
2specify implement category-management --phase=4

Kedua phase selesai tanpa issue major; @citra tetap mereview dan commit tiap phase seperti sebelumnya.


11.7 Final Check: Spec Compliance

14:30 WIB — Sebelum membuka PR, @citra menjalankan validasi otomatis untuk memastikan tidak ada AC yang terlewat.

bash
1specify validate --feature=category-management

Laporan berikut memetakan setiap AC ke test yang membuktikannya.

text
 1✅ Spec Compliance Report: category-management
 2
 3AC Coverage:
 4✅ AC1: Admin list all categories — TestListAllCategories_AdminRole
 5✅ AC2: Customer list active only — TestListCategories_CustomerRole_ActiveOnly
 6✅ AC3: Create with unique name — TestCreateCategory_Success
 7✅ AC4: Reject duplicate name (case-insensitive) — TestCreateCategory_DuplicateName
 8✅ AC5: Auto-generate slug — TestCreateCategory_SlugGenerated
 9✅ AC6: Update category — TestUpdateCategory_Success
10✅ AC7: Soft delete — TestSoftDeleteCategory_Success
11✅ AC8: Prevent delete with active products — TestSoftDeleteCategory_HasProducts
12✅ AC9: Customer cannot access admin endpoints — TestAdminEndpoints_CustomerForbidden
13
14Coverage: 91.3% (usecase), 87.2% (repository)
15All ACs covered. No spec drift detected.

Laporan “9/9 AC covered, no spec drift” ini memberi @citra keyakinan objektif bahwa implementasi sudah sepadan dengan spec — bukan sekadar “rasanya sudah selesai”.


11.8 Pull Request

14:45 WIB — PR dibuka dengan deskripsi yang menautkan implementasi ke spec dan keputusan clarify.

markdown
 1## Category Management CRUD API — SHOP-456
 2
 3### Spec Compliance
 4All 9 ACs from spec.md covered. See .specify/features/category-management/spec.md v1.1
 5
 6### Key Decisions (from clarifications)
 7- Slug: auto-generated from name (user never sets slug directly)
 8- Unique check: case-insensitive (idx_categories_name_ci)
 9- Delete protection: transaction-based race condition prevention
10
11### Race Condition Fix
12SoftDelete uses transaction to prevent race between product count check
13and actual delete. This was not in the original plan — discovered during impl.
14plan.md updated to reflect this.
15
16### Test Coverage
17- UseCase: 91.3%
18- Repository: 87.2%
19- Handler: 83.6%
20All above 85% target per constitution.

Deskripsi PR yang kaya seperti ini memberi reviewer konteks penuh — spec, keputusan, dan temuan — sehingga review jadi soal verifikasi, bukan menebak-nebak niat.


11.9 Code Review dan Merge

15:00–15:30 WIB — @budi mereview dengan spec sebagai acuan.

text
1✅ Spec compliance: semua AC ter-cover
2✅ Architecture: Clean Architecture diikuti
3✅ Race condition fix: good catch!
4💬 Suggestion: Add index on category_id in products table
5    (for performance of "has active products?" check)

Review yang berbasis spec berjalan cepat dan fokus; satu-satunya saran (index performa) bersifat improvement, bukan koreksi bug. @citra menambahkan migration untuk index, PR di-approve, dan di-merge.


11.10 Metrik Studi Kasus

Angka akhir memberi gambaran objektif seberapa efisien workflow ini dibanding estimasi awal.

text
 1Total waktu: ~5.5 jam aktual (dari 8h estimate)
 2
 3Breakdown:
 4- Spec (feature + clarify): 25 menit
 5- Plan + tasks: 30 menit (termasuk 1 correction)
 6- Phase 1: 25 menit (implement + review + commit)
 7- Phase 2: 90 menit (implement + race condition fix + test)
 8- Phase 3: 80 menit (implement + review + commit)
 9- Phase 4: 60 menit (implement + review + commit + route)
10- PR + review: 45 menit
11
12Coverage akhir: 87-91% per layer
13Spec compliance: 9/9 ACs
14Bugs found dalam review: 1 (race condition — caught sebelum merge)

Yang menonjol: 55 menit di depan untuk spec + plan + tasks justru mempercepat sisanya karena implementasi berjalan terarah, bukan trial-and-error.


11.11 Pelajaran dari Studi Kasus

Pelajaran 1: Race condition tidak ter-detect oleh AI tanpa test — AI menghasilkan kode yang logically correct tapi tidak aman dari concurrent access. Review manual dan test yang baik yang mendeteksinya.

Pelajaran 2: Plan correction lebih murah dari kode yang salah — menambahkan instruksi ke plan (slug auto-generated) menghemat 30 menit fix di implementation.

Pelajaran 3: specify clarify mengisi gap yang tidak terpikir — pertanyaan tentang case-insensitive uniqueness tidak ada di spec original. AI menemukannya, 5 menit untuk menjawab, dan berpengaruh ke SQL index.

Pelajaran 4: Actual time lebih cepat dari estimate AI — 8h estimate menjadi 5.5h actual, karena semua context sudah ada dan implementasi lebih fokus.


11.12 Perbandingan: Dengan dan Tanpa Spec Kit

Untuk menilai dampak sebenarnya, bandingkan alur ini dengan cara kerja konvensional pada fitur setara.

text
 1Tanpa Spec Kit (estimated):
 2- Define requirements di slack: 1h (tidak terdokumentasi)
 3- Implement trial-and-error: 4h
 4- Review: 2h (banyak pertanyaan tentang behavior)
 5- Fix review comments: 1h
 6- Total: ~8h + tidak ada dokumentasi permanen
 7
 8Dengan Spec Kit:
 9- Spec + clarify + plan: 55 menit (semua terdokumentasi)
10- Implement + review: 4.5h (focused, ada roadmap)
11- PR review: 45 menit (reviewer punya spec sebagai reference)
12- Total: 5.5h + full dokumentasi di .specify/

Selisihnya bukan hanya 2.5 jam waktu, tapi juga dokumentasi permanen di .specify/ yang tidak ada pada pendekatan konvensional — nilai yang terus berlaku setelah fitur di-merge.


11.13 Files yang Dihasilkan

Sebagai gambaran output konkret, berikut seluruh file yang lahir dari satu siklus ini.

text
 1.specify/features/category-management/
 2├── spec.md (v1.1) — 89 baris, approved
 3├── clarifications.md — 24 baris
 4├── plan.md — 156 baris
 5└── tasks.md — 98 baris (semua [x])
 6
 7internal/category/
 8├── domain/entity.go — 67 baris
 9├── domain/errors.go — 32 baris
10├── usecase/interface.go — 45 baris
11├── usecase/dto.go — 78 baris
12├── usecase/category_usecase.go — 134 baris
13├── usecase/category_usecase_test.go — 187 baris
14├── repository/postgres_repository.go — 213 baris
15└── handler/http_handler.go — 156 baris
16
17migrations/
18└── 20250703001_create_categories.sql — 18 baris
19
20Total: ~1,077 baris Go + SQL yang di-produce dalam 5.5 jam

Rincian ini menunjukkan bahwa spec bukan overhead terpisah dari kode — keduanya lahir bersama dan ter-version dalam satu commit history yang sama.


11.14 Template untuk Studi Kasus Berikutnya

Karena workflow-nya berulang, langkah-langkah di atas layak disimpan sebagai script template.

bash
 1# Template script: scripts/new-feature.sh
 2#!/bin/bash
 3FEATURE=$1
 4TICKET=$2
 5
 6echo "🚀 Starting Spec Kit workflow for $FEATURE ($TICKET)"
 7
 8# Step 1: Spec branch
 9git checkout -b spec/${TICKET}-${FEATURE} develop
10specify feature $FEATURE
11specify clarify $FEATURE
12specify plan $FEATURE
13specify tasks $FEATURE
14
15# Step 2: Commit spec
16git add .specify/features/${FEATURE}/
17git commit -m "spec(${TICKET}): add ${FEATURE} specification"
18echo "✅ Spec ready. Create PR, get approval, then run:"
19echo "   git checkout -b feat/${TICKET}-${FEATURE} develop"
20echo "   specify implement ${FEATURE} --phase=1"

Dengan script ini, tahap spec untuk fitur berikutnya menjadi satu perintah — konsistensi workflow tidak lagi bergantung pada ingatan tiap developer.


11.15 Gotchas Spesifik dari Studi Kasus Ini

Dua kategori gotcha muncul dari studi kasus ini — yang ditemukan dan yang berhasil dihindari.

Gotcha yang ditemukan:

  1. Race condition di SoftDelete — AI tidak otomatis menanganinya tanpa test coverage yang proper
  2. Plan perlu correction untuk slug auto-generation — penting untuk dikoreksi SEBELUM tasks di-generate

Gotcha yang dihindari berkat Spec Kit:

  1. Case-insensitive unique — terdeteksi saat clarify, bukan saat testing
  2. Admin vs Customer endpoint separation — terdefinisi jelas di spec dari awal

Polanya jelas: masalah yang tertangkap lebih awal (di spec/clarify) jauh lebih murah daripada yang lolos sampai review atau produksi.


11.16 Tips & Gotchas

💡 Tip 1: Selalu run specify clarify sebelum specify plan — clarify yang baik menghasilkan plan yang akurat.

💡 Tip 2: Correction ke plan sebelum tasks lebih murah dari correction setelah implementasi.

💡 Tip 3: Race condition adalah blind spot AI yang paling umum — selalu review transaction boundaries secara manual.

💡 Tip 4: Actual time lebih cepat dari estimate karena context sudah siap. Budget dengan confidence.

⚠️ Gotcha 1: AI tidak selalu mendeteksi concurrency issue tanpa test — integration test dengan concurrent requests penting.

⚠️ Gotcha 2: Plan yang tidak dikoreksi sebelum tasks = tasks yang perlu di-regenerate.

⚠️ Gotcha 3: Spec branch harus di-merge sebelum implementation branch dibuat.

⚠️ Gotcha 4: Saran @budi tentang index tidak ada di plan — temuan dari review tidak selalu ter-capture di Spec Kit.


11.17 Ekstensi: Menambahkan Fitur ke Spec yang Sudah Ada

Jika setelah merge ada request untuk menambah fitur kecil, siklus Spec Kit bisa diulang secara terarah pada scope yang sempit.

bash
 1# Update spec dengan fitur baru
 2specify feature category-management --add-ac "AC10: Category can have an icon image URL"
 3
 4# Clarify jika perlu
 5specify clarify category-management --questions="Regarding AC10 only"
 6
 7# Regenerate plan dengan perubahan
 8specify plan category-management --regenerate --scope="AC10 only"
 9
10# Tasks untuk AC10 saja
11specify tasks category-management --scope="AC10"

Dengan flag --scope, kamu bisa menambah satu AC tanpa merombak seluruh spec — perubahan tetap kecil, terdokumentasi, dan tertelusur.


11.18 Retrospective Setelah Studi Kasus

Di sprint retrospective, tim menilai apa yang berhasil dan apa yang perlu diperbaiki.

text
 1What worked:
 2✅ specify clarify menemukan case-insensitive unique yang terlewat
 3✅ Race condition fix sebelum production (bukan setelah)
 4✅ PR review jauh lebih focused — reviewer punya spec sebagai guide
 5✅ 5.5h vs 8h estimate — lebih efisien dari perkiraan
 6
 7What could be better:
 8⚠️ Plan tidak menyebutkan race condition risk — perlu ditambahkan ke constitution
 9    sebagai "Always use transaction for check-then-act patterns"
10⚠️ Index untuk products.category_id ditemukan saat review, bukan saat plan
11    — perlu ditambahkan ke plan template
12
13Actions:
141. Update constitution: add "check-then-act requires transaction" rule
152. Update plan template: add "check dependent table indexes" section

Inti retrospective ini adalah loop perbaikan: temuan dari satu fitur diangkat ke constitution dan template, sehingga fitur berikutnya berangkat dari fondasi yang lebih baik.


11.19 Ke Mana Selanjutnya

Dari studi kasus ini, tim Santekno Shop memiliki:

  • Foundation untuk fitur kategori yang bersih dan terdokumentasi
  • Template workflow yang bisa direplikasi untuk fitur berikutnya
  • Constitution yang lebih baik (race condition rule ditambahkan)
  • Confidence bahwa Spec Kit workflow bekerja di production project

11.20 Ringkasan

Studi kasus ini menunjukkan Spec Kit dalam action — dari ticket di Jira sampai PR yang di-merge dalam 5.5 jam. Setiap keputusan terdokumentasi, setiap AC ter-cover, dan semua context tersimpan di .specify/ untuk referensi masa depan.

Nilai yang paling jelas: Waktu 55 menit untuk spec + plan + tasks menghemat berjam-jam revisi di PR karena reviewer punya referensi yang jelas.

Kejutan positif: AI menemukan case-insensitive unique issue melalui clarify — issue yang mungkin tidak terdeteksi sampai testing atau production.

Temuan penting: Race condition tidak otomatis di-handle oleh AI — human review tetap esensial untuk skenario concurrency.

Setelah melihat satu fitur berjalan end-to-end, pertanyaan berikutnya adalah bagaimana mengelola banyak fitur secara paralel tanpa saling bertabrakan. Di artikel berikutnya kita bahas prinsip branching yang membuat setiap fitur terikat rapi ke spec-nya sendiri.

Artikel Terkait

💬 Komentar