mir-backend-go-ginlisted
Install: claude install-skill anantbhandarkar/make-it-right
# /mir-backend-go-gin · Make It Right (Gin)
Bottom tier of the chain: `mir-backend` (generic gates) → `mir-backend-go` (Go runtime model) → **this** (Gin library mechanics). Run the gates first; load the Go runtime tier for goroutine lifecycle, context propagation, and race discipline; reach for *this* at Gate 5 (design mechanics), Gate 6 (implementation), and Gate 7 review. **Runtime-level concerns (goroutine leaks, data races, context propagation, typed-nil, slice aliasing) live in `mir-backend-go` — not here.**
**Stack assumed:** `github.com/gin-gonic/gin` v1.9+. If the project uses `gin-contrib/*` middleware or GORM, note the interaction before applying these.
## The Gin footguns AI walks into most
### 1. `*gin.Context` is request-scoped — never retain it across the handler boundary
`*gin.Context` is reused from a sync pool after the handler returns. Passing a `*gin.Context` reference to a goroutine spawned inside the handler and then accessing it after the handler returns causes a data race on the pooled object — you get another request's data or a crash.
- **Call `c.Copy()` before passing `*gin.Context` to any goroutine.** The copy is safe to read from a different goroutine after the handler returns; it does not hold a reference to the pool slot.
```go
// WRONG: c is recycled after the handler returns; the goroutine reads stale/corrupt data
func handler(c *gin.Context) {
go func() {
sendEmail(c.Param("id"), c.GetHeader("X-Trace-Id"))
}(