From 3c8c8c8707dc49c5e70c9882838cdff4f97d536c Mon Sep 17 00:00:00 2001 From: gamer147 Date: Fri, 30 Jan 2026 12:48:40 -0500 Subject: [PATCH 1/2] [FA-misc] Fix issues with novel imports --- .../FileUploadRequestCreatedConsumer.cs | 3 +- .../Sagas/NovelImportSagaTests.cs | 48 +++++++++++++++++-- .../Contracts/ImportNovelResult.cs | 3 ++ .../GraphQL/Mutation.cs | 2 +- .../Sagas/NovelImportSaga.cs | 3 +- .../Services/NovelUpdateService.cs | 11 +++-- .../Events/INovelMetadataImported.cs | 3 +- .../lib/components/ImportNovelModal.svelte | 8 +++- .../src/lib/graphql/__generated__/graphql.ts | 19 ++++---- .../lib/graphql/mutations/importNovel.graphql | 7 ++- 10 files changed, 86 insertions(+), 21 deletions(-) create mode 100644 FictionArchive.Service.NovelService/Contracts/ImportNovelResult.cs diff --git a/FictionArchive.Service.FileService/Consumers/FileUploadRequestCreatedConsumer.cs b/FictionArchive.Service.FileService/Consumers/FileUploadRequestCreatedConsumer.cs index 37fb0c5..590339e 100644 --- a/FictionArchive.Service.FileService/Consumers/FileUploadRequestCreatedConsumer.cs +++ b/FictionArchive.Service.FileService/Consumers/FileUploadRequestCreatedConsumer.cs @@ -38,7 +38,8 @@ public class FileUploadRequestCreatedConsumer : IConsumer(new NovelImportRequested(importId, "https://example.com/novel")); - await harness.Bus.Publish(new NovelMetadataImported(importId, 1, 0)); + await harness.Bus.Publish(new NovelMetadataImported(importId, 1, 0, false)); var sagaHarness = harness.GetSagaStateMachineHarness(); (await sagaHarness.Exists(importId, x => x.Completed)).HasValue.Should().BeTrue(); @@ -56,7 +56,7 @@ public class NovelImportSagaTests var importId = Guid.NewGuid(); await harness.Bus.Publish(new NovelImportRequested(importId, "https://example.com/novel")); - await harness.Bus.Publish(new NovelMetadataImported(importId, 1, 2)); + await harness.Bus.Publish(new NovelMetadataImported(importId, 1, 2, false)); var sagaHarness = harness.GetSagaStateMachineHarness(); (await sagaHarness.Exists(importId, x => x.Processing)).HasValue.Should().BeTrue(); @@ -71,7 +71,7 @@ public class NovelImportSagaTests var importId = Guid.NewGuid(); await harness.Bus.Publish(new NovelImportRequested(importId, "https://example.com/novel")); - await harness.Bus.Publish(new NovelMetadataImported(importId, 1, 2)); + await harness.Bus.Publish(new NovelMetadataImported(importId, 1, 2, false)); await harness.Bus.Publish(new ChapterPullCompleted(importId, 1, 1)); await harness.Bus.Publish(new ChapterPullCompleted(importId, 2, 0)); await harness.Bus.Publish(new FileUploadRequestStatusUpdate( @@ -81,6 +81,48 @@ public class NovelImportSagaTests (await sagaHarness.Exists(importId, x => x.Completed)).HasValue.Should().BeTrue(); } + [Fact] + public async Task Should_transition_to_processing_when_cover_image_queued_with_no_chapters() + { + await using var provider = CreateTestProvider(); + var harness = provider.GetRequiredService(); + await harness.Start(); + + var importId = Guid.NewGuid(); + await harness.Bus.Publish(new NovelImportRequested(importId, "https://example.com/novel")); + await harness.Bus.Publish(new NovelMetadataImported(importId, 1, 0, true)); + + var sagaHarness = harness.GetSagaStateMachineHarness(); + (await sagaHarness.Exists(importId, x => x.Processing)).HasValue.Should().BeTrue(); + } + + [Fact] + public async Task Should_complete_when_chapters_pulled_images_uploaded_and_cover_uploaded() + { + await using var provider = CreateTestProvider(); + var harness = provider.GetRequiredService(); + await harness.Start(); + + var importId = Guid.NewGuid(); + await harness.Bus.Publish(new NovelImportRequested(importId, "https://example.com/novel")); + await harness.Bus.Publish(new NovelMetadataImported(importId, 1, 1, true)); + await harness.Bus.Publish(new ChapterPullCompleted(importId, 1, 0)); + + var sagaHarness = harness.GetSagaStateMachineHarness(); + + // Should still be processing - cover image not yet uploaded + (await sagaHarness.Exists(importId, x => x.Processing)).HasValue.Should().BeTrue(); + + // Upload cover image + await harness.Bus.Publish(new FileUploadRequestStatusUpdate( + importId, Guid.NewGuid(), RequestStatus.Success, "https://cdn.example.com/cover.jpg", null)); + + (await sagaHarness.Exists(importId, x => x.Completed)).HasValue.Should().BeTrue(); + + (await harness.Published.Any(x => + x.Context.Message.ImportId == importId && x.Context.Message.Success)).Should().BeTrue(); + } + private ServiceProvider CreateTestProvider() { return new ServiceCollection() diff --git a/FictionArchive.Service.NovelService/Contracts/ImportNovelResult.cs b/FictionArchive.Service.NovelService/Contracts/ImportNovelResult.cs new file mode 100644 index 0000000..a70a8de --- /dev/null +++ b/FictionArchive.Service.NovelService/Contracts/ImportNovelResult.cs @@ -0,0 +1,3 @@ +namespace FictionArchive.Service.NovelService.Contracts; + +public record ImportNovelResult(Guid ImportId, string NovelUrl); diff --git a/FictionArchive.Service.NovelService/GraphQL/Mutation.cs b/FictionArchive.Service.NovelService/GraphQL/Mutation.cs index 16ae407..95e669a 100644 --- a/FictionArchive.Service.NovelService/GraphQL/Mutation.cs +++ b/FictionArchive.Service.NovelService/GraphQL/Mutation.cs @@ -16,7 +16,7 @@ public class Mutation { [Error] [Authorize] - public async Task ImportNovel(string novelUrl, NovelUpdateService service) + public async Task ImportNovel(string novelUrl, NovelUpdateService service) { return await service.QueueNovelImport(novelUrl); } diff --git a/FictionArchive.Service.NovelService/Sagas/NovelImportSaga.cs b/FictionArchive.Service.NovelService/Sagas/NovelImportSaga.cs index dedeae4..7ab4358 100644 --- a/FictionArchive.Service.NovelService/Sagas/NovelImportSaga.cs +++ b/FictionArchive.Service.NovelService/Sagas/NovelImportSaga.cs @@ -57,9 +57,10 @@ public class NovelImportSaga : MassTransitStateMachine { ctx.Saga.NovelId = ctx.Message.NovelId; ctx.Saga.ExpectedChapters = ctx.Message.ChaptersPendingPull; + ctx.Saga.ExpectedImages += ctx.Message.CoverImageQueued ? 1 : 0; }) .IfElse( - ctx => ctx.Saga.ExpectedChapters == 0, + ctx => ctx.Saga.ExpectedChapters == 0 && !ctx.Message.CoverImageQueued, thenBinder => thenBinder .Then(ctx => ctx.Saga.CompletedAt = _clock.GetCurrentInstant()) .TransitionTo(Completed) diff --git a/FictionArchive.Service.NovelService/Services/NovelUpdateService.cs b/FictionArchive.Service.NovelService/Services/NovelUpdateService.cs index ed01566..8f438d5 100644 --- a/FictionArchive.Service.NovelService/Services/NovelUpdateService.cs +++ b/FictionArchive.Service.NovelService/Services/NovelUpdateService.cs @@ -427,15 +427,18 @@ public class NovelUpdateService .Where(c => c.Body?.Texts == null || !c.Body.Texts.Any()) .ToList(); + var hasCoverToUpload = shouldPublishCoverEvent && novel.CoverImage != null && metadata.CoverImage != null; + // Publish metadata imported event for saga await _publishEndpoint.Publish(new NovelMetadataImported( importId, novel.Id, - chaptersNeedingPull.Count + chaptersNeedingPull.Count, + hasCoverToUpload )); // Publish cover image event if needed - if (shouldPublishCoverEvent && novel.CoverImage != null && metadata.CoverImage != null) + if (hasCoverToUpload) { await _publishEndpoint.Publish(new FileUploadRequestCreated( importId, @@ -568,7 +571,7 @@ public class NovelUpdateService await _dbContext.SaveChangesAsync(); } - public async Task QueueNovelImport(string novelUrl) + public async Task QueueNovelImport(string novelUrl) { var importId = Guid.NewGuid(); var activeImport = new ActiveImport @@ -590,7 +593,7 @@ public class NovelUpdateService var importNovelRequestEvent = new NovelImportRequested(importId, novelUrl); await _publishEndpoint.Publish(importNovelRequestEvent); - return importNovelRequestEvent; + return new ImportNovelResult(importId, novelUrl); } public async Task QueueChapterPull(Guid importId, uint novelId, uint volumeId, uint chapterOrder) diff --git a/FictionArchive.Service.Shared/Contracts/Events/INovelMetadataImported.cs b/FictionArchive.Service.Shared/Contracts/Events/INovelMetadataImported.cs index 5f05805..d79a3af 100644 --- a/FictionArchive.Service.Shared/Contracts/Events/INovelMetadataImported.cs +++ b/FictionArchive.Service.Shared/Contracts/Events/INovelMetadataImported.cs @@ -5,6 +5,7 @@ public interface INovelMetadataImported Guid ImportId { get; } uint NovelId { get; } int ChaptersPendingPull { get; } + bool CoverImageQueued { get; } } -public record NovelMetadataImported(Guid ImportId, uint NovelId, int ChaptersPendingPull) : INovelMetadataImported; +public record NovelMetadataImported(Guid ImportId, uint NovelId, int ChaptersPendingPull, bool CoverImageQueued) : INovelMetadataImported; diff --git a/fictionarchive-web-astro/src/lib/components/ImportNovelModal.svelte b/fictionarchive-web-astro/src/lib/components/ImportNovelModal.svelte index f1c1ca5..cc83ea3 100644 --- a/fictionarchive-web-astro/src/lib/components/ImportNovelModal.svelte +++ b/fictionarchive-web-astro/src/lib/components/ImportNovelModal.svelte @@ -39,7 +39,13 @@ return; } - if (result.data?.importNovel?.novelUpdateRequestedEvent) { + const mutationErrors = result.data?.importNovel?.errors; + if (mutationErrors && mutationErrors.length > 0) { + error = mutationErrors[0].message; + return; + } + + if (result.data?.importNovel?.importNovelResult) { success = true; setTimeout(() => { handleClose(); diff --git a/fictionarchive-web-astro/src/lib/graphql/__generated__/graphql.ts b/fictionarchive-web-astro/src/lib/graphql/__generated__/graphql.ts index 476f1c1..4ba2090 100644 --- a/fictionarchive-web-astro/src/lib/graphql/__generated__/graphql.ts +++ b/fictionarchive-web-astro/src/lib/graphql/__generated__/graphql.ts @@ -200,12 +200,20 @@ export type ImageDtoSortInput = { newPath?: InputMaybe; }; +export type ImportNovelError = InvalidOperationError; + export type ImportNovelInput = { novelUrl: Scalars['String']['input']; }; export type ImportNovelPayload = { - novelImportRequested: Maybe; + errors: Maybe>; + importNovelResult: Maybe; +}; + +export type ImportNovelResult = { + importId: Scalars['UUID']['output']; + novelUrl: Scalars['String']['output']; }; export type InstantFilterInput = { @@ -463,11 +471,6 @@ export type NovelDtoSortInput = { url?: InputMaybe; }; -export type NovelImportRequested = { - importId: Scalars['UUID']['output']; - novelUrl: Scalars['String']['output']; -}; - export const NovelStatus = { Abandoned: 'ABANDONED', Completed: 'COMPLETED', @@ -1013,7 +1016,7 @@ export type ImportNovelMutationVariables = Exact<{ }>; -export type ImportNovelMutation = { importNovel: { novelImportRequested: { importId: any, novelUrl: string } | null } }; +export type ImportNovelMutation = { importNovel: { importNovelResult: { importId: any, novelUrl: string } | null, errors: Array<{ message: string }> | null } }; export type InviteUserMutationVariables = Exact<{ input: InviteUserInput; @@ -1117,7 +1120,7 @@ export const AddToReadingListDocument = {"kind":"Document","definitions":[{"kind export const CreateReadingListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateReadingList"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"CreateReadingListInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createReadingList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"readingListPayload"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"success"}},{"kind":"Field","name":{"kind":"Name","value":"readingList"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"itemCount"}},{"kind":"Field","name":{"kind":"Name","value":"createdTime"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"errors"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const DeleteNovelDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteNovel"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"DeleteNovelInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteNovel"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"boolean"}},{"kind":"Field","name":{"kind":"Name","value":"errors"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const DeleteReadingListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteReadingList"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"DeleteReadingListInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteReadingList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"success"}},{"kind":"Field","name":{"kind":"Name","value":"errors"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]}}]} as unknown as DocumentNode; -export const ImportNovelDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"ImportNovel"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ImportNovelInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"importNovel"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"novelImportRequested"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"importId"}},{"kind":"Field","name":{"kind":"Name","value":"novelUrl"}}]}}]}}]}}]} as unknown as DocumentNode; +export const ImportNovelDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"ImportNovel"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ImportNovelInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"importNovel"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"importNovelResult"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"importId"}},{"kind":"Field","name":{"kind":"Name","value":"novelUrl"}}]}},{"kind":"Field","name":{"kind":"Name","value":"errors"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"InvalidOperationError"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const InviteUserDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"InviteUser"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"InviteUserInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"inviteUser"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userDto"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"username"}},{"kind":"Field","name":{"kind":"Name","value":"email"}}]}},{"kind":"Field","name":{"kind":"Name","value":"errors"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"InvalidOperationError"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const RemoveBookmarkDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"RemoveBookmark"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"RemoveBookmarkInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"removeBookmark"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"bookmarkPayload"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"success"}}]}},{"kind":"Field","name":{"kind":"Name","value":"errors"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const RemoveFromReadingListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"RemoveFromReadingList"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"RemoveFromReadingListInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"removeFromReadingList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"readingListPayload"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"success"}},{"kind":"Field","name":{"kind":"Name","value":"readingList"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"itemCount"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"errors"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Error"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]}}]}}]} as unknown as DocumentNode; diff --git a/fictionarchive-web-astro/src/lib/graphql/mutations/importNovel.graphql b/fictionarchive-web-astro/src/lib/graphql/mutations/importNovel.graphql index 1d177dd..8163ef9 100644 --- a/fictionarchive-web-astro/src/lib/graphql/mutations/importNovel.graphql +++ b/fictionarchive-web-astro/src/lib/graphql/mutations/importNovel.graphql @@ -1,8 +1,13 @@ mutation ImportNovel($input: ImportNovelInput!) { importNovel(input: $input) { - novelImportRequested { + importNovelResult { importId novelUrl } + errors { + ... on InvalidOperationError { + message + } + } } } -- 2.49.1 From a6242fdb2a4d37c0e707d424e6d0cb6d8c6f3fbb Mon Sep 17 00:00:00 2001 From: gamer147 Date: Fri, 30 Jan 2026 12:53:10 -0500 Subject: [PATCH 2/2] [FA-misc] Fix release.yml --- .gitea/workflows/release.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index 44d4d07..3ee7cd4 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -25,8 +25,6 @@ jobs: dockerfile: FictionArchive.Service.FileService/Dockerfile - name: scheduler-service dockerfile: FictionArchive.Service.SchedulerService/Dockerfile - - name: authentication-service - dockerfile: FictionArchive.Service.AuthenticationService/Dockerfile - name: usernoveldata-service dockerfile: FictionArchive.Service.UserNovelDataService/Dockerfile steps: -- 2.49.1