H-337: fix Web Channel availability and realtime delivery (#60)

* H-337: fix Web Channel availability and realtime delivery

* fix(widget): preserve realtime sender and activity contracts

* fix(widget): keep realtime sender payloads consistent

* fix(widget): make public message persistence atomic

* fix(inbox): keep availability projection out of schema

---------

Co-authored-by: Rogee <rogee@ipao.vip>
This commit is contained in:
Rogee
2026-08-20 14:30:05 +08:00
committed by GitHub
co-authored by rogee
parent 55b56ee172
commit 3d9817c9f5
17 changed files with 769 additions and 247 deletions
@@ -311,37 +311,6 @@ func TestWidgetHandler_Cov3_GetConversations_ChatwootRoute_Cov3(t *testing.T) {
}
}
// ---------- SendMessage with event publisher ----------
func TestWidgetHandler_Cov3_SendMessage_WithEventPublisher_Cov3(t *testing.T) {
db, router, handler := setupWidgetHandlerTest(t)
seedWidgetHandlerData(t, db)
// Set event publisher
publisher := &recordingWidgetEventPublisher{}
handler.WithEventPublisher(publisher)
// Config to get a widget token
wConfig := httptest.NewRecorder()
reqConfig, _ := http.NewRequest("POST", "/api/v1/widget/config?website_token=handler_ws_token_123", nil)
router.ServeHTTP(wConfig, reqConfig)
require.Equal(t, http.StatusOK, wConfig.Code)
var configResp map[string]interface{}
require.NoError(t, json.Unmarshal(wConfig.Body.Bytes(), &configResp))
authToken := configResp["contact"].(map[string]interface{})["pubsub_token"].(string)
// Send message
messageBody, _ := json.Marshal(map[string]interface{}{"message": map[string]interface{}{"content": "hello with publisher"}})
wMsg := httptest.NewRecorder()
reqMsg, _ := http.NewRequest("POST", "/api/v1/widget/messages?cw_conversation="+authToken, bytes.NewReader(messageBody))
reqMsg.Header.Set("Content-Type", "application/json")
router.ServeHTTP(wMsg, reqMsg)
require.Equal(t, http.StatusOK, wMsg.Code, wMsg.Body.String())
// The event publisher should have been called
assert.NotZero(t, publisher.accountID)
}
// ---------- SendTranscript with valid token (needs conversation) ----------
func TestWidgetHandler_Cov3_SendTranscript_WithConversation_Cov3(t *testing.T) {