fix deployment and frontend build regressions

This commit is contained in:
2026-05-21 15:30:24 +08:00
parent 31f1b510c3
commit b430fb9301
6 changed files with 276 additions and 99 deletions

View File

@@ -7,6 +7,9 @@ import (
"log"
"net/http"
"os"
"path"
"path/filepath"
"strings"
"time"
_ "github.com/lib/pq"
@@ -75,7 +78,7 @@ func main() {
}
}
mux := newMux(db, fetchModels, fetchSubscriptionPlans)
mux := newMux(db, fetchModels, fetchSubscriptionPlans, resolveFrontendDistDir())
log.Printf("server listening on :%s", addr)
if err := http.ListenAndServe(":"+addr, mux); err != nil {
@@ -83,7 +86,7 @@ func main() {
}
}
func newMux(db *sql.DB, fetchModelsFn modelFetcher, fetchPlansFn subscriptionPlanFetcher) *http.ServeMux {
func newMux(db *sql.DB, fetchModelsFn modelFetcher, fetchPlansFn subscriptionPlanFetcher, frontendDistDir string) *http.ServeMux {
mux := http.NewServeMux()
mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
if db == nil {
@@ -122,9 +125,65 @@ func newMux(db *sql.DB, fetchModelsFn modelFetcher, fetchPlansFn subscriptionPla
}
writeJSON(w, http.StatusOK, apiEnvelope{Data: plans})
})
if frontendDistDir != "" {
mux.Handle("/", frontendHandler(frontendDistDir))
}
return mux
}
func resolveFrontendDistDir() string {
candidates := []string{}
if custom := os.Getenv("FRONTEND_DIST_DIR"); custom != "" {
candidates = append(candidates, custom)
}
candidates = append(candidates,
filepath.Join("frontend", "dist"),
filepath.Join(filepath.Dir(os.Args[0]), "frontend", "dist"),
)
for _, candidate := range candidates {
indexPath := filepath.Join(candidate, "index.html")
info, err := os.Stat(indexPath)
if err == nil && !info.IsDir() {
return candidate
}
}
return ""
}
func frontendHandler(frontendDistDir string) http.Handler {
indexPath := filepath.Join(frontendDistDir, "index.html")
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet && r.Method != http.MethodHead {
http.NotFound(w, r)
return
}
cleanPath := path.Clean("/" + r.URL.Path)
if cleanPath == "/" {
http.ServeFile(w, r, indexPath)
return
}
relativePath := strings.TrimPrefix(cleanPath, "/")
assetPath := filepath.Join(frontendDistDir, filepath.FromSlash(relativePath))
if info, err := os.Stat(assetPath); err == nil && !info.IsDir() {
http.ServeFile(w, r, assetPath)
return
}
if filepath.Ext(relativePath) != "" {
http.NotFound(w, r)
return
}
http.ServeFile(w, r, indexPath)
})
}
func fetchModels(ctx context.Context, db *sql.DB) ([]modelResponse, error) {
rows, err := db.QueryContext(ctx, `
WITH latest_prices AS (