docs: add eventual-consistency annotations
D-03: document non-transactional boundaries. - Comment in platform_webhook_handler.go explaining that dialog.Process and outbox.InsertPendingBatch are not in a single transaction; 500 is returned on outbox failure for caller retry. - Package-level comment in dialog/service.go noting the lack of a unified transactional outer box and the eventually-consistent nature of storage operations.
This commit is contained in:
@@ -88,6 +88,13 @@ func (h *PlatformWebhookHandler) Handle(w http.ResponseWriter, r *http.Request)
|
|||||||
writeJSON(w, http.StatusInternalServerError, map[string]any{"error": map[string]any{"code": cserrors.CS_SYS_5001, "message": cserrors.ErrorMsg(cserrors.CS_SYS_5001)}})
|
writeJSON(w, http.StatusInternalServerError, map[string]any{"error": map[string]any{"code": cserrors.CS_SYS_5001, "message": cserrors.ErrorMsg(cserrors.CS_SYS_5001)}})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// NOTE: Final-consistency boundary.
|
||||||
|
// dialog.Process and outbox.InsertPendingBatch are NOT enclosed in a single
|
||||||
|
// transaction. If outbox insertion fails after dialog succeeds, the business
|
||||||
|
// state (Session/Ticket/Audit) is already persisted but no downstream event
|
||||||
|
// is emitted. In that case we return HTTP 500 so the platform caller can
|
||||||
|
// retry; DedupRepository.TryRecord inside dialog.Process guards against
|
||||||
|
// duplicate business-state mutations on retry.
|
||||||
if h.eventWriter == nil {
|
if h.eventWriter == nil {
|
||||||
writeJSON(w, http.StatusInternalServerError, map[string]any{"error": map[string]any{"code": cserrors.CS_SYS_5001, "message": cserrors.ErrorMsg(cserrors.CS_SYS_5001)}})
|
writeJSON(w, http.StatusInternalServerError, map[string]any{"error": map[string]any{"code": cserrors.CS_SYS_5001, "message": cserrors.ErrorMsg(cserrors.CS_SYS_5001)}})
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -1,3 +1,14 @@
|
|||||||
|
// Package dialog implements the core message-processing service.
|
||||||
|
//
|
||||||
|
// NOTE on transaction boundaries: the current repository layer does not
|
||||||
|
// provide a unified transactional outer box (UnitOfWork / sql.Tx). Each
|
||||||
|
// repository call (SessionRepository, DedupRepository, TicketRepository,
|
||||||
|
// AuditRepository) executes on its own connection. Therefore the operations
|
||||||
|
// inside Process are eventually-consistent rather than strictly atomic.
|
||||||
|
//
|
||||||
|
// A future refactor introducing UnitOfWork or TxProvider could lift this
|
||||||
|
// limitation and wrap the entire flow plus outbox insertion in a single
|
||||||
|
// transaction.
|
||||||
package dialog
|
package dialog
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
Reference in New Issue
Block a user