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

SDD Golang Case Study: Order Service E-commerce from Spec to Merge

A complete Specification-Driven Development case study in Golang: how Santekno Shop's cancel order feature was built from scratch using SDD with Claude Code, from the first spec to a production merge.

IH
Ihsan Arif
Writer at Santekno · Backend Engineer

Case Study: Order Service E-commerce from Spec to Merge

We’ve covered every SDD component in isolation. Now it’s time to watch them work together in one real, end-to-end flow — a SDD golang case study on an actual order service.

This case study illustrates the implementation of the Cancel Order feature in Santekno Shop — from the first spec written to a PR merged to production. All steps, all prompts, all decisions are fully transparent.

Timeline: 1.5 working days. Developer: @andi (mid-level Go developer, 2 years of experience).


19.1 Starting Point

Monday, 08:30 WIB

@andi receives Jira ticket SHOP-456: implement cancel order for the customer. The business requirements are clear (customer can cancel their own order, stock is restored, an email notification is sent), but no spec exists yet.

His first move is not to open the editor — it’s to open CLAUDE.md, which states plainly: every feature needs a reviewed spec before implementation starts. The decision follows directly from that rule: write the spec first.


19.2 Phase 1 — Writing the Spec

@andi opens Claude Code and starts the session with clear context. The prompt below deliberately front-loads the business requirements and then asks Claude to raise clarification questions instead of jumping straight to a draft.

text
1I want to implement SHOP-456: cancel order feature.
2Before implementing, I need to write a spec.
3
4Business requirements:
5- Customer can cancel their own order
6- Product stock restored after cancel
7- Customer gets notification email (via Kafka → Notification Service)
8
9Ask clarification questions that need answering before spec can be written.

The last instruction is what matters most: by asking for open questions first, @andi turns a vague ticket into a set of decisions that must be made explicitly rather than assumed.

Claude responds with five clarification questions — cancel window, status restriction, refund, concurrent handling, and admin scope. After confirming each one with the PM and tech lead, @andi has firm answers:

  • Cancel window: 30 minutes (updated from 15 based on user research)
  • Status: PENDING only
  • No refund (payment is not in scope)
  • Concurrent cancel: first wins
  • Admin cancel: out of scope

@andi feeds these answers back, Claude drafts the spec, and @andi reviews and edits it. Monday, 10:30 WIB — @andi creates the spec PR with the label spec-review.


19.3 Phase 2 — Spec Review

Monday, 11:00 WIB

@budi (tech lead) and @maya (PM) review the spec and return four pieces of feedback:

  1. AC5 needs to be explicit that stock restore is “atomic, in one DB transaction”
  2. EC1 needs to specify “use SELECT FOR UPDATE” to prevent the race condition
  3. NFR-P2 latency target is too loose — tighten it to p95 < 300ms
  4. Confirm the 30-minute window (the original ticket said 15)

@andi addresses all four points. Monday, 13:00 — the spec is approved and the PR is merged. Note that this review was not a rubber stamp: @budi caught a real problem with the latency target before a single line of code existed.


19.4 Phase 3 — Plan Mode

Monday, 13:30 WIB

With the spec approved, @andi moves to planning — still without writing any code. The prompt below asks Claude to surface files, queries, migrations, and risks up front, so architectural surprises appear now rather than mid-implementation.

text
 1Spec cancel-order.md v1.0 is approved.
 2
 3BEFORE writing code, create an implementation plan:
 4- Files to create/modify
 5- SQL queries for CancelWithStockRestore
 6- DB migration needed
 7- Dependency order
 8- Risks based on EC1-EC3
 9
10Reference patterns: internal/usecase/order/create_order.go
11Don't write code. Only the plan.

The plan pays off immediately: it reveals that an EventPublisher interface must be created first — the concrete Kafka struct exists, but no interface does. Catching this dependency before coding saves a mid-stream refactor.


19.5 Phase 4 — Task Breakdown

The plan is then broken into eleven small tasks, each 10–90 minutes, with a total estimate of 6.5 hours:

  1. Entity update (30 min)
  2. EventPublisher interface (20 min)
  3. Repository interface (20 min)
  4. Mock regeneration (10 min)
  5. DB migration (15 min)
  6. Repository implementation (90 min)
  7. UseCase implementation (60 min)
  8. UseCase tests (75 min)
  9. HTTP handler (45 min)
  10. Route registration (10 min)
  11. Smoke test (20 min)

Keeping each task under 90 minutes means it can be prompted, reviewed, tested, and committed independently — the granularity that keeps AI-generated code reviewable.


19.6 Phase 5 — Incremental Implementation

Monday, 14:30 WIB

Each task is executed with a focused Claude Code prompt, then reviewed, tested, and committed on its own. The commit messages below show how every commit links back to the exact AC/EC it satisfies.

