feat: add webhook event history UI page
All checks were successful
Check / check (pull_request) Successful in 5s

Add a per-app webhook event history page at /apps/{id}/webhooks that
displays received webhook events with their match/no-match status,
event type, branch, commit SHA (linked to commit URL when available),
and timestamp.

Changes:
- Add webhook_events.html template following existing UI patterns
- Add HandleAppWebhookEvents handler in webhook_events.go
- Register GET /apps/{id}/webhooks route
- Register webhook_events.html in template cache
- Add ShortCommit() method to WebhookEvent model
- Add 'Event History' link to app detail Webhook URL section
This commit is contained in:
clawbot
2026-03-10 04:19:18 -07:00
parent 49ff625ac4
commit e3bd3202bb
6 changed files with 155 additions and 1 deletions

View File

@@ -0,0 +1,56 @@
package handlers
import (
"net/http"
"github.com/go-chi/chi/v5"
"sneak.berlin/go/upaas/internal/models"
"sneak.berlin/go/upaas/templates"
)
// webhookEventsLimit is the number of webhook events to show in history.
const webhookEventsLimit = 100
// HandleAppWebhookEvents returns the webhook event history handler.
func (h *Handlers) HandleAppWebhookEvents() http.HandlerFunc {
tmpl := templates.GetParsed()
return func(writer http.ResponseWriter, request *http.Request) {
appID := chi.URLParam(request, "id")
application, findErr := models.FindApp(request.Context(), h.db, appID)
if findErr != nil {
h.log.Error("failed to find app", "error", findErr)
http.Error(writer, "Internal Server Error", http.StatusInternalServerError)
return
}
if application == nil {
http.NotFound(writer, request)
return
}
events, eventsErr := application.GetWebhookEvents(
request.Context(),
webhookEventsLimit,
)
if eventsErr != nil {
h.log.Error("failed to get webhook events",
"error", eventsErr,
"app", appID,
)
events = []*models.WebhookEvent{}
}
data := h.addGlobals(map[string]any{
"App": application,
"Events": events,
}, request)
h.renderTemplate(writer, tmpl, "webhook_events.html", data)
}
}

View File

@@ -52,6 +52,20 @@ func (w *WebhookEvent) Reload(ctx context.Context) error {
return w.scan(row)
}
// ShortCommit returns a truncated commit SHA for display.
func (w *WebhookEvent) ShortCommit() string {
if !w.CommitSHA.Valid {
return ""
}
sha := w.CommitSHA.String
if len(sha) > shortCommitLength {
return sha[:shortCommitLength]
}
return sha
}
func (w *WebhookEvent) insert(ctx context.Context) error {
query := `
INSERT INTO webhook_events (

View File

@@ -70,6 +70,7 @@ func (s *Server) SetupRoutes() {
r.Post("/apps/{id}/deploy", s.handlers.HandleAppDeploy())
r.Post("/apps/{id}/deployments/cancel", s.handlers.HandleCancelDeploy())
r.Get("/apps/{id}/deployments", s.handlers.HandleAppDeployments())
r.Get("/apps/{id}/webhooks", s.handlers.HandleAppWebhookEvents())
r.Get("/apps/{id}/deployments/{deploymentID}/logs", s.handlers.HandleDeploymentLogsAPI())
r.Get("/apps/{id}/deployments/{deploymentID}/download", s.handlers.HandleDeploymentLogDownload())
r.Get("/apps/{id}/logs", s.handlers.HandleAppLogs())