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.
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.
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:
- AC5 needs to be explicit that stock restore is “atomic, in one DB transaction”
- EC1 needs to specify “use SELECT FOR UPDATE” to prevent the race condition
- NFR-P2 latency target is too loose — tighten it to p95 < 300ms
- 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.
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:
- Entity update (30 min)
- EventPublisher interface (20 min)
- Repository interface (20 min)
- Mock regeneration (10 min)
- DB migration (15 min)
- Repository implementation (90 min)
- UseCase implementation (60 min)
- UseCase tests (75 min)
- HTTP handler (45 min)
- Route registration (10 min)
- 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.
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.
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.
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:
- Warning: the
userIDextraction needs a comment documenting the middleware assumption - Praise: the
SELECT FOR UPDATEimplementation matches the ADR-003 pattern exactly - 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.
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 coveredThe 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.
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 upfrontThe 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.
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 templatesStart 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:
- An approved spec before coding → no ambiguity during implementation
- Plan Mode → architectural thinking before the first line of code
- Tests that trace to the spec → confidence that every AC is covered
- 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.
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 dashboardEach 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.