using System.Security.Claims; using FictionArchive.Service.UserNovelDataService.Models.Database; using FictionArchive.Service.UserNovelDataService.Models.DTOs; using FictionArchive.Service.UserNovelDataService.Services; using HotChocolate.Authorization; using HotChocolate.Types; using Microsoft.EntityFrameworkCore; namespace FictionArchive.Service.UserNovelDataService.GraphQL; public class Mutation { [Authorize] [Error] public async Task UpsertBookmark( UserNovelDataServiceDbContext dbContext, ClaimsPrincipal claimsPrincipal, UpsertBookmarkInput input) { var oAuthProviderId = claimsPrincipal.FindFirst(ClaimTypes.NameIdentifier)?.Value; if (string.IsNullOrEmpty(oAuthProviderId)) { throw new InvalidOperationException("Unable to determine current user identity"); } var user = await dbContext.Users .FirstOrDefaultAsync(u => u.OAuthProviderId == oAuthProviderId); if (user == null) { // Auto-create user if not exists user = new User { OAuthProviderId = oAuthProviderId }; dbContext.Users.Add(user); await dbContext.SaveChangesAsync(); } var existingBookmark = await dbContext.Bookmarks .FirstOrDefaultAsync(b => b.UserId == user.Id && b.ChapterId == input.ChapterId); if (existingBookmark != null) { // Update existing existingBookmark.Description = input.Description; } else { // Create new existingBookmark = new Bookmark { UserId = user.Id, NovelId = input.NovelId, ChapterId = input.ChapterId, Description = input.Description }; dbContext.Bookmarks.Add(existingBookmark); } await dbContext.SaveChangesAsync(); return new BookmarkPayload { Success = true, Bookmark = new BookmarkDto { Id = existingBookmark.Id, ChapterId = existingBookmark.ChapterId, NovelId = existingBookmark.NovelId, Description = existingBookmark.Description, CreatedTime = existingBookmark.CreatedTime } }; } [Authorize] [Error] public async Task RemoveBookmark( UserNovelDataServiceDbContext dbContext, ClaimsPrincipal claimsPrincipal, uint chapterId) { var oAuthProviderId = claimsPrincipal.FindFirst(ClaimTypes.NameIdentifier)?.Value; if (string.IsNullOrEmpty(oAuthProviderId)) { throw new InvalidOperationException("Unable to determine current user identity"); } var user = await dbContext.Users .AsNoTracking() .FirstOrDefaultAsync(u => u.OAuthProviderId == oAuthProviderId); if (user == null) { return new BookmarkPayload { Success = false }; } var bookmark = await dbContext.Bookmarks .FirstOrDefaultAsync(b => b.UserId == user.Id && b.ChapterId == chapterId); if (bookmark == null) { return new BookmarkPayload { Success = false }; } dbContext.Bookmarks.Remove(bookmark); await dbContext.SaveChangesAsync(); return new BookmarkPayload { Success = true }; } }