feat(sentiment): add persistent sentiment entities, summaries, SentimentDbService and MQTT RPC refactoring
This commit is contained in:
@@ -52,26 +52,13 @@ public class FinBertAnalyzerService : IFinBertAnalyzerService
|
||||
double minConfidence = 0.60;
|
||||
using (var scope = _scopeFactory.CreateScope())
|
||||
{
|
||||
var settingsService = scope.ServiceProvider.GetService<ISettingsService>();
|
||||
var settingsService = scope.ServiceProvider.GetRequiredService<ISettingsService>();
|
||||
bool isEnglish = string.Equals(article.Language, "en", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
if (settingsService != null)
|
||||
{
|
||||
targetUrl = isEnglish
|
||||
? await settingsService.GetSettingAsync(SettingKeys.EnglishWebhookUrl)
|
||||
: await settingsService.GetSettingAsync(SettingKeys.GermanWebhookUrl);
|
||||
minConfidence = await settingsService.GetSettingAsync(SettingKeys.MinimumConfidenceThreshold);
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(targetUrl))
|
||||
{
|
||||
var settingsDb = scope.ServiceProvider.GetRequiredService<ISettingsDbService>();
|
||||
var settings = await settingsDb.GetSettingsAsync();
|
||||
targetUrl = isEnglish
|
||||
? settings.EnglishWebhookUrl
|
||||
: settings.GermanWebhookUrl;
|
||||
minConfidence = settings.MinConfidenceScore;
|
||||
}
|
||||
targetUrl = isEnglish
|
||||
? await settingsService.GetSettingAsync(SettingKeys.EnglishWebhookUrl)
|
||||
: await settingsService.GetSettingAsync(SettingKeys.GermanWebhookUrl);
|
||||
minConfidence = await settingsService.GetSettingAsync(SettingKeys.MinimumConfidenceThreshold);
|
||||
}
|
||||
|
||||
await _finlyticLogger.LogInfoAsync(SettingKeys.SentimentChannel, "[FinBertAnalyzerService] Analyzing article (ID: {Id}, Lang: {Lang}) via webhook: {Url} (MinConf: {Conf})", article.Id, article.Language ?? "de", targetUrl, minConfidence);
|
||||
@@ -128,11 +115,11 @@ public class FinBertAnalyzerService : IFinBertAnalyzerService
|
||||
double confidence = GetDoubleProp(root, "confidence")
|
||||
?? GetDoubleProp(root, "confidence_score")
|
||||
?? 0.5;
|
||||
string snippet = GetStringProp(root, "summary_snippet")
|
||||
string? impact = GetStringProp(root, "impact") ?? "MEDIUM";
|
||||
string? keyHighlight = GetStringProp(root, "key_highlight")
|
||||
?? GetStringProp(root, "summary_snippet")
|
||||
?? GetStringProp(root, "summary")
|
||||
?? GetStringProp(root, "text")
|
||||
?? article.Summary
|
||||
?? article.Title;
|
||||
?? article.Summary;
|
||||
|
||||
double pos = 0.0, neg = 0.0, neu = 1.0;
|
||||
if (root.TryGetProperty("probabilities", out var probsElem) && probsElem.ValueKind == JsonValueKind.Object)
|
||||
@@ -165,44 +152,57 @@ public class FinBertAnalyzerService : IFinBertAnalyzerService
|
||||
}
|
||||
}
|
||||
|
||||
return new FinBertResultDto
|
||||
var result = new FinBertResultDto
|
||||
{
|
||||
Label = label,
|
||||
CompoundScore = Math.Round(compoundScore, 4),
|
||||
Confidence = Math.Round(confidence, 4),
|
||||
Impact = impact.ToUpperInvariant(),
|
||||
KeyHighlight = keyHighlight,
|
||||
Probabilities = new FinBertProbabilities
|
||||
{
|
||||
Positive = Math.Round(pos, 4),
|
||||
Negative = Math.Round(neg, 4),
|
||||
Neutral = Math.Round(neu, 4)
|
||||
},
|
||||
SummarySnippet = snippet
|
||||
}
|
||||
};
|
||||
|
||||
await _finlyticLogger.LogInfoAsync(SettingKeys.SentimentChannel, "[FinBertAnalyzerService] Successfully analyzed article {Id}: {Label} (Compound: {Score}, Conf: {Conf}, Impact: {Impact})", article.Id, result.Label, result.CompoundScore, result.Confidence, result.Impact);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await _finlyticLogger.LogWarningAsync(SettingKeys.SentimentChannel, "[FinBertAnalyzerService] n8n Webhook returned non-success status: {StatusCode}.", response.StatusCode);
|
||||
else
|
||||
{
|
||||
await _finlyticLogger.LogWarningAsync(SettingKeys.SentimentChannel, "[FinBertAnalyzerService] Webhook call failed with status: {Status} (Article ID: {Id})", response.StatusCode, article.Id);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await _finlyticLogger.LogErrorAsync(SettingKeys.SentimentChannel, ex, "[FinBertAnalyzerService] Failed to call n8n sentiment webhook.");
|
||||
await _finlyticLogger.LogErrorAsync(SettingKeys.SentimentChannel, ex, "[FinBertAnalyzerService] Exception during webhook request for article: {Id}", article.Id);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static string? GetStringProp(JsonElement elem, string propName)
|
||||
private static string? GetStringProp(JsonElement element, string propName)
|
||||
{
|
||||
return elem.TryGetProperty(propName, out var prop) && prop.ValueKind == JsonValueKind.String ? prop.GetString() : null;
|
||||
if (element.TryGetProperty(propName, out var prop) && prop.ValueKind == JsonValueKind.String)
|
||||
{
|
||||
return prop.GetString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static double? GetDoubleProp(JsonElement elem, string propName)
|
||||
private static double? GetDoubleProp(JsonElement element, string propName)
|
||||
{
|
||||
if (elem.TryGetProperty(propName, out var prop))
|
||||
if (element.TryGetProperty(propName, out var prop))
|
||||
{
|
||||
if (prop.ValueKind == JsonValueKind.Number && prop.TryGetDouble(out var d)) return d;
|
||||
if (prop.ValueKind == JsonValueKind.String && double.TryParse(prop.GetString(), out var parsed)) return parsed;
|
||||
if (prop.ValueKind == JsonValueKind.Number && prop.TryGetDouble(out var d))
|
||||
return d;
|
||||
if (prop.ValueKind == JsonValueKind.String && double.TryParse(prop.GetString(), System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out var parsed))
|
||||
return parsed;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user