FloorVisualizer/internal/api/router.go

88 lines
3.5 KiB
Go
Raw Normal View History

package api
import (
"database/sql"
"encoding/json"
"net/http"
"floorvisualizer/internal/handler"
"floorvisualizer/internal/middleware"
"floorvisualizer/internal/model"
"floorvisualizer/internal/openrouter"
"floorvisualizer/internal/service"
)
// RegisterRoutes sets up all HTTP routes with injected dependencies.
func RegisterRoutes(mux *http.ServeMux, client *openrouter.Client, db *sql.DB, authSvc *service.AuthService) {
auth := middleware.RequireAuth(authSvc)
// Pre-build handlers — dependencies injected once
var (
register = handler.Register(authSvc, db)
login = handler.Login(authSvc, db)
me = auth(handler.Me(db))
uploadAvatar = auth(handler.UploadAvatar(db))
favorites = auth(handler.Favorites(db))
favoritesSub = auth(handler.Favorites(db))
projects = auth(handler.Projects(db))
projectsSub = auth(handler.Projects(db))
frequentBrands = auth(handler.FrequentBrands(db))
products = handler.Products(db)
productsSub = handler.Products(db)
productOpts = handler.ProductOptions(db)
filterOpts = handler.FilterOptions(db)
recommend = handler.Recommend(db)
floorGenerate = handler.FloorGenerate(client, db)
floorOptions = handler.FloorOptions(db)
articleRecommend = handler.ArticleRecommend(db)
articles = handler.Articles(db)
articlesSub = handler.Articles(db)
)
// Route mapping
mux.HandleFunc("/auth/register", register)
mux.HandleFunc("/auth/login", login)
mux.HandleFunc("/user/me", me)
mux.HandleFunc("/user/avatar", uploadAvatar)
mux.HandleFunc("/user/favorites", favorites)
mux.HandleFunc("/user/favorites/", favoritesSub)
mux.HandleFunc("/user/projects", projects)
mux.HandleFunc("/user/projects/", projectsSub)
mux.HandleFunc("/user/frequent-brands", frequentBrands)
mux.HandleFunc("/healthz", handler.Healthz)
mux.HandleFunc("/upload", handler.Upload)
mux.HandleFunc("/products", products)
mux.HandleFunc("/products/", productsSub)
mux.HandleFunc("/product-options", productOpts)
mux.HandleFunc("/filter-options", filterOpts)
mux.HandleFunc("/recommend/api", recommend)
mux.HandleFunc("/calculator/calc", handler.Calc)
mux.HandleFunc("/floor/generate", floorGenerate)
mux.HandleFunc("/floor/status", handler.FloorStatus)
mux.HandleFunc("/floor/options", floorOptions)
mux.HandleFunc("/articles/recommend", articleRecommend)
mux.HandleFunc("/articles", articles)
mux.HandleFunc("/articles/", articlesSub)
// Static files
mux.Handle("/outputs/", http.StripPrefix("/outputs/", http.FileServer(http.Dir("./outputs"))))
mux.Handle("/uploads/", http.StripPrefix("/uploads/", http.FileServer(http.Dir("./uploads"))))
mux.Handle("/knowledge_images/", http.StripPrefix("/knowledge_images/", http.FileServer(http.Dir("./knowledge_images"))))
mux.Handle("/images/knowledge/", http.StripPrefix("/images/knowledge/", http.FileServer(http.Dir("./knowledge_images"))))
}
// ── Response helpers ──────────────────────────────────────
// JSON writes a success response with the API envelope.
func JSON(w http.ResponseWriter, status int, v any) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(status)
json.NewEncoder(w).Encode(model.ApiResponse{Code: status, Data: v})
}
func Error(w http.ResponseWriter, status int, msg string) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(status)
json.NewEncoder(w).Encode(model.ApiError{Code: status, Error: msg})
}