From 9639a03bfed614be56c6415253575e1f170fecd1 Mon Sep 17 00:00:00 2001 From: Denozordec Date: Thu, 21 May 2026 18:10:51 +0700 Subject: [PATCH] feat(store): add test for clearing dispatch error on successful merge - Introduced a new test case in speaker_meta_test.go to verify that the LastDispatchError is cleared when a successful dispatch status is merged. - Updated MergeSpeakerMetaJSON function in speaker_meta.go to clear LastDispatchError if LastDispatchStatus is "ok". - Enhanced speakerDispatchError function in network-metrics.ts to handle stale dispatch errors after successful agent sync. --- internal/store/speaker_meta.go | 4 +++- internal/store/speaker_meta_test.go | 21 +++++++++++++++++++++ web/src/lib/network/network-metrics.ts | 6 ++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/internal/store/speaker_meta.go b/internal/store/speaker_meta.go index 97bc226..a37108b 100644 --- a/internal/store/speaker_meta.go +++ b/internal/store/speaker_meta.go @@ -72,7 +72,9 @@ func MergeSpeakerMetaJSON(existing string, patch SpeakerMeta) string { if patch.LastDispatchAt != "" { cur.LastDispatchAt = patch.LastDispatchAt } - if patch.LastDispatchError != "" { + if patch.LastDispatchStatus == "ok" { + cur.LastDispatchError = "" + } else if patch.LastDispatchError != "" { cur.LastDispatchError = patch.LastDispatchError } if patch.LastDispatchStatus != "" { diff --git a/internal/store/speaker_meta_test.go b/internal/store/speaker_meta_test.go index eaa462f..8413905 100644 --- a/internal/store/speaker_meta_test.go +++ b/internal/store/speaker_meta_test.go @@ -34,3 +34,24 @@ func TestAgentSyncURL(t *testing.T) { t.Fatalf("got %q", u) } } + +func TestMergeSpeakerMetaJSON_clearsDispatchErrorOnOk(t *testing.T) { + t.Parallel() + existing := store.SpeakerMetaJSON(store.SpeakerMeta{ + LastDispatchError: "HTTP 502: bundle 403", + LastDispatchStatus: "error", + SyncStatus: "error", + }) + merged := store.MergeSpeakerMetaJSON(existing, store.SpeakerMeta{ + LastDispatchStatus: "ok", + SyncStatus: "synced", + LastDispatchAt: "2026-05-21T15:06:43Z", + }) + m := store.ParseSpeakerMeta(merged) + if m.LastDispatchError != "" { + t.Fatalf("LastDispatchError should clear on ok dispatch, got %q", m.LastDispatchError) + } + if m.LastDispatchStatus != "ok" || m.SyncStatus != "synced" { + t.Fatalf("status: dispatch=%q sync=%q", m.LastDispatchStatus, m.SyncStatus) + } +} diff --git a/web/src/lib/network/network-metrics.ts b/web/src/lib/network/network-metrics.ts index 93c6c3f..ad014da 100644 --- a/web/src/lib/network/network-metrics.ts +++ b/web/src/lib/network/network-metrics.ts @@ -277,6 +277,12 @@ export function formatSpeakerError(raw: string | null | undefined): FormattedSpe } export function speakerDispatchError(s: SpeakerRow): FormattedSpeakerError | null { + const liveRev = s.live?.agent_last_applied_revision_id?.trim(); + const pub = s.published_revision_id?.trim(); + // CP meta can keep a stale dispatch error after a later successful agent sync. + if (s.live?.agent_ok && liveRev && pub && liveRev === pub) { + return null; + } return formatSpeakerError(s.last_dispatch_error); }