diff --git a/src/NexusReader.Application/Abstractions/Services/IEpubService.cs b/src/NexusReader.Application/Abstractions/Services/IEpubService.cs index d6ff680..188988c 100644 --- a/src/NexusReader.Application/Abstractions/Services/IEpubService.cs +++ b/src/NexusReader.Application/Abstractions/Services/IEpubService.cs @@ -5,5 +5,5 @@ namespace NexusReader.Application.Abstractions.Services; public interface IEpubService { - Task> GetEpubContentAsync(int chapterIndex); + Task> GetEpubContentAsync(int chapterIndex, string? userId = null); } diff --git a/src/NexusReader.Application/Queries/Reader/GetReaderPageQuery.cs b/src/NexusReader.Application/Queries/Reader/GetReaderPageQuery.cs index 132a3f4..4cc2e9e 100644 --- a/src/NexusReader.Application/Queries/Reader/GetReaderPageQuery.cs +++ b/src/NexusReader.Application/Queries/Reader/GetReaderPageQuery.cs @@ -2,4 +2,4 @@ using NexusReader.Application.Abstractions.Messaging; namespace NexusReader.Application.Queries.Reader; -public record GetReaderPageQuery(int ChapterIndex = 0) : IQuery; +public record GetReaderPageQuery(int ChapterIndex = 0, string? UserId = null) : IQuery; diff --git a/src/NexusReader.Application/Queries/Reader/GetReaderPageQueryHandler.cs b/src/NexusReader.Application/Queries/Reader/GetReaderPageQueryHandler.cs index d12cd5c..a7fb52d 100644 --- a/src/NexusReader.Application/Queries/Reader/GetReaderPageQueryHandler.cs +++ b/src/NexusReader.Application/Queries/Reader/GetReaderPageQueryHandler.cs @@ -15,6 +15,6 @@ internal sealed class GetReaderPageQueryHandler : IQueryHandler> Handle(GetReaderPageQuery request, CancellationToken cancellationToken) { - return await _epubService.GetEpubContentAsync(request.ChapterIndex); + return await _epubService.GetEpubContentAsync(request.ChapterIndex, request.UserId); } } diff --git a/src/NexusReader.Infrastructure/Services/EpubService.cs b/src/NexusReader.Infrastructure/Services/EpubService.cs index d3b94f3..b516625 100644 --- a/src/NexusReader.Infrastructure/Services/EpubService.cs +++ b/src/NexusReader.Infrastructure/Services/EpubService.cs @@ -21,7 +21,7 @@ public class EpubService : IEpubService _dbContextFactory = dbContextFactory; } - public async Task> GetEpubContentAsync(int chapterIndex) + public async Task> GetEpubContentAsync(int chapterIndex, string? userId = null) { try { @@ -109,14 +109,29 @@ public class EpubService : IEpubService blocks.Add(CreateAiTrigger($"trigger-{blockCounter++}")); } - // Find the EbookId from DB for this file + // Find the EbookId from DB for this file AND this user using var context = await _dbContextFactory.CreateDbContextAsync(); - var ebookId = await context.Ebooks - .Where(e => e.FilePath.Contains("book.epub")) - .Select(e => e.Id) + var ebook = await context.Ebooks + .Where(e => e.FilePath.Contains("book.epub") && (userId == null || e.UserId == userId)) .FirstOrDefaultAsync(); - return Result.Ok(new ReaderPageViewModel(blocks, chapterIndex, readingOrder.Count, chapterTitle, ebookId)); + // Auto-provision if not found for this user (convenience for dev) + if (ebook == null && !string.IsNullOrEmpty(userId)) + { + var author = await context.Authors.FirstOrDefaultAsync() ?? new Author { Name = "Unknown Author" }; + ebook = new Ebook + { + Title = "Lives of the Most Excellent Painters, Sculptors, and Architects", + FilePath = "wwwroot/assets/book.epub", + UserId = userId, + Author = author, + TenantId = "global" + }; + context.Ebooks.Add(ebook); + await context.SaveChangesAsync(); + } + + return Result.Ok(new ReaderPageViewModel(blocks, chapterIndex, readingOrder.Count, chapterTitle, ebook?.Id ?? Guid.Empty)); } catch (Exception ex) { diff --git a/src/NexusReader.UI.Shared/Components/Organisms/ReaderCanvas.razor b/src/NexusReader.UI.Shared/Components/Organisms/ReaderCanvas.razor index 6bc34be..280f8ce 100644 --- a/src/NexusReader.UI.Shared/Components/Organisms/ReaderCanvas.razor +++ b/src/NexusReader.UI.Shared/Components/Organisms/ReaderCanvas.razor @@ -11,6 +11,8 @@ @inject KnowledgeCoordinator Coordinator @inject IReaderInteractionService InteractionService @inject ISyncService SyncService +@using Microsoft.AspNetCore.Components.Authorization +@inject AuthenticationStateProvider AuthStateProvider
@if (ViewModel == null) @@ -190,7 +192,10 @@ ViewModel = null; StatusMessage = "Fetching content..."; - var result = await Mediator.Send(new GetReaderPageQuery(index)); + var authState = await AuthStateProvider.GetAuthenticationStateAsync(); + var userId = authState.User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value; + + var result = await Mediator.Send(new GetReaderPageQuery(index, userId)); if (result.IsSuccess) { ViewModel = result.Value; diff --git a/src/NexusReader.Web.Client/Services/WasmEpubService.cs b/src/NexusReader.Web.Client/Services/WasmEpubService.cs index 20ef2b6..00431ed 100644 --- a/src/NexusReader.Web.Client/Services/WasmEpubService.cs +++ b/src/NexusReader.Web.Client/Services/WasmEpubService.cs @@ -14,7 +14,7 @@ public class WasmEpubService : IEpubService _httpClient = httpClient; } - public async Task> GetEpubContentAsync(int chapterIndex) + public async Task> GetEpubContentAsync(int chapterIndex, string? userId = null) { try { diff --git a/src/NexusReader.Web.New/Program.cs b/src/NexusReader.Web.New/Program.cs index b8c3d4d..76918f0 100644 --- a/src/NexusReader.Web.New/Program.cs +++ b/src/NexusReader.Web.New/Program.cs @@ -226,9 +226,11 @@ app.MapStaticAssets(); app.MapHub("/synchub"); // API endpoint for WASM client to fetch EPUB content -app.MapGet("/api/epub/{index}", async (int index, IEpubService epubService) => +app.MapGet("/api/epub/{index}", async (int index, IEpubService epubService, ClaimsPrincipal user) => { - var result = await epubService.GetEpubContentAsync(index); + var userId = user.FindFirstValue(ClaimTypes.NameIdentifier); + var result = await epubService.GetEpubContentAsync(index, userId); + if (result.IsSuccess) return Results.Ok(result.Value); var errorMsg = result.Errors.Count > 0 ? result.Errors[0].Message : "Unknown server error";