package web import ( "io/fs" "net/http" "github.com/gin-gonic/gin" "github.com/jackc/pgx/v5/pgxpool" "github.com/mattnite/cairn/internal/blob" "github.com/mattnite/cairn/internal/forgejo" "github.com/mattnite/cairn/internal/handler" assets "github.com/mattnite/cairn/web" ) type RouterConfig struct { Pool *pgxpool.Pool Store blob.Store ForgejoClient *forgejo.Client WebhookSecret string } func NewRouter(cfg RouterConfig) (*gin.Engine, error) { templates, err := LoadTemplates() if err != nil { return nil, err } forgejoSync := &forgejo.Sync{Client: cfg.ForgejoClient, Pool: cfg.Pool} pages := &PageHandler{Pool: cfg.Pool, Templates: templates} ingest := &handler.IngestHandler{Pool: cfg.Pool, Store: cfg.Store, ForgejoSync: forgejoSync} artifactAPI := &handler.ArtifactHandler{Pool: cfg.Pool} download := &handler.DownloadHandler{Pool: cfg.Pool, Store: cfg.Store} crashGroupAPI := &handler.CrashGroupHandler{Pool: cfg.Pool} searchAPI := &handler.SearchHandler{Pool: cfg.Pool} regressionAPI := &handler.RegressionHandler{Pool: cfg.Pool, ForgejoSync: forgejoSync} campaignAPI := &handler.CampaignHandler{Pool: cfg.Pool} dashboardAPI := &handler.DashboardHandler{Pool: cfg.Pool} webhookH := &handler.WebhookHandler{Sync: forgejoSync, Secret: cfg.WebhookSecret} gin.SetMode(gin.ReleaseMode) r := gin.New() r.Use(LoggingMiddleware(), RecoveryMiddleware()) // Static files staticFS, err := fs.Sub(assets.Assets, "static") if err != nil { return nil, err } r.StaticFS("/static", http.FS(staticFS)) // HTML pages r.GET("/", pages.Index) r.GET("/artifacts", pages.Artifacts) r.GET("/artifacts/:id", pages.ArtifactDetail) r.GET("/repos", pages.Repos) r.GET("/crashgroups", pages.CrashGroups) r.GET("/crashgroups/:id", pages.CrashGroupDetail) r.GET("/campaigns", pages.Campaigns) r.GET("/campaigns/:id", pages.CampaignDetail) r.GET("/search", pages.Search) r.GET("/regression", pages.Regression) // JSON API api := r.Group("/api/v1") api.POST("/artifacts", ingest.Create) api.GET("/artifacts", artifactAPI.List) api.GET("/artifacts/:id", artifactAPI.Detail) api.GET("/artifacts/:id/download", download.Download) api.GET("/crashgroups", crashGroupAPI.List) api.GET("/crashgroups/:id", crashGroupAPI.Detail) api.GET("/search", searchAPI.Search) api.POST("/regression/check", regressionAPI.Check) api.POST("/campaigns", campaignAPI.Create) api.GET("/campaigns", campaignAPI.List) api.GET("/campaigns/:id", campaignAPI.Detail) api.POST("/campaigns/:id/finish", campaignAPI.Finish) api.GET("/dashboard", dashboardAPI.Stats) // Webhooks r.POST("/webhooks/forgejo", webhookH.Handle) return r, nil }