fix: break sync feedback loop, respect timestamps, surface errors
- Add migration v2: source column on change_log to distinguish local vs sync-originated entries, preventing the echo loop where synced tasks get re-pushed as local changes - PushChanges handler now skips save when server version is newer - Client PushChanges/pushQueuedChanges collect and report marshal errors instead of silently dropping them - De-duplicate getLocalChanges/getLastSyncTime into exported sync package functions - Fix logConflict winner detection via pointer identity instead of fragile UUID+timestamp comparison - Fix sync down to actually parse, save, and tag-sync pulled changes Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -57,7 +57,11 @@ func MergeTasks(local, remote []*engine.Task, strategy ConflictResolution) ([]*e
|
||||
if DetectConflict(task, remoteTask) {
|
||||
conflicts++
|
||||
winner := resolveConflict(task, remoteTask, strategy)
|
||||
logConflict(task, remoteTask, winner)
|
||||
winnerLabel := "local"
|
||||
if winner == remoteTask {
|
||||
winnerLabel = "remote"
|
||||
}
|
||||
logConflict(task, remoteTask, winnerLabel)
|
||||
result = append(result, winner)
|
||||
} else {
|
||||
// No conflict - use either (same content)
|
||||
@@ -110,17 +114,12 @@ func resolveConflict(local, remote *engine.Task, strategy ConflictResolution) *e
|
||||
}
|
||||
|
||||
// logConflict writes conflict information to log file
|
||||
func logConflict(local, remote *engine.Task, winner *engine.Task) {
|
||||
func logConflict(local, remote *engine.Task, winnerLabel string) {
|
||||
logPath, err := engine.GetSyncConflictLogPath()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
winnerLabel := "local"
|
||||
if winner.UUID == remote.UUID && winner.Modified.Equal(remote.Modified) {
|
||||
winnerLabel = "remote"
|
||||
}
|
||||
|
||||
entry := fmt.Sprintf(
|
||||
"[%s] Conflict on task %s\n"+
|
||||
" Local: modified %s - %s\n"+
|
||||
|
||||
Reference in New Issue
Block a user