refactor(repo): conform structure to AGENTS.md (web->frontend, internal/api->cmd/webui/{api,handlers}, docs/README+CHANGELOGs, module .gitignores, drop stray library/ and committed debug bins)
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"booklib/cmd/webui/handlers"
|
||||
"booklib/internal/config"
|
||||
"booklib/internal/redispkg"
|
||||
"booklib/internal/scanner"
|
||||
"booklib/internal/store"
|
||||
)
|
||||
|
||||
func NewRouter(cfg *config.Config, st *store.Store, rdb *redispkg.R, sc *scanner.Scanner) *gin.Engine {
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
h := handlers.New(cfg, st, rdb, sc)
|
||||
r := gin.New()
|
||||
if e := r.SetTrustedProxies(cfg.TrustedProxies); e != nil {
|
||||
panic(e)
|
||||
}
|
||||
r.Use(gin.Recovery())
|
||||
g := r.Group("/api")
|
||||
g.GET("/healthz", func(c *gin.Context) { c.String(http.StatusOK, "ok") })
|
||||
g.POST("/auth/login", h.Login)
|
||||
|
||||
p := g.Group("", h.AuthMw())
|
||||
p.GET("/auth/me", h.Me)
|
||||
|
||||
users := p.Group("/users", h.AdminOnly())
|
||||
users.GET("", h.ListUsers)
|
||||
users.POST("", h.CreateUser)
|
||||
users.DELETE("/:id", h.DeleteUser)
|
||||
|
||||
libs := p.Group("/libraries")
|
||||
libs.GET("", h.ListLibraries)
|
||||
libs.POST("", h.AdminOnly(), h.CreateLibrary)
|
||||
libs.POST("/:id/scan", h.AdminOnly(), h.ScanLibrary)
|
||||
libs.POST("/:id/upload", h.AdminOnly(), h.Upload)
|
||||
|
||||
p.GET("/books", h.ListBooks)
|
||||
p.GET("/books/:id", h.GetBook)
|
||||
p.DELETE("/books/:id", h.AdminOnly(), h.DeleteBook)
|
||||
p.GET("/books/:id/cover", h.ServeCover)
|
||||
p.GET("/books/:id/file", h.ServeFile)
|
||||
p.GET("/books/:id/pages", h.PagesCount)
|
||||
p.GET("/books/:id/pages/:n", h.Page)
|
||||
p.PUT("/books/:id/progress", h.PutProgress)
|
||||
p.GET("/progress", h.ListProgress)
|
||||
return r
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"booklib/internal/config"
|
||||
"booklib/internal/redispkg"
|
||||
)
|
||||
|
||||
func testCfg() *config.Config {
|
||||
return &config.Config{Addr: ":8080", JWTSecret: []byte("s3cret"), ScanInterval: time.Minute, UploadMaxMB: 200,
|
||||
TrustedProxies: []string{"172.16.0.0/12"}} // 与 prod 默认一致: 只有 compose 网段内代理才可信
|
||||
}
|
||||
|
||||
func TestHealthz(t *testing.T) {
|
||||
r := NewRouter(testCfg(), nil, redispkg.New(""), nil)
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/healthz", nil)
|
||||
w := httptest.NewRecorder()
|
||||
r.ServeHTTP(w, req)
|
||||
if w.Code != http.StatusOK {
|
||||
t.Fatalf("healthz = %d, want 200", w.Code)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user