Changeset 0.28.3 (#187)

This commit is contained in:
2026-03-14 12:30:57 +00:00
parent b2c03be001
commit f68a58b073
46 changed files with 1589 additions and 107 deletions

View File

@@ -130,26 +130,43 @@ func (h *WorkflowAssignmentHandler) Claim(c *gin.Context) {
return
}
// Emit workflow.claimed WS event
if h.hub != nil {
// Look up channel for this assignment (needed for WS delivery + notification)
var channelID string
_ = database.DB.QueryRowContext(c.Request.Context(),
database.Q(`SELECT channel_id FROM workflow_assignments WHERE id = $1`),
assignmentID).Scan(&channelID)
// Emit workflow.claimed WS event to all user participants in the channel.
// Uses SendToUser (not room-scoped Bus.Publish) because room subscriptions
// are not yet wired on the client side. See websocket.md § Room Model.
if h.hub != nil && channelID != "" {
payload, _ := json.Marshal(map[string]any{
"assignment_id": assignmentID,
"claimed_by": userID,
"channel_id": channelID,
})
h.hub.GetBus().Publish(events.Event{
evt := events.Event{
Label: "workflow.claimed",
Room: assignmentID,
Payload: payload,
Ts: now.UnixMilli(),
})
}
rows, err := database.DB.QueryContext(c.Request.Context(), database.Q(`
SELECT participant_id FROM channel_participants
WHERE channel_id = $1 AND participant_type = 'user'
`), channelID)
if err == nil {
defer rows.Close()
for rows.Next() {
var uid string
if rows.Scan(&uid) == nil {
h.hub.SendToUser(uid, evt)
}
}
}
}
// Persist notification for bell/inbox (v0.28.2)
if svc := notifications.Default(); svc != nil {
var channelID string
_ = database.DB.QueryRowContext(c.Request.Context(),
database.Q(`SELECT channel_id FROM workflow_assignments WHERE id = $1`),
assignmentID).Scan(&channelID)
if svc := notifications.Default(); svc != nil && channelID != "" {
notifications.NotifyWorkflowClaimed(svc, userID, assignmentID, channelID)
}

View File

@@ -338,18 +338,36 @@ func (h *WorkflowInstanceHandler) readWorkflowState(ctx context.Context, channel
return
}
// emitWorkflowEvent pushes a workflow event to all connected clients in the channel's room.
// emitWorkflowEvent pushes a workflow event to all user participants in the channel.
// Uses SendToUser (not room-scoped Bus.Publish) because room subscriptions are
// not yet wired on the client side. See websocket.md § Room Model.
func (h *WorkflowInstanceHandler) emitWorkflowEvent(label, channelID string, data map[string]any) {
if h.hub == nil {
return
}
payload, _ := json.Marshal(data)
h.hub.GetBus().Publish(events.Event{
evt := events.Event{
Label: label,
Room: channelID,
Payload: payload,
Ts: time.Now().UnixMilli(),
})
}
// Send to all user participants in the channel
rows, err := database.DB.Query(database.Q(`
SELECT participant_id FROM channel_participants
WHERE channel_id = $1 AND participant_type = 'user'
`), channelID)
if err != nil {
log.Printf("[ws] %s: failed to query participants for channel %s: %v", label, channelID[:min(8, len(channelID))], err)
return
}
defer rows.Close()
for rows.Next() {
var uid string
if rows.Scan(&uid) == nil {
h.hub.SendToUser(uid, evt)
}
}
}
// triggerOnComplete checks if the workflow has an on_complete chain config