Files
8b682aa6f6 fix(coinbaseprime): avoid refetching payments on every account fetch cycle (#707)
* fix(coinbaseprime): avoid refetching payments on every account fetch

TASK_FETCH_PAYMENTS was a child of TASK_FETCH_ACCOUNTS, so payments
were re-fetched from scratch on every account sync cycle. Moving it
to a top-level sibling task makes it run independently on its own
schedule instead of being triggered by every account fetch.

Backport of fix from PR #657 (fd62842).

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>

* fix(coinbaseprime): fix cursor reset causing full refetch on every cycle

Without advanceCursor, when Coinbase returns an empty next_cursor at
end-of-pagination the state was reset to an empty cursor, causing the
next run to refetch all transactions from the beginning.

- Extract paymentsState into shared incrementalState in state.go
- Introduce advanceCursor: keep the previous cursor when next_cursor is
  empty so the pagination marker is never wiped

Backport of fix from PR #657 (fd62842).

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>

* test(coinbaseprime): add unit tests for advanceCursor

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>

---------

Co-authored-by: Claude <[email protected]>
Co-authored-by: Claude Sonnet 4.6 <[email protected]>
2026-05-04 10:15:55 +02:00

35 lines
794 B
Go

package coinbaseprime
import "testing"
func TestAdvanceCursor_UsesNextWhenNonEmpty(t *testing.T) {
t.Parallel()
got := advanceCursor("old", "next-cursor")
if got != "next-cursor" {
t.Errorf("want next-cursor, got %q", got)
}
}
func TestAdvanceCursor_KeepsOldWhenNextEmpty(t *testing.T) {
t.Parallel()
// End-of-pagination: Coinbase returns empty next_cursor. The plugin
// must keep the previous cursor rather than resetting to the start of
// history.
got := advanceCursor("old", "")
if got != "old" {
t.Errorf("want old, got %q", got)
}
}
func TestAdvanceCursor_FirstRun(t *testing.T) {
t.Parallel()
// First-ever call: both oldCursor and nextCursor empty → stay empty.
got := advanceCursor("", "")
if got != "" {
t.Errorf("want empty cursor, got %q", got)
}
}