fix: resolve all linting and formatting issues

- Fix error return value checks (errcheck)
- Fix unused parameters by using underscore prefix
- Add missing package comments to all packages
- Fix context key type issue in middleware (use typed contextKey)
- Replace deprecated trace.NewNoopTracerProvider with noop.NewTracerProvider
- Fix embedded field selector in database client
- Remove trailing whitespace
- Remove revive linter (as requested) to avoid stuttering warnings for public API interfaces

All linting and formatting checks now pass.
This commit is contained in:
2025-11-05 20:48:59 +01:00
parent 926f3f927e
commit 52d48590ae
21 changed files with 57 additions and 68 deletions

View File

@@ -13,21 +13,11 @@ linters:
- errcheck
- govet
- staticcheck
- revive
- gosec
disable:
- gocritic # Can be enabled later for stricter checks
linters-settings:
revive:
rules:
- name: exported
severity: warning
arguments:
- checkPrivateReceivers
# Disable stuttering check - interface names like ConfigProvider are acceptable
- name: package-comments
severity: warning
gosec:
severity: medium
errcheck:
@@ -43,10 +33,6 @@ issues:
linters:
- errcheck
- gosec
# ConfigProvider stuttering is acceptable - it's a common pattern for interfaces
- path: pkg/config/config\.go
linters:
- revive
output:
print-issued-lines: true

View File

@@ -184,6 +184,7 @@ When working on this project, follow this workflow:
- Meet the acceptance criteria
- Use the implementation notes as guidance
- Follow the patterns established in `playbook.md`
- Implement tests
### 6. Verify Alignment
- Ensure code follows Clean/Hexagonal Architecture principles
@@ -196,6 +197,8 @@ When working on this project, follow this workflow:
- **ALWAYS commit** after successful implementation
- Ensure the code builds (`go build`)
- Ensure all tests pass (`go test`)
- Ensure there are no linter issues (`make lint`)
- Ensure there are no fmt issues (`make fmt-check`)
- Verify all acceptance criteria are met
- Write a clear, descriptive commit message
@@ -301,6 +304,7 @@ If you make architectural decisions or significant changes:
2. Update architecture documents if structure changes
3. Update stories if implementation details change
4. Keep documentation in sync with code
5. Do not use any emojis
---

View File

