Files
Nexus.Reader/src/NexusReader.UI.Shared/Services/KnowledgeCoordinator.cs
T
mjasin 3faecbb639 feat: implement structured logging in KnowledgeCoordinator [MN-01] (#10)
Reviewed-on: #10
Co-authored-by: Marek Jasiński <jasins.marek@gmail.com>
Co-committed-by: Marek Jasiński <jasins.marek@gmail.com>
2026-05-05 18:12:09 +00:00

138 lines
4.8 KiB
C#

using NexusReader.Application.Abstractions.Services;
using NexusReader.Application.Queries.Graph;
using NexusReader.Application.Queries.Quiz;
using NexusReader.UI.Shared.Services;
using NexusReader.Application.DTOs.AI;
using Microsoft.Extensions.Logging;
namespace NexusReader.UI.Shared.Services;
public sealed partial class KnowledgeCoordinator : IDisposable
{
private readonly IKnowledgeService _knowledgeService;
private readonly IKnowledgeGraphService _graphService;
private readonly IQuizStateService _quizService;
private readonly IPlatformService _platformService;
private readonly IReaderInteractionService _interactionService;
private readonly ILogger<KnowledgeCoordinator> _logger;
public event Action<GraphDataDto>? OnGraphUpdated;
public KnowledgeCoordinator(
IKnowledgeService knowledgeService,
IKnowledgeGraphService graphService,
IQuizStateService quizService,
IPlatformService platformService,
IReaderInteractionService interactionService,
ILogger<KnowledgeCoordinator> logger)
{
_knowledgeService = knowledgeService;
_graphService = graphService;
_quizService = quizService;
_platformService = platformService;
_interactionService = interactionService;
_logger = logger;
_interactionService.OnNodeSelected += HandleNodeSelected;
}
private void HandleNodeSelected(string nodeId)
{
_interactionService.RequestScrollToBlock(nodeId);
_interactionService.RequestHighlightBlock(nodeId);
}
public async Task ProcessFullPageAsync(string fullContent, string tenantId = "global")
{
if (string.IsNullOrWhiteSpace(fullContent)) return;
LogGeneratingGraph(tenantId);
_graphService.Clear();
_graphService.SetLoading(true);
try
{
var result = await _knowledgeService.GetGraphDataAsync(fullContent, tenantId);
if (result.IsSuccess)
{
var packet = result.Value;
if (packet.Graph != null)
{
_graphService.UpdateGraph(packet.Graph);
OnGraphUpdated?.Invoke(packet.Graph);
await _platformService.VibrateSuccessAsync();
}
}
}
catch (Exception ex)
{
LogGraphError(ex, tenantId);
}
}
public void OnBlockReached(string blockId, string content)
{
// Only update active node for "TU JESTEŚ" logic, do NOT trigger highlight here
_graphService.SetActiveNode(blockId);
}
public async Task<KnowledgePacket?> RequestSummaryAndQuizAsync(string content, string tenantId = "global")
{
_quizService.SetHydrating(true);
LogRequestingSummary(tenantId);
try
{
var result = await _knowledgeService.GetSummaryAndQuizAsync(content, tenantId);
if (result.IsSuccess)
{
var packet = result.Value;
var quizQuestions = packet.Quizzes
.Select(q => new QuizQuestionDto(q.Question, q.Options, q.CorrectIndex))
.ToList();
_quizService.SetQuiz(null, new QuizDto(quizQuestions));
await _platformService.VibrateSuccessAsync();
return packet;
}
LogSummaryWarning(tenantId);
}
catch (Exception ex)
{
LogSummaryError(ex, tenantId);
}
finally
{
_quizService.SetHydrating(false);
}
return null;
}
public void Clear()
{
_graphService.Clear();
_quizService.SetQuiz(null, null);
}
public void Dispose()
{
_interactionService.OnNodeSelected -= HandleNodeSelected;
}
[LoggerMessage(Level = LogLevel.Information, Message = "[KnowledgeCoordinator] Generating full page graph for tenant: {TenantId}")]
private partial void LogGeneratingGraph(string tenantId);
[LoggerMessage(Level = LogLevel.Error, Message = "[KnowledgeCoordinator] Error generating graph for tenant: {TenantId}")]
private partial void LogGraphError(Exception ex, string tenantId);
[LoggerMessage(Level = LogLevel.Information, Message = "[KnowledgeCoordinator] Requesting summary and quiz for tenant: {TenantId}")]
private partial void LogRequestingSummary(string tenantId);
[LoggerMessage(Level = LogLevel.Warning, Message = "[KnowledgeCoordinator] Failed to get summary and quiz for tenant: {TenantId}")]
private partial void LogSummaryWarning(string tenantId);
[LoggerMessage(Level = LogLevel.Error, Message = "[KnowledgeCoordinator] Error requesting summary and quiz for tenant: {TenantId}")]
private partial void LogSummaryError(Exception ex, string tenantId);
}