Skip to content
Santekno.com | Level Up Your Engineering Skills
EN
📖 0%
26 Aug 2026 · 7 min read ·Article 31 / 208
Go

Case Study: A Golang CRUD API End-to-End with Spec Kit

A complete case study using GitHub Spec Kit to build a Golang CRUD API from constitution to merge. Every command, every output, and every decision made transparent — including the race condition the AI missed.

IH
Ihsan Arif
Writer at Santekno · Backend Engineer

This spec kit golang CRUD API case study shows all six Spec Kit commands working together to build the Product Category Management feature for Santekno Shop — a CRUD API that lets admins manage product categories while customers browse them read-only.

Timeline: 5.5 hours actual against an 8-hour estimate. Developer: @citra, a mid-level Go engineer. Every command, output, and decision below is real workflow, not an idealized demo.


11.1 The Workflow at a Glance

Before dissecting individual moments, here’s the whole day compressed into the commands that produced it — spec to merge in one screen.

bash
 1# 09:05 — Spec
 2specify feature category-management    # 8 min Q&A
 3specify clarify category-management    # 10 min (4 questions)
 4
 5# 09:26 — Plan
 6specify plan category-management       # 45 seconds
 7# Review + 1 correction (slug auto-generation instruction)
 8
 9# 09:40 — Tasks
10specify tasks category-management      # 30 seconds → 12 tasks in 4 phases
11
12# 09:45 — Commit spec → PR → merge (30 min)
13
14# 10:20 — Implementation
15specify implement category-management --phase=1  # 4 min + review + commit
16specify implement category-management --phase=2  # + race condition fix!
17specify implement category-management --phase=3
18specify implement category-management --phase=4
19
20# 14:30 — Validate
21specify validate --feature=category-management   # 9/9 ACs covered
22
23# 14:45 — PR → review → merge

The takeaway: notice how little of the day is spent typing commands — the value is in the review checkpoints between them, especially the Phase 2 fix that follows.


11.2 The Clarification That Mattered Most

Of the four clarify questions, one reshaped the database schema before a line of code existed. The exchange below is that question.

text
1Q4: Case sensitivity for unique names?
2A: Case-insensitive. "Electronics" and "electronics" are duplicates.
3→ Added: CREATE UNIQUE INDEX idx_categories_name_ci ON categories(LOWER(name))
4→ Without clarify: this would have been discovered in testing or production

The takeaway: specify clarify earns its keep here — a 30-second answer produced a schema-level constraint that would otherwise have surfaced as a production duplicate-data bug.


11.3 The Race Condition the AI Missed

The AI generated a SoftDelete that was logically correct but unsafe under concurrency. The two versions below show the gap and the fix @citra applied during review.

go
 1// AI generated (has race condition):
 2func (r *repo) SoftDelete(ctx context.Context, id uuid.UUID) error {
 3	var count int
 4	r.db.QueryRow(ctx, "SELECT COUNT(*) FROM products WHERE category_id = $1", id).Scan(&count)
 5	// ← GAP HERE: product could be created between count check and delete
 6	if count > 0 {
 7		return ErrCategoryHasProducts
 8	}
 9	r.db.Exec(ctx, "UPDATE categories SET deleted_at = NOW() WHERE id = $1", id)
10	return nil
11}
12
13// @citra fix: wrap in transaction with row lock
14func (r *repo) SoftDelete(ctx context.Context, id uuid.UUID) error {
15	tx, _ := r.db.Begin(ctx)
16	defer tx.Rollback(ctx)
17	// Lock and check + delete in a single transaction
18	// ... commit at the end
19	return nil
20}

The takeaway: the AI does not automatically detect concurrency issues — human review of check-then-act sequences and transaction boundaries remains essential.


11.4 Metrics

The numbers below quantify what the workflow actually delivered, so you can compare against your own runs.

text
1Time: 5.5h actual vs 8h estimated (31% faster)
2Coverage: 87-91% per layer (above the 85% target)
3Spec compliance: 9/9 ACs
4Bugs caught pre-merge: 1 (race condition)
5Bugs discovered via clarify: 1 (case-insensitive uniqueness)
6Permanent documentation: 4 .specify/ files

The takeaway: the headline isn’t just “faster” — it’s faster and fully documented, which is the combination raw vibe coding never delivers.


11.5 What Spec Kit Found (That Would Have Been Missed)

Two defects surfaced that a typical Slack-brief workflow would likely have shipped:

  1. Case-insensitive unique check — found by clarify Q4, not by the developer’s instinct.
  2. Race condition — found by @citra during code review, not by the AI.

