feat(desktop/account-health): treat active/expiring_soon probes as live and dedupe in-flight checks

Why: avoid showing accounts as not-live during stale-window probes; keep publish gating consistent with runtime view.

- collapse FIRST_PROBE window so initial probe runs immediately
- skip due-probe selection when a probe is already queued/in-flight
- mirror auth-state→health projection on both client report and tenant ingest paths

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-29 15:58:25 +08:00
parent f8b918b9cd
commit 59ad14ef2c
6 changed files with 148 additions and 48 deletions
@@ -505,7 +505,7 @@ func (s *DesktopAccountService) applyRuntimeHealth(ctx context.Context, workspac
continue
}
health := report.Health
health := effectiveDesktopAccountRuntimeHealth(report)
authState := report.AuthState
probeState := report.ProbeState
checkedAt := report.CheckedAt
@@ -523,6 +523,20 @@ func (s *DesktopAccountService) applyRuntimeHealth(ctx context.Context, workspac
}
}
func effectiveDesktopAccountRuntimeHealth(report bufferedDesktopAccountHealthReport) string {
authState := strings.TrimSpace(report.AuthState)
probeState := strings.TrimSpace(report.ProbeState)
switch authState {
case "active":
return "live"
case "expiring_soon":
if probeState != "network_error" {
return "live"
}
}
return report.Health
}
func (s *DesktopAccountService) buildDesktopAccountView(
account *repository.DesktopAccount,
clientMap map[uuid.UUID]*repository.DesktopClient,
@@ -121,7 +121,7 @@ func (s *PublishJobService) Create(ctx context.Context, actor auth.Actor, req Cr
}
accountHealth := account.Health
if report, ok := runtimeHealth[account.DesktopID]; ok && strings.TrimSpace(report.Health) != "" {
accountHealth = report.Health
accountHealth = effectiveDesktopAccountRuntimeHealth(report)
}
if accountHealth != "live" {
return nil, response.ErrConflict(40993, "desktop_account_not_publishable", "one or more selected desktop accounts require re-authorization before publishing")