add correct backfile

Signed-off-by: GnomeZworc <nicolas.boufidjeline@g3e.fr>
This commit is contained in:
GnomeZworc 2026-06-14 13:41:42 +02:00
commit 28e082f0fc
Signed by: nicolas.boufideline
GPG key ID: 4406BBBF8845D632
8 changed files with 317 additions and 35 deletions

View file

@ -2,6 +2,7 @@ package pipeline
import (
"context"
"fmt"
"log/slog"
"time"
@ -90,6 +91,54 @@ func (p *Pipeline) FetchAll(ctx context.Context) error {
return nil
}
// BackfillInstrument récupère l'historique de prix d'un instrument entre from et to
// et upserte chaque point dans price_history. Idempotent.
func (p *Pipeline) BackfillInstrument(ctx context.Context, instrumentID int32, from, to time.Time) error {
inst, err := p.store.GetInstrument(ctx, instrumentID)
if err != nil {
return fmt.Errorf("get instrument %d: %w", instrumentID, err)
}
switch inst.Type {
case "devise":
return nil // EUR toujours = 1, pas de backfill nécessaire
case "action", "etf":
ticker, err := p.resolveTicker(ctx, inst)
if err != nil {
return fmt.Errorf("resolve ticker for %s: %w", inst.Code, err)
}
points, err := FetchYahooHistory(ctx, ticker, from, to)
if err != nil {
return fmt.Errorf("yahoo history %s: %w", ticker, err)
}
for _, pt := range points {
if err := p.store.UpsertPrice(ctx, inst.ID, pt.At, pt.Price); err != nil {
p.logger.Error("upsert historical price", "instrument", inst.Code, "date", pt.At, "error", err)
}
}
p.logger.Info("backfill done", "instrument", inst.Code, "points", len(points))
case "crypto":
coinID, err := p.resolveCoinID(ctx, inst)
if err != nil {
return fmt.Errorf("resolve coin id for %s: %w", inst.Code, err)
}
points, err := FetchCoinGeckoHistory(ctx, p.cfg.CoinGeckoKey, coinID, from, to)
if err != nil {
return fmt.Errorf("coingecko history %s: %w", coinID, err)
}
for _, pt := range points {
if err := p.store.UpsertPrice(ctx, inst.ID, pt.At, pt.Price); err != nil {
p.logger.Error("upsert historical price", "instrument", inst.Code, "date", pt.At, "error", err)
}
}
p.logger.Info("backfill done", "instrument", inst.Code, "points", len(points))
}
return nil
}
// CleanHistory supprime les prix intraday des jours passés, ne gardant que le dernier par instrument.
func (p *Pipeline) CleanHistory(ctx context.Context) error {
if err := p.store.CleanPastDays(ctx); err != nil {