bash
1# Task 1 commit
2git commit -m "feat(order): add StatusCancelled and CanBeCancelled method
3Implements: cancel-order.md v1.0 AC3, AC4"
4
5# Task 6 commit
6git commit -m "feat(order): implement cancel order repository methods
7- GetByIDAndUserID: nil,nil for not-found OR not-owner (security)
8- CancelWithStockRestore: atomic with SELECT FOR UPDATE (EC1)
9Implements: cancel-order.md v1.0 AC2, AC5, EC1"

The spec references in these commits turn the git log into an audit trail: months later, anyone can trace a line of code back to the requirement that justified it. End of Monday: Tasks 1–8 are complete across 6 commits, with 93.7% coverage.


19.7 Phase 6 — Handler and Integration

Tuesday, 09:00

With the domain and use case in place, @andi implements the HTTP handler. The most important detail is the test, which asserts the exact error-code string the spec mandates rather than a loose approximation.

go
1// Spec compliance assertion — prevents spec drift
2s.Equal("ORDER_NOT_CANCELLABLE", body["error_code"],
3    "error_code must match spec cancel-order.md AC9 exactly")

Because the string is asserted verbatim, any future change to that error code fails CI immediately — spec drift is caught mechanically, not by memory. All four manual smoke tests (happy path, not found, already confirmed, no auth) pass.


19.8 Phase 7 — Final Compliance Check

Tuesday, 11:00

Before opening the PR, @andi runs one last self-check that maps every acceptance and edge case in the spec to the code and tests that cover it. The prompt below drives that audit.

text
1Do a final spec compliance check.
2Spec: cancel-order.md v1.0
3Files: entity.go, cancel_order.go, order_repository.go, order_handler.go, router.go
4
5For each AC (AC1-AC10) and EC (EC1-EC3):
6- Where is it implemented?
7- Is there a test covering it?
8- Are there any gaps?

The result: 12 of 13 items fully covered, with EC3 flagged as an acknowledged gap tracked in JIRA-789. Running this before the PR is the cheapest possible place to find a gap — 20 minutes here versus a costly round-trip after review.


19.9 Phase 8 — Pull Request

Tuesday, 11:30

@andi opens the PR with a complete description: spec reference and version, a full AC/EC compliance table, the AI compliance-check output (collapsed), the 93.7% coverage number, the list of changed files, and a reviewer checklist. Everything a reviewer needs to verify the work against the spec is in one place, so the review can focus on judgment rather than archaeology.


19.10 Phase 9 — Code Review

Tuesday, 13:00

@budi reviews the PR and returns three points:

  1. Warning: the userID extraction needs a comment documenting the middleware assumption
  2. Praise: the SELECT FOR UPDATE implementation matches the ADR-003 pattern exactly
  3. Suggestion (non-blocking): extract the context key into a constant to avoid a magic string

@andi addresses all three. Tuesday, 14:30 — the PR is approved and merged. Notice what the reviewer did not have to ask: there were zero “does this handle X?” questions, because every case was already traced to a test.


19.11 Post-Merge

Tuesday, 15:00

After merge, @andi closes the loop with a short set of housekeeping steps:

  • The Jira ticket is moved to Done
  • The spec status transitions DRAFT → APPROVED → ACTIVE
  • Stakeholders are notified in Slack
  • The known gap (EC3) is tracked in JIRA-789

These steps keep the spec and the reality in sync, which is what makes the spec trustworthy for the next developer who reads it.


19.12 Metrics from This Case Study

To make the trade-off concrete, here is where the 12.5 hours actually went, along with the outcomes it produced.

text
 1Writing spec:           2 hours (including PM clarification)
 2Spec review:            2 hours (review + revision + approval)
 3Plan Mode:              30 minutes
 4Task breakdown:         20 minutes
 5Implementation:         5 hours
 6Compliance check:       20 minutes
 7PR:                     30 minutes
 8Code review:            1.5 hours
 9
10Total: ~12.5 hours (1.5 working days)
11
12Results:
13- 93.7% test coverage
14- 0 staging issues
15- 0 clarification questions from reviewer about behavior
16- All ACs traced to tests
17- 12/13 spec items fully covered

The distribution is telling: spec-related work and implementation each took roughly 40% of the time. That front-loaded spec investment is exactly what bought the zero staging issues and zero behavioral review questions.


19.13 Lessons from the Case Study

Lesson 1: Time in the spec saves time in implementation — the 30-minute window discovery prevented a whole revision cycle.

Lesson 2: Plan Mode is a free architectural sanity check — it caught the EventPublisher interface need before coding started.

Lesson 3: Tests derived from the spec give confidence — the reviewer had zero “does this handle X?” questions.

Lesson 4: Spec drift is prevented from day one — exact-string assertions make error-code changes fail immediately in CI.

