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:
@@ -1,6 +1,8 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"fuj-management/go/internal/scheduler"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -92,6 +94,28 @@ func Load() Config {
|
||||
}
|
||||
}
|
||||
|
||||
// Scheduled bank sync defaults (Go server only; the legacy Python app has no scheduler).
|
||||
const (
|
||||
DefaultSyncSchedule = "04:00" // SYNC_SCHEDULE: comma-separated HH:MM times, or "off"
|
||||
DefaultSyncTimezone = "Europe/Prague" // SYNC_TZ: IANA zone the schedule is read in
|
||||
)
|
||||
|
||||
// LoadSyncSchedule reads SYNC_SCHEDULE and SYNC_TZ. An empty schedule means
|
||||
// the scheduled sync is disabled. Resolving the zone needs a zone database:
|
||||
// the server binary embeds one via time/tzdata.
|
||||
func LoadSyncSchedule() ([]scheduler.TimeOfDay, *time.Location, error) {
|
||||
times, err := scheduler.ParseTimes(env("SYNC_SCHEDULE", DefaultSyncSchedule))
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("SYNC_SCHEDULE: %w", err)
|
||||
}
|
||||
tz := env("SYNC_TZ", DefaultSyncTimezone)
|
||||
loc, err := time.LoadLocation(tz)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("SYNC_TZ: unknown time zone %q", tz)
|
||||
}
|
||||
return times, loc, nil
|
||||
}
|
||||
|
||||
// IBANAccountNum extracts the bare account number from a Czech IBAN.
|
||||
// "CZ8520100000002800359168" → "2800359168"
|
||||
// Structure: CZ(2 check)(4 bank code)(16 zero-padded account).
|
||||
|
||||
Reference in New Issue
Block a user