This is the honest split: Spec Kit dramatically improves quality and speed, but human review remains essential for concurrency and security edge cases. One class of bug was caught by process, the other by a human — and you need both.


11.6 With vs Without Spec Kit

To make the value concrete, compare the same feature built the old way against the Spec Kit way. The breakdown below sets them side by side.

text
 1Without Spec Kit (estimated):
 2- Slack requirements discussion: 1h (undocumented)
 3- Trial-and-error implementation: 4h
 4- Review with many behavior questions: 2h
 5- Fix review comments: 1h
 6- Total: ~8h + no permanent documentation
 7
 8With Spec Kit:
 9- Spec + clarify + plan: 55 min (fully documented)
10- Implementation: 4.5h (focused, with roadmap)
11- PR review: 45 min (reviewer has spec reference)
12- Total: 5.5h + full documentation in .specify/

The takeaway: most of the saved time comes from the review phase — a reviewer holding the spec asks far fewer clarifying questions, which compounds across every future reader of the code.


11.7 Spec Compliance Report

At 14:30, specify validate mapped every acceptance criterion to a passing test. The report below is the result.

text
 1specify validate --feature=category-management
 2
 3✅ AC1: Admin list all categories
 4✅ AC2: Customer list active only
 5✅ AC3: Create with unique name
 6✅ AC4: Reject duplicate (case-insensitive) ← from clarify
 7✅ AC5: Auto-generate slug
 8✅ AC6: Update category
 9✅ AC7: Soft delete
10✅ AC8: Prevent delete with active products
11✅ AC9: Customer forbidden from admin endpoints
12
13Coverage: 91.3% (usecase), 87.2% (repository)

The takeaway: a green compliance report is not a formality — it’s an auditable statement that every requirement in the spec has a test proving it, which is what lets a reviewer approve with confidence.


11.8 Retrospective Actions

The most valuable output of a case study is the improvement it feeds back into the system. Two concrete actions came out of this one:

  1. Update the constitution: add a “check-then-act requires a transaction” rule — this prevents the race-condition pattern in every future feature.
  2. Update the plan template: add a “check dependent table indexes” section — this catches missing indexes at plan time instead of review time.

The loop is: case study → discover gaps → improve constitution and templates → better future features. Every project this way makes the next one safer by default.


11.9 Reusable Workflow Template

Finally, distill the whole flow into a script so the next feature starts in seconds. The template below scaffolds the spec branch and runs the four spec-phase commands.

bash
1#!/bin/bash
2FEATURE=$1 && TICKET=$2
3git checkout -b spec/${TICKET}-${FEATURE} develop
4specify feature $FEATURE && specify clarify $FEATURE
5specify plan $FEATURE && specify tasks $FEATURE
6git add .specify/features/${FEATURE}/ && git commit -m "spec(${TICKET}): add ${FEATURE} specification"
7echo "✅ Spec ready. Create PR → get approval → create feat branch → implement"

The takeaway: scripting the repetitive scaffolding removes friction, which is exactly what keeps a team following the process on the busy days when they’d otherwise cut corners.


11.10 Tips & Gotchas

The patterns from this case study generalize into a short field guide:

💡 Tip 1: Run clarify before plan — clarify findings become plan decisions.

💡 Tip 2: Correct the plan before tasks — it’s cheaper than regenerating tasks afterward.

💡 Tip 3: Race conditions are the AI’s most common blind spot — always review transaction boundaries manually.

💡 Tip 4: Actual time is typically faster than the AI estimate — all context is ready, so implementation stays focused.

⚠️ Gotcha 1: The AI doesn’t automatically detect concurrency issues — integration tests with concurrent requests matter.

⚠️ Gotcha 2: An uncorrected plan yields tasks that need regenerating — invest five minutes in plan review.

⚠️ Gotcha 3: The spec branch must merge before the implementation branch is created.

⚠️ Gotcha 4: Code-review findings aren’t always in Spec Kit’s scope — document them in plan.md for the next developer.


11.11 Summary

This case study demonstrates Spec Kit in action — from a Jira ticket to a merged PR in 5.5 hours. Every decision documented, every AC covered, all context stored in .specify/ for future reference.

Clearest value: 55 minutes for spec + plan + tasks saved hours of PR revision because reviewers had a clear reference.

Positive surprise: the AI found the case-insensitive uniqueness issue through clarify — an issue that might not have surfaced until testing or production.

Key finding: race conditions are not automatically handled by the AI — human review remains essential for concurrency scenarios.

With one feature fully traced from spec to merge, the natural next question is how to organize this at the repository level. Next, we cover the branching strategy that keeps each feature, spec, and branch tied together.

Related Articles

💬 Comments