feat(intelligence): implement Global AI Q&A screen and paywall blocker
- Implemented standard empty and active chat conversation states for the `/intelligence` page - Created interactive `AiResponseRenderer` with AOT-compliant sentence splitting and payment gateway simulation - Added scoped `LibraryStateService` to synchronize book ownership and updates across the application - Obfuscated paywalled content in DOM to prevent inspection bypass - Fixed local port connection mismatch by updating API configurations to use port 5104
This commit is contained in:
@@ -57,6 +57,7 @@ builder.Services.AddScoped<IReaderNavigationService, ReaderNavigationService>();
|
||||
builder.Services.AddScoped<IKnowledgeGraphService, KnowledgeGraphService>();
|
||||
builder.Services.AddScoped<IReaderInteractionService, ReaderInteractionService>();
|
||||
builder.Services.AddScoped<IReaderStateService, ReaderStateService>();
|
||||
builder.Services.AddScoped<ILibraryStateService, LibraryStateService>();
|
||||
builder.Services.AddScoped<KnowledgeCoordinator>();
|
||||
builder.Services.AddScoped<ISyncService, SyncService>();
|
||||
|
||||
@@ -454,6 +455,48 @@ app.MapGet("/api/library/books", async (ClaimsPrincipal user, IMediator mediator
|
||||
return Results.BadRequest(errorMsg);
|
||||
}).RequireAuthorization();
|
||||
|
||||
app.MapPost("/api/library/purchase", async (
|
||||
ClaimsPrincipal user,
|
||||
[FromBody] PurchaseBookRequest request,
|
||||
IDbContextFactory<AppDbContext> dbContextFactory) =>
|
||||
{
|
||||
var userId = user.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||
if (string.IsNullOrEmpty(userId)) return Results.Unauthorized();
|
||||
|
||||
using var dbContext = await dbContextFactory.CreateDbContextAsync();
|
||||
|
||||
// Find or create author
|
||||
var authorName = "Nexus Architect";
|
||||
var author = await dbContext.Authors.FirstOrDefaultAsync(a => a.Name == authorName);
|
||||
if (author == null)
|
||||
{
|
||||
author = new Author { Name = authorName };
|
||||
dbContext.Authors.Add(author);
|
||||
await dbContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
// Check if the book already exists for the user
|
||||
var bookExists = await dbContext.Ebooks.AnyAsync(e => e.UserId == userId && e.Title == request.Title);
|
||||
if (!bookExists)
|
||||
{
|
||||
var newBook = new Ebook
|
||||
{
|
||||
Title = request.Title,
|
||||
AuthorId = author.Id,
|
||||
UserId = userId,
|
||||
FilePath = "wwwroot/assets/book.epub",
|
||||
AddedDate = DateTime.UtcNow,
|
||||
Progress = 0,
|
||||
Description = "Zaawansowany kurs budowania skalowalnych SaaS z Native AOT, CQRS, MediatR, FluentResults i izolowanym systemem stylów Blazor CSS.",
|
||||
IsReadyForReading = true
|
||||
};
|
||||
dbContext.Ebooks.Add(newBook);
|
||||
await dbContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
return Results.Ok();
|
||||
}).RequireAuthorization();
|
||||
|
||||
app.MapGet("/api/book/{bookId:guid}/concepts-map", async (
|
||||
Guid bookId,
|
||||
ClaimsPrincipal user,
|
||||
@@ -729,3 +772,4 @@ public record KnowledgeRequest(string Text, Guid? EbookId = null);
|
||||
public record GroundednessRequest(string Answer, string Context);
|
||||
public record SemanticSearchRequest(string QueryText, int Limit = 5);
|
||||
public record AskQuestionRequest(string Question, Guid? EbookId = null, int Limit = 5);
|
||||
public record PurchaseBookRequest(string Title);
|
||||
|
||||
Reference in New Issue
Block a user