fix: golangci-lint v2 config and lint-clean production code
- Fix .golangci.yml for v2 format (linters-settings -> linters.settings) - All production code now passes golangci-lint with zero issues - Line length 88, funlen 80/50, cyclop 15, dupl 100 - Extract shared helpers in db (scanChannels, scanInt64s, scanMessages) - Split runMigrations into applyMigration/execMigration - Fix fanOut return signature (remove unused int64) - Add fanOutSilent helper to avoid dogsled - Rewrite CLI code for lint compliance (nlreturn, wsl_v5, noctx, etc) - Rename CLI api package to chatapi to avoid revive var-naming - Fix all noinlineerr, mnd, perfsprint, funcorder issues - Fix db tests: extract helpers, add t.Parallel, proper error checks - Broker tests already clean - Handler integration tests still have lint issues (next commit)
This commit is contained in:
@@ -16,7 +16,7 @@ import (
|
||||
|
||||
const routeTimeout = 60 * time.Second
|
||||
|
||||
// SetupRoutes configures the HTTP routes and middleware chain.
|
||||
// SetupRoutes configures the HTTP routes and middleware.
|
||||
func (s *Server) SetupRoutes() {
|
||||
s.router = chi.NewRouter()
|
||||
|
||||
@@ -39,13 +39,19 @@ func (s *Server) SetupRoutes() {
|
||||
}
|
||||
|
||||
// Health check
|
||||
s.router.Get("/.well-known/healthcheck.json", s.h.HandleHealthCheck())
|
||||
s.router.Get(
|
||||
"/.well-known/healthcheck.json",
|
||||
s.h.HandleHealthCheck(),
|
||||
)
|
||||
|
||||
// Protected metrics endpoint
|
||||
if viper.GetString("METRICS_USERNAME") != "" {
|
||||
s.router.Group(func(r chi.Router) {
|
||||
r.Use(s.mw.MetricsAuth())
|
||||
r.Get("/metrics", http.HandlerFunc(promhttp.Handler().ServeHTTP))
|
||||
r.Get("/metrics",
|
||||
http.HandlerFunc(
|
||||
promhttp.Handler().ServeHTTP,
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -53,55 +59,66 @@ func (s *Server) SetupRoutes() {
|
||||
s.router.Route("/api/v1", func(r chi.Router) {
|
||||
r.Get("/server", s.h.HandleServerInfo())
|
||||
r.Post("/session", s.h.HandleCreateSession())
|
||||
|
||||
// Unified state and message endpoints
|
||||
r.Get("/state", s.h.HandleState())
|
||||
r.Get("/messages", s.h.HandleGetMessages())
|
||||
r.Post("/messages", s.h.HandleSendCommand())
|
||||
r.Get("/history", s.h.HandleGetHistory())
|
||||
|
||||
// Channels
|
||||
r.Get("/channels", s.h.HandleListAllChannels())
|
||||
r.Get("/channels/{channel}/members", s.h.HandleChannelMembers())
|
||||
r.Get(
|
||||
"/channels/{channel}/members",
|
||||
s.h.HandleChannelMembers(),
|
||||
)
|
||||
})
|
||||
|
||||
// Serve embedded SPA
|
||||
s.setupSPA()
|
||||
}
|
||||
|
||||
func (s *Server) setupSPA() {
|
||||
distFS, err := fs.Sub(web.Dist, "dist")
|
||||
if err != nil {
|
||||
s.log.Error("failed to get web dist filesystem", "error", err)
|
||||
} else {
|
||||
fileServer := http.FileServer(http.FS(distFS))
|
||||
|
||||
s.router.Get("/*", func(w http.ResponseWriter, r *http.Request) {
|
||||
s.serveSPA(distFS, fileServer, w, r)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) serveSPA(
|
||||
distFS fs.FS,
|
||||
fileServer http.Handler,
|
||||
w http.ResponseWriter,
|
||||
r *http.Request,
|
||||
) {
|
||||
readFS, ok := distFS.(fs.ReadFileFS)
|
||||
if !ok {
|
||||
http.Error(w, "filesystem error", http.StatusInternalServerError)
|
||||
s.log.Error(
|
||||
"failed to get web dist filesystem",
|
||||
"error", err,
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Try to serve the file; fall back to index.html for SPA routing.
|
||||
f, err := readFS.ReadFile(r.URL.Path[1:])
|
||||
if err != nil || len(f) == 0 {
|
||||
indexHTML, _ := readFS.ReadFile("index.html")
|
||||
fileServer := http.FileServer(http.FS(distFS))
|
||||
|
||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, _ = w.Write(indexHTML)
|
||||
s.router.Get("/*", func(
|
||||
w http.ResponseWriter,
|
||||
r *http.Request,
|
||||
) {
|
||||
readFS, ok := distFS.(fs.ReadFileFS)
|
||||
if !ok {
|
||||
fileServer.ServeHTTP(w, r)
|
||||
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
fileServer.ServeHTTP(w, r)
|
||||
f, readErr := readFS.ReadFile(r.URL.Path[1:])
|
||||
if readErr != nil || len(f) == 0 {
|
||||
indexHTML, indexErr := readFS.ReadFile(
|
||||
"index.html",
|
||||
)
|
||||
if indexErr != nil {
|
||||
http.NotFound(w, r)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set(
|
||||
"Content-Type",
|
||||
"text/html; charset=utf-8",
|
||||
)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, _ = w.Write(indexHTML)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
fileServer.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user