Files
Dash/apps/backend/internal/api/api.go
T
Tomas Dvorak b60821350a feat: phase 0 foundation — monorepo scaffold, backend, frontend, CI, docker
Establishes the skeleton every later phase builds on: Go+Gin API with
zap logging, /api/healthz, SQLite+goose runner; Vite+React18+TS strict+
Tailwind v4 frontend with bento-mono theme tokens; openapi.yaml driving
a generated TS client; oxlint with vendored anti-slop rules; GitHub CI;
multi-stage Dockerfile -> 33.6MB distroless image; docker compose up
serves the blank board.


Generated with [Devin](https://devin.ai)

Authored By: TDvorak <[email protected]>
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-17 20:29:21 +02:00

43 lines
1.0 KiB
Go

// Package api wires the Gin router and /api handlers.
package api
import (
"database/sql"
"net/http"
"time"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
// NewRouter builds the HTTP handler: zap access log, recovery, /api routes.
func NewRouter(logger *zap.Logger, db *sql.DB) *gin.Engine {
r := gin.New()
r.Use(accessLog(logger), gin.Recovery())
v1 := r.Group("/api")
v1.GET("/healthz", func(c *gin.Context) {
if err := db.PingContext(c.Request.Context()); err != nil {
c.JSON(http.StatusServiceUnavailable, gin.H{"status": "db unreachable"})
return
}
c.JSON(http.StatusOK, gin.H{"status": "ok"})
})
return r
}
// accessLog is gin.Logger backed by zap: one structured line per request.
func accessLog(logger *zap.Logger) gin.HandlerFunc {
return func(c *gin.Context) {
start := time.Now()
c.Next()
logger.Info("request",
zap.String("method", c.Request.Method),
zap.String("path", c.Request.URL.Path),
zap.Int("status", c.Writer.Status()),
zap.Duration("latency", time.Since(start)),
)
}
}