feat(core): update DTOs, Trade Republic client, Yahoo scrapers, and dynamic settings

This commit is contained in:
2026-08-14 23:55:02 +02:00
parent 3d8af3940b
commit 4f733bf8c3
511 changed files with 1990 additions and 1080548 deletions
@@ -0,0 +1,186 @@
using System;
using System.Threading.Tasks;
using FinlyticCore.Models.Settings;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
namespace FinlyticCore.Services;
/// <summary>
/// Bietet kanalbasierte, dynamisch steuerbare Logging-Funktionalitäten über den <see cref="ISettingsService{TContext}"/>.
/// </summary>
/// <typeparam name="TContextClass">Die aufrufende Klasse (für Log-Kategorien).</typeparam>
/// <typeparam name="TDbContext">Der DbContext des Services für den Zugriff auf die Settings.</typeparam>
public interface IFinlyticLogger<TContextClass, TDbContext> where TDbContext : DbContext
{
// --- Debug ---
Task LogDebugAsync(SettingKey<bool> channelKey, string message, params object[] args);
Task LogDebugAsync(SettingKey<bool> channelKey, Exception? exception, string message, params object[] args);
// --- Info ---
Task LogInfoAsync(SettingKey<bool> channelKey, string message, params object[] args);
Task LogInfoAsync(SettingKey<bool> channelKey, Exception? exception, string message, params object[] args);
// --- Warning ---
Task LogWarningAsync(SettingKey<bool> channelKey, string message, params object[] args);
Task LogWarningAsync(SettingKey<bool> channelKey, Exception? exception, string message, params object[] args);
// --- Error ---
Task LogErrorAsync(SettingKey<bool> channelKey, string message, params object[] args);
Task LogErrorAsync(SettingKey<bool> channelKey, Exception? exception, string message, params object[] args);
// --- Trace & Critical ---
Task LogTraceAsync(SettingKey<bool> channelKey, string message, params object[] args);
Task LogCriticalAsync(SettingKey<bool> channelKey, Exception? exception, string message, params object[] args);
}
/// <summary>
/// Kanalbasierte Logger-Implementierung, die Einstellungen und Stummschaltungen
/// in Echtzeit aus dem <see cref="ISettingsService{TContext}"/> bezieht.
/// </summary>
public class FinlyticLogger<TContextClass, TDbContext> : IFinlyticLogger<TContextClass, TDbContext>
where TDbContext : DbContext
{
private readonly ILogger<TContextClass> _logger;
private readonly ISettingsService<TDbContext> _settingsService;
public FinlyticLogger(
ILogger<TContextClass> logger,
ISettingsService<TDbContext> settingsService)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_settingsService = settingsService ?? throw new ArgumentNullException(nameof(settingsService));
}
#region Debug
public async Task LogDebugAsync(SettingKey<bool> channelKey, string message, params object[] args)
{
if (await ShouldLogAsync(channelKey, LogLevel.Debug))
{
_logger.LogDebug(message, args);
}
}
public async Task LogDebugAsync(SettingKey<bool> channelKey, Exception? exception, string message, params object[] args)
{
if (await ShouldLogAsync(channelKey, LogLevel.Debug))
{
if (exception != null)
_logger.LogDebug(exception, message, args);
else
_logger.LogDebug(message, args);
}
}
#endregion
#region Info
public async Task LogInfoAsync(SettingKey<bool> channelKey, string message, params object[] args)
{
if (await ShouldLogAsync(channelKey, LogLevel.Information))
{
_logger.LogInformation(message, args);
}
}
public async Task LogInfoAsync(SettingKey<bool> channelKey, Exception? exception, string message, params object[] args)
{
if (await ShouldLogAsync(channelKey, LogLevel.Information))
{
if (exception != null)
_logger.LogInformation(exception, message, args);
else
_logger.LogInformation(message, args);
}
}
#endregion
#region Warning
public async Task LogWarningAsync(SettingKey<bool> channelKey, string message, params object[] args)
{
if (await ShouldLogAsync(channelKey, LogLevel.Warning))
{
_logger.LogWarning(message, args);
}
}
public async Task LogWarningAsync(SettingKey<bool> channelKey, Exception? exception, string message, params object[] args)
{
if (await ShouldLogAsync(channelKey, LogLevel.Warning))
{
if (exception != null)
_logger.LogWarning(exception, message, args);
else
_logger.LogWarning(message, args);
}
}
#endregion
#region Error
public async Task LogErrorAsync(SettingKey<bool> channelKey, string message, params object[] args)
{
if (await ShouldLogAsync(channelKey, LogLevel.Error))
{
_logger.LogError(message, args);
}
}
public async Task LogErrorAsync(SettingKey<bool> channelKey, Exception? exception, string message, params object[] args)
{
if (await ShouldLogAsync(channelKey, LogLevel.Error))
{
if (exception != null)
_logger.LogError(exception, message, args);
else
_logger.LogError(message, args);
}
}
#endregion
#region Trace & Critical
public async Task LogTraceAsync(SettingKey<bool> channelKey, string message, params object[] args)
{
if (await ShouldLogAsync(channelKey, LogLevel.Trace))
{
_logger.LogTrace(message, args);
}
}
public async Task LogCriticalAsync(SettingKey<bool> channelKey, Exception? exception, string message, params object[] args)
{
if (await ShouldLogAsync(channelKey, LogLevel.Critical))
{
if (exception != null)
_logger.LogCritical(exception, message, args);
else
_logger.LogCritical(message, args);
}
}
#endregion
/// <summary>
/// Prüft, ob ein spezifischer Kanal und die aufrufende Klasse aktives Logging erlauben.
/// </summary>
private async Task<bool> ShouldLogAsync(SettingKey<bool> channelKey, LogLevel level)
{
ArgumentNullException.ThrowIfNull(channelKey);
try
{
return await _settingsService.GetSettingAsync(channelKey);
}
catch
{
return channelKey.DefaultValue;
}
}
}