Init
This commit is contained in:
83
backend/internal/api/router.go
Normal file
83
backend/internal/api/router.go
Normal file
@@ -0,0 +1,83 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-chi/chi/v5/middleware"
|
||||
"github.com/go-chi/cors"
|
||||
"simplefinancedash/backend/internal/auth"
|
||||
"simplefinancedash/backend/internal/db"
|
||||
)
|
||||
|
||||
func NewRouter(queries *db.Queries, sessionSecret string, frontendFS fs.FS) http.Handler {
|
||||
r := chi.NewRouter()
|
||||
|
||||
r.Use(middleware.Logger)
|
||||
r.Use(middleware.Recoverer)
|
||||
r.Use(middleware.Compress(5))
|
||||
r.Use(cors.Handler(cors.Options{
|
||||
AllowedOrigins: []string{"http://localhost:5173", "http://localhost:8080"},
|
||||
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
|
||||
AllowedHeaders: []string{"Content-Type"},
|
||||
AllowCredentials: true,
|
||||
}))
|
||||
|
||||
h := NewHandlers(queries, sessionSecret)
|
||||
|
||||
// Auth routes (no auth required)
|
||||
r.Route("/api/auth", func(r chi.Router) {
|
||||
r.Post("/register", h.Register)
|
||||
r.Post("/login", h.Login)
|
||||
r.Post("/logout", h.Logout)
|
||||
r.Get("/me", h.Me)
|
||||
r.Get("/oidc", h.OIDCStart)
|
||||
r.Get("/oidc/callback", h.OIDCCallback)
|
||||
})
|
||||
|
||||
// Protected routes
|
||||
r.Group(func(r chi.Router) {
|
||||
r.Use(auth.Middleware(sessionSecret))
|
||||
|
||||
r.Route("/api/categories", func(r chi.Router) {
|
||||
r.Get("/", h.ListCategories)
|
||||
r.Post("/", h.CreateCategory)
|
||||
r.Put("/{id}", h.UpdateCategory)
|
||||
r.Delete("/{id}", h.DeleteCategory)
|
||||
})
|
||||
|
||||
r.Route("/api/budgets", func(r chi.Router) {
|
||||
r.Get("/", h.ListBudgets)
|
||||
r.Post("/", h.CreateBudget)
|
||||
r.Get("/{id}", h.GetBudget)
|
||||
r.Put("/{id}", h.UpdateBudget)
|
||||
r.Delete("/{id}", h.DeleteBudget)
|
||||
r.Post("/{id}/copy-from/{srcId}", h.CopyBudgetItems)
|
||||
|
||||
r.Post("/{id}/items", h.CreateBudgetItem)
|
||||
r.Put("/{id}/items/{itemId}", h.UpdateBudgetItem)
|
||||
r.Delete("/{id}/items/{itemId}", h.DeleteBudgetItem)
|
||||
})
|
||||
|
||||
r.Get("/api/settings", h.GetSettings)
|
||||
r.Put("/api/settings", h.UpdateSettings)
|
||||
})
|
||||
|
||||
// Serve SPA for all non-API routes
|
||||
spaHandler := http.FileServer(http.FS(frontendFS))
|
||||
r.NotFound(func(w http.ResponseWriter, r *http.Request) {
|
||||
// Try to serve the file directly first
|
||||
f, err := frontendFS.Open(r.URL.Path[1:]) // strip leading /
|
||||
if err == nil {
|
||||
f.Close()
|
||||
spaHandler.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
// Fall back to index.html for SPA routing
|
||||
r.URL.Path = "/"
|
||||
spaHandler.ServeHTTP(w, r)
|
||||
})
|
||||
|
||||
return r
|
||||
}
|
||||
Reference in New Issue
Block a user