refactor(dotnet): validate raw history ingestion payloads
This commit is contained in:
@@ -15,16 +15,16 @@ namespace QuantEngine.Application.Services
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Task<int> AppendDecisionAsync(IDictionary<string, object?> payload)
|
public Task<int> AppendDecisionAsync(IDictionary<string, object?> payload)
|
||||||
=> _store.AppendAsync("decision_result_history", payload);
|
=> _store.AppendAsync("decision_result_history", RequirePayload(payload));
|
||||||
|
|
||||||
public Task<int> AppendFactorOutputAsync(IDictionary<string, object?> payload)
|
public Task<int> AppendFactorOutputAsync(IDictionary<string, object?> payload)
|
||||||
=> _store.AppendAsync("factor_output_history", payload);
|
=> _store.AppendAsync("factor_output_history", RequirePayload(payload));
|
||||||
|
|
||||||
public Task<int> AppendMarketRawAsync(IDictionary<string, object?> payload)
|
public Task<int> AppendMarketRawAsync(IDictionary<string, object?> payload)
|
||||||
=> _store.AppendAsync("market_raw_history", payload);
|
=> _store.AppendAsync("market_raw_history", RequirePayload(payload));
|
||||||
|
|
||||||
public Task<int> AppendGapAsync(IDictionary<string, object?> payload)
|
public Task<int> AppendGapAsync(IDictionary<string, object?> payload)
|
||||||
=> _store.AppendAsync("market_vs_engine_gap_history", payload);
|
=> _store.AppendAsync("market_vs_engine_gap_history", RequirePayload(payload));
|
||||||
|
|
||||||
public Task<int> AppendDecisionAsync(
|
public Task<int> AppendDecisionAsync(
|
||||||
FinalDecisionResult decision,
|
FinalDecisionResult decision,
|
||||||
@@ -113,5 +113,11 @@ namespace QuantEngine.Application.Services
|
|||||||
|
|
||||||
private static string? NormalizeOptional(string? value)
|
private static string? NormalizeOptional(string? value)
|
||||||
=> string.IsNullOrWhiteSpace(value) ? null : value.Trim();
|
=> string.IsNullOrWhiteSpace(value) ? null : value.Trim();
|
||||||
|
|
||||||
|
private static IDictionary<string, object?> RequirePayload(IDictionary<string, object?> payload)
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(payload);
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,4 +48,12 @@ public class HistoryIngestionServiceTests
|
|||||||
1.0,
|
1.0,
|
||||||
"PASS"));
|
"PASS"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task AppendDecisionAsync_RejectsNullRawPayload()
|
||||||
|
{
|
||||||
|
var service = new HistoryIngestionService(new Mock<IPostgresqlHistoryStore>().Object);
|
||||||
|
|
||||||
|
await Assert.ThrowsAsync<ArgumentNullException>(() => service.AppendDecisionAsync((IDictionary<string, object?>)null!));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user