@@ -21,7 +21,7 @@ func main() {
fx.Invoke(di.RegisterLifecycleHooks),
// Force HTTP server to be created (which triggers all dependencies)
// This ensures database, health, metrics, etc. are all created
fx.Invoke(func(srv *server.Server, dbClient *database.Client) {
fx.Invoke(func(_ *server.Server, _ *database.Client) {
// Both server and database are created, hooks are registered
// This ensures all providers execute
}),

View File

@@ -1,3 +1,4 @@
// Package ent provides code generation for Ent schema definitions.
package ent
//go:generate go run -mod=mod entgo.io/ent/cmd/ent generate ./schema

View File

@@ -1,3 +1,4 @@
// Package schema defines the Ent schema for audit log entities.
package schema
import "entgo.io/ent"

View File

@@ -19,6 +19,7 @@ import (
"git.dcentral.systems/toolz/goplt/pkg/errorbus"
"git.dcentral.systems/toolz/goplt/pkg/logger"
"go.opentelemetry.io/otel/trace"
"go.opentelemetry.io/otel/trace/noop"
"go.uber.org/fx"
)
@@ -130,7 +131,7 @@ func ProvideDatabase() fx.Option {
log.Info("Database migrations completed successfully")
return nil
},
OnStop: func(ctx context.Context) error {
OnStop: func(_ context.Context) error {
return dbClient.Close()
},
})
@@ -147,7 +148,7 @@ func ProvideErrorBus() fx.Option {
// Register lifecycle hook to close the bus on shutdown
lc.Append(fx.Hook{
OnStop: func(ctx context.Context) error {
OnStop: func(_ context.Context) error {
return bus.Close()
},
})
@@ -181,7 +182,7 @@ func ProvideTracer() fx.Option {
enabled := cfg.GetBool("tracing.enabled")
if !enabled {
// Return no-op tracer
return trace.NewNoopTracerProvider(), nil
return noop.NewTracerProvider(), nil
}
serviceName := cfg.GetString("tracing.service_name")
@@ -248,8 +249,7 @@ func ProvideHTTPServer() fx.Option {
// Register lifecycle hooks
lc.Append(fx.Hook{
OnStart: func(ctx context.Context) error {
OnStart: func(_ context.Context) error {
// Get server address from config
port := cfg.GetInt("server.port")
if port == 0 {
@@ -300,7 +300,7 @@ func ProvideHTTPServer() fx.Option {
)
// Continue anyway - server might still be starting
} else {
resp.Body.Close()
_ = resp.Body.Close()
}
log.Info("HTTP server started successfully",

View File

@@ -1,3 +1,4 @@
// Package schema defines the Ent schema for domain entities.
package schema
import (
@@ -46,4 +47,3 @@ func (AuditLog) Indexes() []ent.Index {
index.Fields("action"),
}
}

View File

@@ -30,4 +30,3 @@ func (Permission) Edges() []ent.Edge {
edge.To("role_permissions", RolePermission.Type),
}
}

View File

@@ -37,4 +37,3 @@ func (Role) Edges() []ent.Edge {
edge.To("user_roles", UserRole.Type),
}
}

View File

@@ -32,4 +32,3 @@ func (RolePermission) Edges() []ent.Edge {
Field("permission_id"),
}
}

View File

@@ -41,4 +41,3 @@ func (User) Edges() []ent.Edge {
edge.To("user_roles", UserRole.Type),
}
}

View File

@@ -32,4 +32,3 @@ func (UserRole) Edges() []ent.Edge {
Field("role_id"),
}
}

View File

@@ -1,3 +1,4 @@
// Package errorbus provides a channel-based error bus implementation.
package errorbus
import (
@@ -11,17 +12,17 @@ import (
// ChannelBus implements a channel-based error bus.
type ChannelBus struct {
errors chan errorWithContext
logger logger.Logger
done chan struct{}
wg sync.WaitGroup
once sync.Once
errors chan errorWithContext
logger logger.Logger
done chan struct{}
wg sync.WaitGroup
once sync.Once
}
type errorWithContext struct {
err error
ctx context.Context
stack []byte
err error
ctx context.Context
stack []byte
}
// NewChannelBus creates a new channel-based error bus.
@@ -162,4 +163,3 @@ func (b *ChannelBus) Close() error {
// Ensure ChannelBus implements ErrorPublisher
var _ errorbus.ErrorPublisher = (*ChannelBus)(nil)

View File

@@ -1,3 +1,4 @@
// Package health provides health check implementations for various components.
package health
import (
@@ -23,4 +24,3 @@ func NewDatabaseChecker(client *database.Client) health.HealthChecker {
func (d *DatabaseChecker) Check(ctx context.Context) error {
return d.client.Ping(ctx)
}

View File

@@ -60,7 +60,7 @@ func (r *Registry) Check(ctx context.Context) health.HealthStatus {
}
// LivenessCheck performs a basic liveness check (no dependencies).
func (r *Registry) LivenessCheck(ctx context.Context) health.HealthStatus {
func (r *Registry) LivenessCheck(_ context.Context) health.HealthStatus {
// Liveness is always healthy if the service is running
return health.HealthStatus{
Status: health.StatusHealthy,
@@ -71,4 +71,3 @@ func (r *Registry) LivenessCheck(ctx context.Context) health.HealthStatus {
func (r *Registry) ReadinessCheck(ctx context.Context) health.HealthStatus {
return r.Check(ctx)
}

View File

@@ -1,3 +1,4 @@
// Package database provides database client and connection management.
package database
import (
@@ -20,11 +21,11 @@ type Client struct {
// Config holds database configuration.
type Config struct {
DSN string
MaxConnections int
MaxIdleConns int
ConnMaxLifetime time.Duration
ConnMaxIdleTime time.Duration
DSN string
MaxConnections int
MaxIdleConns int
ConnMaxLifetime time.Duration
ConnMaxIdleTime time.Duration
}
// NewClient creates a new Ent client with connection pooling.
@@ -46,7 +47,7 @@ func NewClient(cfg Config) (*Client, error) {
defer cancel()
if err := db.PingContext(ctx); err != nil {
db.Close()
_ = db.Close()
return nil, fmt.Errorf("failed to ping database: %w", err)
}
@@ -72,7 +73,7 @@ func (c *Client) Close() error {
// Migrate runs database migrations.
func (c *Client) Migrate(ctx context.Context) error {
return c.Client.Schema.Create(ctx)
return c.Schema.Create(ctx)
}
// Ping checks database connectivity.
@@ -84,4 +85,3 @@ func (c *Client) Ping(ctx context.Context) error {
func (c *Client) DB() *sql.DB {
return c.db
}

View File

@@ -1,3 +1,4 @@
// Package metrics provides Prometheus metrics collection and instrumentation.
package metrics
import (
@@ -12,9 +13,9 @@ import (
// Metrics holds all Prometheus metrics.
type Metrics struct {
httpRequestDuration *prometheus.HistogramVec
httpRequestTotal *prometheus.CounterVec
httpErrorsTotal *prometheus.CounterVec
registry *prometheus.Registry
httpRequestTotal *prometheus.CounterVec
httpErrorsTotal *prometheus.CounterVec
registry *prometheus.Registry
}
// NewMetrics creates a new metrics registry with all metrics.
@@ -94,4 +95,3 @@ func (m *Metrics) Handler() http.Handler {
func (m *Metrics) Registry() *prometheus.Registry {
return m.registry
}

View File

@@ -1,3 +1,4 @@
// Package observability provides OpenTelemetry tracing setup and configuration.
package observability
import (
@@ -13,22 +14,23 @@ import (
sdktrace "go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.26.0"
"go.opentelemetry.io/otel/trace"
"go.opentelemetry.io/otel/trace/noop"
)
// Config holds OpenTelemetry configuration.
type Config struct {
Enabled bool
ServiceName string
Enabled bool
ServiceName string
ServiceVersion string
Environment string
OTLPEndpoint string
Environment string
OTLPEndpoint string
}
// InitTracer initializes OpenTelemetry tracing.
func InitTracer(ctx context.Context, cfg Config) (trace.TracerProvider, error) {
if !cfg.Enabled {
// Return a no-op tracer provider
return trace.NewNoopTracerProvider(), nil
return noop.NewTracerProvider(), nil
}
// Create resource with service information
@@ -91,4 +93,3 @@ func ShutdownTracer(ctx context.Context, tp trace.TracerProvider) error {
}
return nil
}

View File

@@ -1,3 +1,4 @@
// Package server provides HTTP middleware functions for request processing.
package server
import (
@@ -6,15 +7,17 @@ import (
"runtime"
"time"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"git.dcentral.systems/toolz/goplt/pkg/errorbus"
"git.dcentral.systems/toolz/goplt/pkg/logger"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
)
type contextKey string
const (
requestIDKey = "request_id"
userIDKey = "user_id"
requestIDKey contextKey = "request_id"
userIDKey contextKey = "user_id"
)
// RequestIDMiddleware generates a unique request ID for each request.
@@ -25,7 +28,7 @@ func RequestIDMiddleware() gin.HandlerFunc {
requestID = uuid.New().String()
}
c.Set(requestIDKey, requestID)
c.Set(string(requestIDKey), requestID)
c.Header("X-Request-ID", requestID)
c.Next()
}
@@ -45,7 +48,7 @@ func LoggingMiddleware(log logger.Logger) gin.HandlerFunc {
duration := time.Since(start)
// Get request ID from context
requestID, _ := c.Get(requestIDKey)
requestID, _ := c.Get(string(requestIDKey))
requestIDStr := ""
if id, ok := requestID.(string); ok {
requestIDStr = id
@@ -74,8 +77,8 @@ func PanicRecoveryMiddleware(errorBus errorbus.ErrorPublisher) gin.HandlerFunc {
stack = stack[:n]
// Get request ID from context
requestID, _ := c.Get(requestIDKey)
ctx := context.WithValue(context.Background(), "request_id", requestID)
requestID, _ := c.Get(string(requestIDKey))
ctx := context.WithValue(context.Background(), requestIDKey, requestID)
// Create error
var panicErr error
@@ -138,4 +141,3 @@ func TimeoutMiddleware(timeout time.Duration) gin.HandlerFunc {
c.Next()
}
}

View File

@@ -1,3 +1,4 @@
// Package errorbus provides interfaces for error publishing and handling.
package errorbus
import (
@@ -18,4 +19,3 @@ type ErrorContext struct {
Component string
Metadata map[string]interface{}
}

View File

@@ -1,3 +1,4 @@
// Package health provides interfaces and types for health checking.
package health
import "context"
@@ -31,4 +32,3 @@ type HealthStatus struct {
Status Status `json:"status"`
Components []ComponentStatus `json:"components,omitempty"`
}