| 1 | // SPDX-License-Identifier: AGPL-3.0-or-later |
| 2 | |
| 3 | // Package handlers registers HTTP handlers on the web server's mux. |
| 4 | // |
| 5 | // S00 ships only the hello page, static asset server, and health endpoints. |
| 6 | // Each future sprint adds its own routes via this package. |
| 7 | package handlers |
| 8 | |
| 9 | import ( |
| 10 | "fmt" |
| 11 | "io/fs" |
| 12 | "log/slog" |
| 13 | "net/http" |
| 14 | |
| 15 | "github.com/tenseleyFlow/shithub/internal/web/render" |
| 16 | ) |
| 17 | |
| 18 | // Deps holds the dependencies the handlers need. The web package owns the |
| 19 | // embedded filesystems and constructs Deps; this package stays decoupled |
| 20 | // from the embed.FS instances so it remains testable. |
| 21 | type Deps struct { |
| 22 | Logger *slog.Logger |
| 23 | TemplatesFS fs.FS |
| 24 | StaticFS fs.FS |
| 25 | LogoSVG string |
| 26 | } |
| 27 | |
| 28 | // Register wires every S00 route into mux. Later sprints' Register entrypoints |
| 29 | // are called from here; for S00 the surface is small. |
| 30 | func Register(mux *http.ServeMux, deps Deps) error { |
| 31 | if deps.Logger == nil { |
| 32 | return fmt.Errorf("handlers.Register: nil Logger") |
| 33 | } |
| 34 | if deps.TemplatesFS == nil { |
| 35 | return fmt.Errorf("handlers.Register: nil TemplatesFS") |
| 36 | } |
| 37 | if deps.StaticFS == nil { |
| 38 | return fmt.Errorf("handlers.Register: nil StaticFS") |
| 39 | } |
| 40 | |
| 41 | r, err := render.New(deps.TemplatesFS) |
| 42 | if err != nil { |
| 43 | return fmt.Errorf("renderer: %w", err) |
| 44 | } |
| 45 | |
| 46 | mux.Handle("GET /static/", http.StripPrefix("/static/", staticFileServer(deps.StaticFS))) |
| 47 | mux.HandleFunc("GET /healthz", healthz) |
| 48 | mux.HandleFunc("GET /readyz", readyz) |
| 49 | mux.Handle("GET /{$}", helloHandler{render: r, logoSVG: deps.LogoSVG, logger: deps.Logger}) |
| 50 | |
| 51 | return nil |
| 52 | } |
| 53 |