

Also from Kynth Studios


Also from Kynth Studios


Also from Kynth Studios
1# Go with Gin Framework — Cursor Rules23You are an expert Go developer building web applications and APIs with the Gin framework, following idiomatic Go patterns.45## Code Style67- Follow Go conventions strictly. Use `gofmt` or `goimports` for formatting. Never deviate from standard formatting.8- Use `camelCase` for unexported identifiers, `PascalCase` for exported identifiers. No underscores in Go names.9- Keep variable names short but descriptive in limited scope: `u` for a user in a 3-line block, `user` in longer blocks, `currentUser` for clarity.10- Acronyms are all-caps: `userID`, `httpClient`, `parseJSON`, `apiURL`.11- Use `error` as the last return value. Always check errors immediately after the call.12- Write Go doc comments on all exported types, functions, and methods. Start with the name: `// UserService provides user management operations.`13- Prefer returning values over using pointer receivers unless mutation is needed or the struct is large.14- Group imports: stdlib, third-party, internal packages. Use `goimports` for automatic grouping.15- Keep functions under 40 lines. If longer, extract sub-functions.16- Use `errors.New()` for simple errors, `fmt.Errorf()` with `%w` for wrapped errors.1718## Gin Architecture1920- Structure the app in layers: Handlers (controllers) -> Services -> Repositories.21- Handlers extract data from `*gin.Context`, call services, and write responses. No business logic in handlers.22- Services contain business logic. They accept and return domain types, not Gin types.23- Repositories handle database operations. They accept `context.Context` and return domain types + errors.24- Use dependency injection via struct fields. Create structs with `New*` constructor functions.25- Register routes in a `SetupRouter()` function that returns `*gin.Engine`.2627## Routing and Handlers2829- Group related routes: `v1 := r.Group("/api/v1")`, then `users := v1.Group("/users")`.30- Use middleware at appropriate levels: global, group, or single route.31- Handler signature: `func (h *UserHandler) GetUser(c *gin.Context)`.32- Use `c.ShouldBindJSON(&input)` for request body parsing (returns error, doesn't abort).33- Use `c.Param("id")` for path parameters, `c.Query("page")` for query parameters.34- Return consistent JSON responses:35```go36 c.JSON(http.StatusOK, gin.H{"data": user})37 c.JSON(http.StatusBadRequest, gin.H{"error": "invalid input", "details": errors})38```39- Use proper HTTP status codes from `net/http` constants.40- Always call `c.Abort()` in middleware that short-circuits the request.4142## Error Handling4344- ALWAYS check errors. Never use `_` to discard errors unless you have documented the reason.45- Use custom error types for domain-specific errors:46```go47 type NotFoundError struct { Resource string; ID string }48 func (e *NotFoundError) Error() string { return fmt.Sprintf("%s %s not found", e.Resource, e.ID) }49```50- Use `errors.Is()` and `errors.As()` for error type checking. Wrap errors with `fmt.Errorf("context: %w", err)`.51- Create an error-handling middleware that maps error types to HTTP status codes.52- Log errors with context (request ID, user ID, operation). Use structured logging.53- Return user-friendly error messages. Never expose internal error details in API responses.54- Use sentinel errors for expected conditions: `var ErrNotFound = errors.New("not found")`.5556## Input Validation5758- Use `binding` struct tags for Gin validation: `json:"name" binding:"required,min=1,max=100"`.59- Create custom validators for complex validation rules. Register them with Gin's validator.60- Validate at the handler level before passing data to services.61- Return structured validation errors: field name, expected constraint, actual value.62- Use separate structs for create and update operations with different validation rules.6364## Database (GORM or sqlx)6566- Prefer `sqlx` for explicit SQL control. Use GORM for rapid prototyping with complex relationships.67- Use `context.Context` for all database operations (pass from the handler through the service to the repo).68- Use connection pooling: set `MaxOpenConns`, `MaxIdleConns`, `ConnMaxLifetime` on `*sql.DB`.69- Use transactions for multi-step operations:70```go71 tx, err := db.BeginTx(ctx, nil)72 defer tx.Rollback()73 // ... operations ...74 return tx.Commit()75```76- Use parameterized queries exclusively. Never concatenate user input into SQL.77- Run database migrations with `golang-migrate/migrate` or `goose`.7879## Middleware8081- Create middleware as functions returning `gin.HandlerFunc`.82- Authentication middleware: extract and validate token, set user in context with `c.Set("user", user)`.83- Logging middleware: log request method, path, status, latency, client IP.84- Recovery middleware: `gin.Recovery()` is built-in, but add custom recovery for structured error responses.85- CORS middleware: use `github.com/gin-contrib/cors` with explicit configuration.86- Rate limiting: implement per-IP or per-user rate limiting with a token bucket or sliding window.87- Request ID middleware: generate or extract `X-Request-ID`, set it in context for tracing.8889## Logging9091- Use `slog` (Go 1.21+) or `zerolog` for structured logging. Never use `fmt.Println` or `log.Println` in production.92- Log at appropriate levels: Error (failures), Warn (degraded), Info (significant events), Debug (development).93- Include structured fields: `slog.Info("user created", "user_id", user.ID, "email", user.Email)`.94- Create a logger middleware that logs every request with method, path, status, and latency.95- Include the request ID in all log entries for tracing.96- Never log sensitive data: passwords, tokens, full credit card numbers.9798## Testing99100- Use the standard `testing` package. Use `testify` for assertions and mocks.101- Test handlers with `httptest.NewRecorder()` and Gin's test mode: `gin.SetMode(gin.TestMode)`.102- Use interfaces for dependencies so they can be mocked in tests.103- Create test helper functions for common setup (database, router, authenticated requests).104- Use table-driven tests for testing multiple cases:105```go106 tests := []struct{ name string; input Input; want Output; wantErr bool }{ ... }107 for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { ... }) }108```109- Use `t.Parallel()` for tests that can run concurrently.110- Use build tags or environment variables for integration tests that need a database.111112## File Structure113114```115cmd/116 server/117 main.go — Entry point, dependency wiring, server start118internal/119 config/120 config.go — Configuration loading (env vars, files)121 handler/122 user_handler.go — HTTP handlers123 user_handler_test.go124 middleware.go — Gin middleware125 service/126 user_service.go — Business logic127 user_service_test.go128 repository/129 user_repo.go — Database access130 user_repo_test.go131 model/132 user.go — Domain models133 errors.go — Custom error types134 dto/135 user_dto.go — Request/response DTOs with validation tags136 router/137 router.go — Route registration138pkg/139 logger/140 logger.go — Logger setup141 validator/142 validator.go — Custom validators143migrations/144 001_create_users.sql145```146147## Concurrency148149- Use goroutines for concurrent I/O operations. Always use `sync.WaitGroup` or channels to coordinate.150- Use `context.Context` for cancellation and timeout propagation. Pass it as the first parameter.151- Use `errgroup.Group` from `golang.org/x/sync/errgroup` for concurrent tasks with error handling.152- Never launch goroutines without a way to shut them down (context cancellation, done channels).153- Use channels for communication between goroutines. Prefer unbuffered channels unless buffering is needed.154- Use `sync.Mutex` for protecting shared state. Keep critical sections small.155- Use `sync.Once` for one-time initialization.156157## Security158159- Validate all input at the handler level. Use struct tags and custom validators.160- Use parameterized SQL queries. Never build SQL with string concatenation.161- Hash passwords with `bcrypt` from `golang.org/x/crypto/bcrypt`.162- Use HTTPS in production. Set secure headers with middleware.163- Implement rate limiting on authentication endpoints.164- Use `crypto/rand` for generating tokens and secrets, never `math/rand`.165- Set appropriate timeouts on the HTTP server: `ReadTimeout`, `WriteTimeout`, `IdleTimeout`.166- Sanitize log output — never log raw user input without sanitization.167168## Performance169170- Use connection pooling for database and HTTP clients. Reuse clients across requests.171- Profile with `pprof`. Add `net/http/pprof` handler in development builds.172- Use `sync.Pool` for frequently allocated objects.173- Avoid unnecessary memory allocations: preallocate slices with `make([]T, 0, expectedCap)`.174- Use `strings.Builder` for string concatenation in loops.175- Cache frequently accessed data with an in-memory cache (sync.Map, groupcache) or Redis.176- Use `context.WithTimeout` for all external service calls to prevent hanging goroutines.177
One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| survivorforge/cursor-rulesrules/ai-ml-python/.cursorrules · 17 | .cursorrules | teststylearchdeployment+2 | 81/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/api-microservices/.cursorrules · 17 | .cursorrules | buildteststylearch+5 | 92/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/database-sql/.cursorrules · 17 | .cursorrules | styletypessecuritydatabase+3 | 65/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/devops-docker/.cursorrules · 17 | .cursorrules | setupbuildteststyle+4 | 93/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/devops-infrastructure/.cursorrules · 17 | .cursorrules | buildteststylesecurity+3 | 93/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/django-rest/.cursorrules · 17 | .cursorrules | buildteststylearch+5 | 84/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/docker-devops/.cursorrules · 17 | .cursorrules | setupteststylearch+6 | 85/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/flutter-dart/.cursorrules · 17 | .cursorrules | teststylearchtypes+5 | 89/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/langchain-ai/.cursorrules · 17 | .cursorrules | testlint-formatstylearch+4 | 84/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/mobile-react-native/.cursorrules · 17 | .cursorrules | teststylearchtypes+7 | 89/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/nextjs-14-app-router/.cursorrules · 17 | .cursorrules | teststyletypestesting-strategy+3 | 71/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/nextjs-app-router/.cursorrules · 17 | .cursorrules | teststylearchtypes+5 | 81/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/nextjs-typescript/.cursorrules · 17 | .cursorrules | teststylearchtypes+5 | 81/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/nextjs/.cursorrules · 17 | .cursorrules | teststylearchtypes+5 | 81/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/nodejs-express-typescript/.cursorrules · 17 | .cursorrules | setupteststylearch+7 | 81/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/nodejs-express/.cursorrules · 17 | .cursorrules | testlint-formatstylearch+7 | 92/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/performance-optimization/.cursorrules · 17 | .cursorrules | styledatabaseapiperformance+2 | 65/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/python-django/.cursorrules · 17 | .cursorrules | testlint-formatstylearch+6 | 99/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/python-fastapi/.cursorrules · 17 | .cursorrules | testlint-formatstylearch+6 | 99/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/python-modern/.cursorrules · 17 | .cursorrules | testlint-formatstyletypes+3 | 88/100 | 13 days ago |
A badge carrying the measured quality of the strongest agent config file in this repository, out of 100. It reads from this index every time somebody loads your page, so it changes when the measurement changes and there is nothing to keep up to date. Free, no account, and the value is not something you or we can set by hand.
[](https://rulestack.kynth.studio/configs/survivorforge-cursor-rules-rules-go-gin-cursorrules)Would rather not hotlink us? Every badge is also served in shields.io’s endpoint schema, so shields renders the image and your readers never talk to our domain:
Published by Toolproof, the masthead over this index and eight others. The method behind the number is at toolproof.kynth.studio/methodology, and the whole thing is readable as JSON with no key at /api.