feat(go): scheduled bank sync (Go only)
The Go server now runs sync -> infer -> flush-cache by itself at the times in SYNC_SCHEDULE (comma-separated HH:MM, default 04:00, "off" disables), read in SYNC_TZ (default Europe/Prague). Nothing runs at startup; an invalid value stops the server with an error. - internal/scheduler: time-of-day parsing, Next, and the run loop - banksync.Runner: one lock shared by /sync-bank and the scheduler so runs never overlap, plus the status of the last run - footer shows the last sync since start and the next scheduled run - binary embeds time/tzdata because the Alpine image has no zone data Deliberately not implemented in the legacy Python app, which is being phased out; recorded in CLAUDE.md under "Deliberately Go-only features". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLoadSyncSchedule(t *testing.T) {
|
||||
cases := []struct {
|
||||
name, schedule, tz string
|
||||
wantTimes int
|
||||
wantZone string
|
||||
wantErr bool
|
||||
}{
|
||||
{"defaults", "", "", 1, "Europe/Prague", false},
|
||||
{"two times", "06:00,18:00", "", 2, "Europe/Prague", false},
|
||||
{"off", "off", "", 0, "Europe/Prague", false},
|
||||
{"other zone", "04:00", "UTC", 1, "UTC", false},
|
||||
{"bad time", "25:00", "", 0, "", true},
|
||||
{"bad zone", "04:00", "Mars/Olympus", 0, "", true},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Setenv("SYNC_SCHEDULE", tc.schedule)
|
||||
t.Setenv("SYNC_TZ", tc.tz)
|
||||
times, loc, err := LoadSyncSchedule()
|
||||
if (err != nil) != tc.wantErr {
|
||||
t.Fatalf("err = %v, wantErr %v", err, tc.wantErr)
|
||||
}
|
||||
if tc.wantErr {
|
||||
return
|
||||
}
|
||||
if len(times) != tc.wantTimes {
|
||||
t.Errorf("times = %v, want %d entries", times, tc.wantTimes)
|
||||
}
|
||||
if loc.String() != tc.wantZone {
|
||||
t.Errorf("zone = %s, want %s", loc, tc.wantZone)
|
||||
}
|
||||
})
|
||||
}
|
||||
t.Setenv("SYNC_SCHEDULE", "")
|
||||
t.Setenv("SYNC_TZ", "")
|
||||
if times, _, _ := LoadSyncSchedule(); len(times) != 1 || times[0].String() != DefaultSyncSchedule {
|
||||
t.Errorf("default schedule = %v, want [%s]", times, DefaultSyncSchedule)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user