using System.Text.Json; using Tiku.Application.Assets; using Tiku.Domain.Content; using Tiku.Domain.QuestionBanks; namespace Tiku.Application.PlatformAdmin; public sealed record PlatformQuestionBankFilter( Guid? QuestionBankId = null, Guid? ContentNodeId = null, string? Keyword = null, string? Type = null, int? Difficulty = null, string? Status = null, int Page = 1, int PageSize = 20); public sealed record PlatformQuestionBankItem( Guid Id, Guid? ContentEntryId, string Name, QuestionBankStatus Status, int NodeCount, int QuestionCount, JsonElement Metadata, DateTimeOffset CreatedAt, DateTimeOffset? UpdatedAt); public sealed record UpsertPlatformQuestionBankCommand( Guid? Id, string Name, JsonElement Metadata); public sealed record PlatformQuestionBankNodeItem( Guid Id, Guid QuestionBankId, Guid EntryId, Guid? ParentId, string? NodeKey, string Name, ContentNodeType NodeType, int Depth, int SortOrder, bool IsActive, bool IsSelectable, bool IsLeaf, int QuestionCount, JsonElement Metadata); public sealed record UpsertPlatformQuestionBankNodeCommand( Guid? Id, Guid QuestionBankId, Guid? ParentId, string? NodeKey, string Name, ContentNodeType NodeType, int SortOrder, bool IsSelectable, JsonElement Metadata); public sealed record BatchCreatePlatformQuestionBankNodesCommand( Guid QuestionBankId, Guid? ParentId, ContentNodeType NodeType, IReadOnlyCollection Names); public sealed record PlatformQuestionItem( Guid Id, Guid? VersionId, Guid QuestionBankId, Guid EntryId, Guid ContentNodeId, string? LegacyId, string Type, string? TypeLabel, int? Difficulty, JsonElement Tags, string? Content, JsonElement Options, int? CorrectOptionIndex, JsonElement CorrectOptionIndices, string? AnswerText, string? Explanation, JsonElement SubQuestions, string? CodeLang, string? CodeTemplate, string? MediaUrl, QuestionStatus Status, int VersionNo, DateTimeOffset CreatedAt, DateTimeOffset? UpdatedAt); public sealed record PlatformQuestionPage( IReadOnlyCollection Items, int Total, int Page, int PageSize); public sealed record UpsertPlatformQuestionCommand( Guid? Id, Guid QuestionBankId, Guid ContentNodeId, string? LegacyId, string? Type, string? TypeLabel, int? Difficulty, JsonElement Tags, string? Content, JsonElement Options, int? CorrectOptionIndex, JsonElement CorrectOptionIndices, string? AnswerText, string? Explanation, JsonElement SubQuestions, string? CodeLang, string? CodeTemplate, string? MediaUrl, string? Status, JsonElement ExamMarkers, string? SourceHash); public sealed record ArchivePlatformQuestionsCommand(IReadOnlyCollection QuestionIds); public sealed record PlatformQuestionImportCommand( Guid QuestionBankId, Guid? ContentNodeId, string Format, string? SourceName, JsonElement Payload); public sealed record PlatformQuestionImportResult( ContentImportJobDetail Detail, int CreatedNodeCount, int InsertedQuestionCount, int UpdatedQuestionCount, int SkippedQuestionCount); public interface IPlatformQuestionBankService { Task> GetBanksAsync(PlatformAdminActor actor, PlatformQuestionBankFilter filter, CancellationToken cancellationToken = default); Task UpsertBankAsync(PlatformAdminActor actor, UpsertPlatformQuestionBankCommand command, CancellationToken cancellationToken = default); Task ArchiveBankAsync(PlatformAdminActor actor, Guid bankId, CancellationToken cancellationToken = default); Task> GetNodesAsync(PlatformAdminActor actor, Guid bankId, CancellationToken cancellationToken = default); Task UpsertNodeAsync(PlatformAdminActor actor, UpsertPlatformQuestionBankNodeCommand command, CancellationToken cancellationToken = default); Task> BatchCreateNodesAsync(PlatformAdminActor actor, BatchCreatePlatformQuestionBankNodesCommand command, CancellationToken cancellationToken = default); Task ArchiveNodeAsync(PlatformAdminActor actor, Guid nodeId, CancellationToken cancellationToken = default); Task GetQuestionsAsync(PlatformAdminActor actor, PlatformQuestionBankFilter filter, CancellationToken cancellationToken = default); Task UpsertQuestionAsync(PlatformAdminActor actor, UpsertPlatformQuestionCommand command, CancellationToken cancellationToken = default); Task ArchiveQuestionsAsync(PlatformAdminActor actor, ArchivePlatformQuestionsCommand command, CancellationToken cancellationToken = default); Task PreviewImportAsync(PlatformAdminActor actor, PlatformQuestionImportCommand command, CancellationToken cancellationToken = default); Task ExecuteImportAsync(PlatformAdminActor actor, PlatformQuestionImportCommand command, CancellationToken cancellationToken = default); Task GetImportAsync(PlatformAdminActor actor, Guid jobId, CancellationToken cancellationToken = default); Task SignQuestionAssetUploadAsync(PlatformAdminActor actor, AssetUploadSignCommand command, CancellationToken cancellationToken = default); Task ConfirmQuestionAssetUploadAsync(PlatformAdminActor actor, AssetUploadConfirmCommand command, CancellationToken cancellationToken = default); }