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) questionnaireRec = handler.QuestionnaireRecommend(db) questionnaireOpt = handler.QuestionnaireOptions(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("/questionnaire", Questionnaire) mux.HandleFunc("/questionnaire/options", questionnaireOpt) mux.HandleFunc("/questionnaire/recommend", questionnaireRec) 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) mux.HandleFunc("/", Index) // 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}) }