mirror of
https://github.com/Dvorinka/Primora.git
synced 2026-10-28 07:41:23 +00:00
- POST /projects/:id/events accepts client-authored events restricted to
the custom.* namespace — system types can't be spoofed. They flow
through the same publishEvent fan-out: realtime, webhooks, and
event_pattern functions all fire.
- Presence: subscribe/unsubscribe bumps a per-project count and
broadcasts presence.update {online} to the realtime stream only —
deliberately not through publishEvent so webhooks and "*" functions
don't fire on connect noise. GET …/realtime/presence reads the count.
- @primora/client gains publish() and presence(); CLI gains events:send.
Verified live: presence 0->1 on subscribe, presence.update frame
delivered, custom event delivered to SSE + fired a custom.* function,
spoofed document.created rejected 400.
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
45 lines
1.2 KiB
Go
45 lines
1.2 KiB
Go
package handlers
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// publishEvent accepts a client-authored domain event (custom.* namespace)
|
|
// and fans it out through the standard publishEvent path — realtime
|
|
// subscribers, matching webhooks, and event_pattern functions all fire.
|
|
func (h *HTTPHandler) publishEvent(c *gin.Context) {
|
|
actor, projectID, ok := h.actorAndProject(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
var body struct {
|
|
Type string `json:"type" validate:"required"`
|
|
Data map[string]any `json:"data"`
|
|
}
|
|
if !h.bindAndValidate(c, &body) {
|
|
return
|
|
}
|
|
if err := h.Platform.PublishProjectEvent(c.Request.Context(), actor, projectID, body.Type, body.Data); err != nil {
|
|
h.handleError(c, err)
|
|
return
|
|
}
|
|
c.JSON(http.StatusAccepted, gin.H{"published": body.Type})
|
|
}
|
|
|
|
// realtimePresence returns the count of clients currently subscribed to the
|
|
// project's realtime stream.
|
|
func (h *HTTPHandler) realtimePresence(c *gin.Context) {
|
|
actor, projectID, ok := h.actorAndProject(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
n, err := h.Platform.Presence(c.Request.Context(), actor, projectID)
|
|
if err != nil {
|
|
h.handleError(c, err)
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, gin.H{"online": n})
|
|
}
|