Lesson 5: AI is an accelerator, not a replacement for judgment — @andi made every architectural decision; the AI executed them.


19.14 What Would Happen Without SDD

It’s worth estimating the counterfactual: what if @andi had started coding immediately, with no spec? The rough breakdown below is typical of a code-first approach.

text
 1Without SDD estimate:
 2- Initial implementation: 3 hours
 3- PR #1: "implement cancel order"
 4- Review comments: cancel window? concurrent? error code? coverage only 45%
 5- PR #2 (revision): 2 more hours
 6- PR #3 (more fixes): 1 more hour
 7
 8Total: ~6 hours + more back-and-forth
 9Coverage: 45-60%
10Business decision (30 min): discovered in review, not upfront

The code-first path looks faster on paper (~6 hours) but produces lower coverage, more review rounds, and — critically — discovers business decisions during review instead of up front. SDD spends more hours, but many of them produce a spec that keeps paying dividends long after the PR merges.


19.15 Reproducing in Your Project

The same workflow transfers directly to your own codebase. The steps below are the minimum setup and loop to run your own SDD pilot.

text
 1Step 1: Setup
 2- Create/update CLAUDE.md with spec rules
 3- Create a spec template at specs/_templates/feature-spec.md
 4- Set up a PR template with a spec reference section
 5
 6Step 2: Pick a small pilot feature
 7
 8Step 3: Follow the workflow
 9Clarify → Spec → Plan → Tasks → Implement → Test → Compliance check → PR → Review → Merge
10
11Step 4: Retrospective after the pilot
12- What worked? What needs adjustment?
13- Update CLAUDE.md and templates

Start with a small, well-understood feature rather than your most complex one — the goal of the pilot is to prove the loop and tune it for your team, not to test SDD against a worst case.


19.16 Key SDD Workflow Metrics to Track

To know whether SDD is actually helping, track a handful of signals over time:

  • % of features that have a spec (target: 100% for new features)
  • Spec coverage — ACs/ECs with tests (target: ≥ 80%)
  • Time from spec approved to PR merged
  • Spec drift incidents per sprint
  • Review cycle count (lower means better spec quality)

These numbers turn “SDD feels good” into an argument you can make to stakeholders with data.


19.17 The Four Components Working Together

What made this case study work was not any single practice but four of them reinforcing each other:

  1. An approved spec before coding → no ambiguity during implementation
  2. Plan Mode → architectural thinking before the first line of code
  3. Tests that trace to the spec → confidence that every AC is covered
  4. A compliance check before the PR → drift caught before review

When these four operate together, each phase becomes easier and faster than it would be in isolation.


19.18 Tips & Gotchas from Direct Experience

💡 Tip 1: Start the spec with clarification questions, not assumptions — it saved one full revision cycle here.

💡 Tip 2: Plan Mode is a free architectural sanity check — it caught an interface dependency before coding.

💡 Tip 3: Self-check before the PR is faster than fixing after review — 20 minutes versus 1–2 hours for fix plus re-review.

💡 Tip 4: Acknowledged gaps beat hidden gaps — EC3 tracked in JIRA is far better than an undocumented EC3 buried in code.

⚠️ Gotcha 1: Spec approval is not a rubber stamp — a meaningful review caught the latency target.

⚠️ Gotcha 2: Claude’s context window fills up in long sessions — start a fresh session per large task.

⚠️ Gotcha 3: 1.5 days feels slow for a “simple” feature — but it produces higher-quality, better-documented code that survives production.


19.19 What’s Next for Cancel Order

The feature isn’t finished — it’s a foundation. The roadmap below shows how the deferred items each become their own spec-driven work item.

text
1Sprint 24: EC3 explicit timeout (JIRA-789), Idempotency key (JIRA-790)
2Sprint 25: Rate limiting (JIRA-791), Load test for NFR-P2 verification
3Sprint 26: Admin cancel (separate spec), Analytics dashboard

Each item will follow the exact same workflow you just watched — clarify, spec, plan, implement, verify — which is precisely what makes the process repeatable rather than heroic.


19.20 Summary

This case study shows that SDD is not a linear, perfect process — there are feedback loops, spec revisions, and mid-implementation decisions. What makes SDD effective is not the perfection of the process but the structure that provides confidence at every step.

Four key components working together: an approved spec before coding, Plan Mode for architectural thinking, tests that trace to the spec, and a compliance check before the PR.

SDD as an investment: 12.5 hours to implement, but the output includes a reusable spec for onboarding, tests that catch regressions, and documented decisions that stay useful months or years later.

AI as an accelerator: Claude Code saved significant time by generating the spec draft, plan, code, and tests — but @andi made the decisions at every step. That is the difference between SDD and vibe coding.

In the final article of this series, we look at what comes after SDD mastery: deeper tools, the next evolution, and a bridge to the broader ecosystem.

Related Articles

💬 Comments