fix: NeedSync проверяет версии сервера когда онлайн, игнорируя 1-часовой порог

Раньше NeedSync возвращал true сразу если last_sync > 1 часа назад —
до сравнения версий дело не доходило. Это приводило к бесконечным
повторным попыткам синка когда все прайслисты уже скачаны, но
last_pricelist_status застрял в "failed" из-за предыдущего сбоя.

Теперь когда онлайн — всегда сравниваем реальные версии с сервером.
Если все источники совпадают — возвращаем false независимо от времени
последнего синка. Фолбэк на 1-часовой порог только в офлайн-режиме.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-02 14:06:18 +03:00
parent 8d965bfee9
commit 5d5af07fc5

View File

@@ -274,54 +274,49 @@ func (s *Service) GetStatus() (*SyncStatus, error) {
func (s *Service) NeedSync() (bool, error) {
lastSync := s.localDB.GetLastSyncTime()
// If never synced, need sync
// If never synced, always need sync.
if lastSync == nil {
return true, nil
}
// If last sync was more than 1 hour ago, suggest sync
// When online, compare actual server versions regardless of elapsed time.
// This prevents a stale "failed" status from the past from triggering
// endless sync retries when all pricelists are already up to date.
connStatus := s.getConnectionStatus()
if connStatus.IsConnected {
mariaDB, err := s.getDB()
if err == nil {
pricelistRepo := repository.NewPricelistRepository(mariaDB)
sources := []models.PricelistSource{
models.PricelistSourceEstimate,
models.PricelistSourceWarehouse,
models.PricelistSourceCompetitor,
}
allMatch := true
for _, source := range sources {
latestServer, err := pricelistRepo.GetLatestActiveBySource(string(source))
if err != nil {
continue
}
latestLocal, err := s.localDB.GetLatestLocalPricelistBySource(string(source))
if err != nil {
return true, nil
}
if latestServer.ID != latestLocal.ServerID {
return true, nil
}
}
if allMatch {
return false, nil
}
}
}
// Offline fallback: suggest sync if last successful sync was more than 1 hour ago.
if time.Since(*lastSync) > time.Hour {
return true, nil
}
// Check if there are new pricelists on server (only if already connected)
connStatus := s.getConnectionStatus()
if !connStatus.IsConnected {
// If offline, can't check server, no need to sync
return false, nil
}
mariaDB, err := s.getDB()
if err != nil {
// If offline, can't check server, no need to sync
return false, nil
}
pricelistRepo := repository.NewPricelistRepository(mariaDB)
sources := []models.PricelistSource{
models.PricelistSourceEstimate,
models.PricelistSourceWarehouse,
models.PricelistSourceCompetitor,
}
for _, source := range sources {
latestServer, err := pricelistRepo.GetLatestActiveBySource(string(source))
if err != nil {
// No active pricelist for this source yet.
continue
}
latestLocal, err := s.localDB.GetLatestLocalPricelistBySource(string(source))
if err != nil {
// No local pricelist for an existing source on server.
return true, nil
}
// If server has newer pricelist for this source, need sync.
if latestServer.ID != latestLocal.ServerID {
return true, nil
}
}
return false, nil
}