package web import ( "io/fs" "net/http" "github.com/gin-gonic/gin" "github.com/mattnite/cairn/internal/blob" "github.com/mattnite/cairn/internal/forgejo" "github.com/mattnite/cairn/internal/handler" assets "github.com/mattnite/cairn/web" "gorm.io/gorm" ) type RouterConfig struct { DB *gorm.DB Store blob.Store ForgejoClient *forgejo.Client ForgejoURL string WebhookSecret string } func NewRouter(cfg RouterConfig) (*gin.Engine, error) { templates, err := LoadTemplates() if err != nil { return nil, err } forgejoSync := &forgejo.Sync{Client: cfg.ForgejoClient, DB: cfg.DB} pages := &PageHandler{DB: cfg.DB, Templates: templates, ForgejoURL: cfg.ForgejoURL} ingest := &handler.IngestHandler{DB: cfg.DB, Store: cfg.Store, ForgejoSync: forgejoSync} artifactAPI := &handler.ArtifactHandler{DB: cfg.DB} download := &handler.DownloadHandler{DB: cfg.DB, Store: cfg.Store} crashGroupAPI := &handler.CrashGroupHandler{DB: cfg.DB} searchAPI := &handler.SearchHandler{DB: cfg.DB} regressionAPI := &handler.RegressionHandler{DB: cfg.DB, ForgejoSync: forgejoSync} campaignAPI := &handler.CampaignHandler{DB: cfg.DB} dashboardAPI := &handler.DashboardHandler{DB: cfg.DB} 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 }