package server import ( "database/sql" "net/http" "github.com/go-chi/chi/v5" chimiddleware "github.com/go-chi/chi/v5/middleware" "git.unsupervised.ca/walkies/internal/auth" "git.unsupervised.ca/walkies/internal/checkin" "git.unsupervised.ca/walkies/internal/notification" "git.unsupervised.ca/walkies/internal/schedule" "git.unsupervised.ca/walkies/internal/server/middleware" "git.unsupervised.ca/walkies/internal/timeoff" "git.unsupervised.ca/walkies/internal/volunteer" ) func New(db *sql.DB, jwtSecret string, staticDir string) http.Handler { authSvc := auth.NewService(db, jwtSecret) volunteerStore := volunteer.NewStore(db) volunteerHandler := volunteer.NewHandler(volunteerStore, authSvc) scheduleStore := schedule.NewStore(db) scheduleHandler := schedule.NewHandler(scheduleStore) timeoffStore := timeoff.NewStore(db) timeoffHandler := timeoff.NewHandler(timeoffStore) checkinStore := checkin.NewStore(db) checkinHandler := checkin.NewHandler(checkinStore) notificationStore := notification.NewStore(db) notificationHandler := notification.NewHandler(notificationStore) r := chi.NewRouter() r.Use(chimiddleware.Logger) r.Use(chimiddleware.Recoverer) r.Use(chimiddleware.RealIP) // API routes r.Route("/api/v1", func(r chi.Router) { // Public auth endpoints r.Post("/auth/register", volunteerHandler.Register) r.Post("/auth/login", volunteerHandler.Login) // Protected routes r.Group(func(r chi.Router) { r.Use(middleware.Authenticate(authSvc)) // Volunteers r.Get("/volunteers", volunteerHandler.List) r.Get("/volunteers/{id}", volunteerHandler.Get) r.With(middleware.RequireAdmin).Put("/volunteers/{id}", volunteerHandler.Update) // Schedules r.Get("/schedules", scheduleHandler.List) r.Post("/schedules", scheduleHandler.Create) r.With(middleware.RequireAdmin).Put("/schedules/{id}", scheduleHandler.Update) r.With(middleware.RequireAdmin).Delete("/schedules/{id}", scheduleHandler.Delete) // Time off r.Get("/timeoff", timeoffHandler.List) r.Post("/timeoff", timeoffHandler.Create) r.With(middleware.RequireAdmin).Put("/timeoff/{id}/review", timeoffHandler.Review) // Check-in / check-out r.Post("/checkin", checkinHandler.CheckIn) r.Post("/checkout", checkinHandler.CheckOut) r.Get("/checkin/history", checkinHandler.History) // Notifications r.Get("/notifications", notificationHandler.List) r.Put("/notifications/{id}/read", notificationHandler.MarkRead) }) }) // Serve static React app for all other routes r.Handle("/*", http.FileServer(http.Dir(staticDir))) return r }