twelve version
Deploy / Test, build and deploy (push) Successful in 50s

This commit is contained in:
2026-06-08 20:11:10 +00:00
parent 82cd1936ea
commit f877907b20
9 changed files with 284 additions and 18 deletions
+10 -1
View File
@@ -29,7 +29,16 @@ func (r Registry) SyncMetadata(ctx context.Context) error {
}
remote, err := r.gateway.GetInstrument(ctx, instrument.Ticker, instrument.ClassCode)
if err != nil {
return fmt.Errorf("sync instrument metadata %s: %w", instrument.Ticker, err)
if insertErr := r.repo.InsertRiskEvent(ctx, domain.RiskEvent{
Severity: domain.SeverityWarn,
EventType: "instrument_metadata_sync_failed",
InstrumentUID: instrument.InstrumentUID,
Message: fmt.Sprintf("sync instrument metadata %s: %s", instrument.Ticker, err),
ContextJSON: fmt.Sprintf(`{"ticker":%q,"class_code":%q}`, instrument.Ticker, instrument.ClassCode),
}); insertErr != nil {
return fmt.Errorf("record metadata sync failure %s: %w", instrument.Ticker, insertErr)
}
continue
}
remote.Enabled = instrument.Enabled && remote.Enabled
remote.FundType = instrument.FundType
+38 -6
View File
@@ -12,11 +12,11 @@ import (
"overnight-trading-bot/internal/tinvest"
)
func TestSyncMetadataFailsWhenEnabledInstrumentCannotBeLoaded(t *testing.T) {
func TestSyncMetadataSkipsInstrumentWhenRemoteMetadataFails(t *testing.T) {
ctx := context.Background()
repo := testutil.NewMemoryRepository()
gateway := tinvest.NewFakeGateway()
instrument := domain.Instrument{
bad := domain.Instrument{
InstrumentUID: "uid",
Ticker: "TRUR",
ClassCode: "TQTF",
@@ -25,14 +25,46 @@ func TestSyncMetadataFailsWhenEnabledInstrumentCannotBeLoaded(t *testing.T) {
Currency: "RUB",
Enabled: true,
}
if err := repo.UpsertInstrument(ctx, instrument); err != nil {
good := domain.Instrument{
InstrumentUID: "good-local",
Ticker: "TGLD",
ClassCode: "TQTF",
Lot: 1,
MinPriceIncrement: decimal.NewFromInt(1),
Currency: "RUB",
Enabled: true,
}
remoteGood := good
remoteGood.InstrumentUID = "good-remote"
remoteGood.Name = "remote metadata"
if err := repo.UpsertInstrument(ctx, bad); err != nil {
t.Fatal(err)
}
gateway.Instruments["uid"] = instrument
if err := repo.UpsertInstrument(ctx, good); err != nil {
t.Fatal(err)
}
gateway.Instruments["uid"] = bad
gateway.Instruments["good-remote"] = remoteGood
gateway.InstrumentErrors["uid"] = errors.New("metadata unavailable")
err := NewRegistry(repo, gateway).SyncMetadata(ctx)
if err == nil {
t.Fatal("expected sync metadata error")
if err != nil {
t.Fatal(err)
}
if len(repo.RiskEvents) != 1 || repo.RiskEvents[0].EventType != "instrument_metadata_sync_failed" {
t.Fatalf("risk events=%+v, want one metadata sync failure", repo.RiskEvents)
}
instruments, err := repo.ListInstruments(ctx, true)
if err != nil {
t.Fatal(err)
}
foundRemote := false
for _, instrument := range instruments {
if instrument.InstrumentUID == "good-remote" && instrument.Name == "remote metadata" {
foundRemote = true
}
}
if !foundRemote {
t.Fatalf("instruments=%+v, want successful instruments to keep syncing", instruments)
}
}