From 7bbe47b9438a006ff744d1da5b0b4bbcace9fc60 Mon Sep 17 00:00:00 2001 From: clawbot Date: Sun, 1 Mar 2026 15:44:22 -0800 Subject: [PATCH] refactor: rename Processor to Webhook and Webhook to Entrypoint The top-level entity that groups entrypoints and targets is now called Webhook (was Processor). The inbound URL endpoint entity is now called Entrypoint (was Webhook). This rename affects database models, handler comments, routes, and README documentation. closes https://git.eeqj.de/sneak/webhooker/issues/12 --- internal/database/model_entrypoint.go | 14 +++++++++++ internal/database/model_event.go | 8 +++---- internal/database/model_processor.go | 16 ------------- internal/database/model_target.go | 12 +++++----- internal/database/model_user.go | 4 ++-- internal/database/model_webhook.go | 14 ++++++----- internal/database/models.go | 2 +- internal/handlers/source_management.go | 32 +++++++++++++------------- internal/handlers/webhook.go | 12 +++++----- internal/server/routes.go | 12 +++++----- 10 files changed, 63 insertions(+), 63 deletions(-) create mode 100644 internal/database/model_entrypoint.go delete mode 100644 internal/database/model_processor.go diff --git a/internal/database/model_entrypoint.go b/internal/database/model_entrypoint.go new file mode 100644 index 0000000..37b7e3b --- /dev/null +++ b/internal/database/model_entrypoint.go @@ -0,0 +1,14 @@ +package database + +// Entrypoint represents an inbound URL endpoint that feeds into a webhook +type Entrypoint struct { + BaseModel + + WebhookID string `gorm:"type:uuid;not null" json:"webhook_id"` + Path string `gorm:"uniqueIndex;not null" json:"path"` // URL path for this entrypoint + Description string `json:"description"` + Active bool `gorm:"default:true" json:"active"` + + // Relations + Webhook Webhook `json:"webhook,omitempty"` +} diff --git a/internal/database/model_event.go b/internal/database/model_event.go index 7b6ea50..f9dbaed 100644 --- a/internal/database/model_event.go +++ b/internal/database/model_event.go @@ -1,11 +1,11 @@ package database -// Event represents a webhook event +// Event represents a captured webhook event type Event struct { BaseModel - ProcessorID string `gorm:"type:uuid;not null" json:"processor_id"` - WebhookID string `gorm:"type:uuid;not null" json:"webhook_id"` + WebhookID string `gorm:"type:uuid;not null" json:"webhook_id"` + EntrypointID string `gorm:"type:uuid;not null" json:"entrypoint_id"` // Request data Method string `gorm:"not null" json:"method"` @@ -14,7 +14,7 @@ type Event struct { ContentType string `json:"content_type"` // Relations - Processor Processor `json:"processor,omitempty"` Webhook Webhook `json:"webhook,omitempty"` + Entrypoint Entrypoint `json:"entrypoint,omitempty"` Deliveries []Delivery `json:"deliveries,omitempty"` } diff --git a/internal/database/model_processor.go b/internal/database/model_processor.go deleted file mode 100644 index 121b0c1..0000000 --- a/internal/database/model_processor.go +++ /dev/null @@ -1,16 +0,0 @@ -package database - -// Processor represents an event processor -type Processor struct { - BaseModel - - UserID string `gorm:"type:uuid;not null" json:"user_id"` - Name string `gorm:"not null" json:"name"` - Description string `json:"description"` - RetentionDays int `gorm:"default:30" json:"retention_days"` // Days to retain events - - // Relations - User User `json:"user,omitempty"` - Webhooks []Webhook `json:"webhooks,omitempty"` - Targets []Target `json:"targets,omitempty"` -} diff --git a/internal/database/model_target.go b/internal/database/model_target.go index 76478ba..1c1c842 100644 --- a/internal/database/model_target.go +++ b/internal/database/model_target.go @@ -10,14 +10,14 @@ const ( TargetTypeLog TargetType = "log" ) -// Target represents a delivery target for a processor +// Target represents a delivery target for a webhook type Target struct { BaseModel - ProcessorID string `gorm:"type:uuid;not null" json:"processor_id"` - Name string `gorm:"not null" json:"name"` - Type TargetType `gorm:"not null" json:"type"` - Active bool `gorm:"default:true" json:"active"` + WebhookID string `gorm:"type:uuid;not null" json:"webhook_id"` + Name string `gorm:"not null" json:"name"` + Type TargetType `gorm:"not null" json:"type"` + Active bool `gorm:"default:true" json:"active"` // Configuration fields (JSON stored based on type) Config string `gorm:"type:text" json:"config"` // JSON configuration @@ -27,6 +27,6 @@ type Target struct { MaxQueueSize int `json:"max_queue_size,omitempty"` // Relations - Processor Processor `json:"processor,omitempty"` + Webhook Webhook `json:"webhook,omitempty"` Deliveries []Delivery `json:"deliveries,omitempty"` } diff --git a/internal/database/model_user.go b/internal/database/model_user.go index b31afdb..6a578d0 100644 --- a/internal/database/model_user.go +++ b/internal/database/model_user.go @@ -8,6 +8,6 @@ type User struct { Password string `gorm:"not null" json:"-"` // Argon2 hashed // Relations - Processors []Processor `json:"processors,omitempty"` - APIKeys []APIKey `json:"api_keys,omitempty"` + Webhooks []Webhook `json:"webhooks,omitempty"` + APIKeys []APIKey `json:"api_keys,omitempty"` } diff --git a/internal/database/model_webhook.go b/internal/database/model_webhook.go index 7fae55f..08e4bc4 100644 --- a/internal/database/model_webhook.go +++ b/internal/database/model_webhook.go @@ -1,14 +1,16 @@ package database -// Webhook represents a webhook endpoint that feeds into a processor +// Webhook represents a webhook processing unit that groups entrypoints and targets type Webhook struct { BaseModel - ProcessorID string `gorm:"type:uuid;not null" json:"processor_id"` - Path string `gorm:"uniqueIndex;not null" json:"path"` // URL path for this webhook - Description string `json:"description"` - Active bool `gorm:"default:true" json:"active"` + UserID string `gorm:"type:uuid;not null" json:"user_id"` + Name string `gorm:"not null" json:"name"` + Description string `json:"description"` + RetentionDays int `gorm:"default:30" json:"retention_days"` // Days to retain events // Relations - Processor Processor `json:"processor,omitempty"` + User User `json:"user,omitempty"` + Entrypoints []Entrypoint `json:"entrypoints,omitempty"` + Targets []Target `json:"targets,omitempty"` } diff --git a/internal/database/models.go b/internal/database/models.go index 560fdce..ce19b36 100644 --- a/internal/database/models.go +++ b/internal/database/models.go @@ -5,8 +5,8 @@ func (d *Database) Migrate() error { return d.db.AutoMigrate( &User{}, &APIKey{}, - &Processor{}, &Webhook{}, + &Entrypoint{}, &Target{}, &Event{}, &Delivery{}, diff --git a/internal/handlers/source_management.go b/internal/handlers/source_management.go index e8cd792..11d166f 100644 --- a/internal/handlers/source_management.go +++ b/internal/handlers/source_management.go @@ -4,66 +4,66 @@ import ( "net/http" ) -// HandleSourceList shows a list of user's webhook sources +// HandleSourceList shows a list of user's webhooks func (h *Handlers) HandleSourceList() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - // TODO: Implement source list page + // TODO: Implement webhook list page http.Error(w, "Not implemented", http.StatusNotImplemented) } } -// HandleSourceCreate shows the form to create a new webhook source +// HandleSourceCreate shows the form to create a new webhook func (h *Handlers) HandleSourceCreate() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - // TODO: Implement source creation form + // TODO: Implement webhook creation form http.Error(w, "Not implemented", http.StatusNotImplemented) } } -// HandleSourceCreateSubmit handles the source creation form submission +// HandleSourceCreateSubmit handles the webhook creation form submission func (h *Handlers) HandleSourceCreateSubmit() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - // TODO: Implement source creation logic + // TODO: Implement webhook creation logic http.Error(w, "Not implemented", http.StatusNotImplemented) } } -// HandleSourceDetail shows details for a specific webhook source +// HandleSourceDetail shows details for a specific webhook func (h *Handlers) HandleSourceDetail() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - // TODO: Implement source detail page + // TODO: Implement webhook detail page http.Error(w, "Not implemented", http.StatusNotImplemented) } } -// HandleSourceEdit shows the form to edit a webhook source +// HandleSourceEdit shows the form to edit a webhook func (h *Handlers) HandleSourceEdit() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - // TODO: Implement source edit form + // TODO: Implement webhook edit form http.Error(w, "Not implemented", http.StatusNotImplemented) } } -// HandleSourceEditSubmit handles the source edit form submission +// HandleSourceEditSubmit handles the webhook edit form submission func (h *Handlers) HandleSourceEditSubmit() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - // TODO: Implement source update logic + // TODO: Implement webhook update logic http.Error(w, "Not implemented", http.StatusNotImplemented) } } -// HandleSourceDelete handles webhook source deletion +// HandleSourceDelete handles webhook deletion func (h *Handlers) HandleSourceDelete() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - // TODO: Implement source deletion logic + // TODO: Implement webhook deletion logic http.Error(w, "Not implemented", http.StatusNotImplemented) } } -// HandleSourceLogs shows the request/response logs for a webhook source +// HandleSourceLogs shows the request/response logs for a webhook func (h *Handlers) HandleSourceLogs() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - // TODO: Implement source logs page + // TODO: Implement webhook logs page http.Error(w, "Not implemented", http.StatusNotImplemented) } } diff --git a/internal/handlers/webhook.go b/internal/handlers/webhook.go index 474d2f8..a515966 100644 --- a/internal/handlers/webhook.go +++ b/internal/handlers/webhook.go @@ -6,19 +6,19 @@ import ( "github.com/go-chi/chi" ) -// HandleWebhook handles incoming webhook requests +// HandleWebhook handles incoming webhook requests at entrypoint URLs func (h *Handlers) HandleWebhook() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - // Get webhook UUID from URL - webhookUUID := chi.URLParam(r, "uuid") - if webhookUUID == "" { + // Get entrypoint UUID from URL + entrypointUUID := chi.URLParam(r, "uuid") + if entrypointUUID == "" { http.NotFound(w, r) return } // Log the incoming webhook request h.log.Info("webhook request received", - "uuid", webhookUUID, + "entrypoint_uuid", entrypointUUID, "method", r.Method, "remote_addr", r.RemoteAddr, "user_agent", r.UserAgent(), @@ -32,7 +32,7 @@ func (h *Handlers) HandleWebhook() http.HandlerFunc { } // TODO: Implement webhook handling logic - // For now, return "unimplemented" for all webhook POST requests + // Look up entrypoint by UUID, find parent webhook, fan out to targets w.WriteHeader(http.StatusNotFound) _, err := w.Write([]byte("unimplemented")) if err != nil { diff --git a/internal/server/routes.go b/internal/server/routes.go index e9bb056..3c177c9 100644 --- a/internal/server/routes.go +++ b/internal/server/routes.go @@ -90,23 +90,23 @@ func (s *Server) SetupRoutes() { r.Get("/", s.h.HandleProfile()) }) - // Webhook source management routes (require authentication) + // Webhook management routes (require authentication) s.router.Route("/sources", func(r chi.Router) { // TODO: Add authentication middleware here - r.Get("/", s.h.HandleSourceList()) // List all sources + r.Get("/", s.h.HandleSourceList()) // List all webhooks r.Get("/new", s.h.HandleSourceCreate()) // Show create form r.Post("/new", s.h.HandleSourceCreateSubmit()) // Handle create submission }) s.router.Route("/source/{sourceID}", func(r chi.Router) { // TODO: Add authentication middleware here - r.Get("/", s.h.HandleSourceDetail()) // View source details + r.Get("/", s.h.HandleSourceDetail()) // View webhook details r.Get("/edit", s.h.HandleSourceEdit()) // Show edit form r.Post("/edit", s.h.HandleSourceEditSubmit()) // Handle edit submission - r.Post("/delete", s.h.HandleSourceDelete()) // Delete source - r.Get("/logs", s.h.HandleSourceLogs()) // View source logs + r.Post("/delete", s.h.HandleSourceDelete()) // Delete webhook + r.Get("/logs", s.h.HandleSourceLogs()) // View webhook logs }) - // Webhook endpoint - accepts all HTTP methods + // Entrypoint endpoint - accepts incoming webhook POST requests s.router.HandleFunc("/webhook/{uuid}", s.h.HandleWebhook()) }