using Microsoft.EntityFrameworkCore; using Tiku.Application.Catalog; using Tiku.Application.Content; namespace Tiku.Infrastructure.Content; internal sealed class OperationContentManagementService(DirectContentServiceDependencies dependencies) : DirectContentServiceBase(dependencies), IOperationContentManagementService { public async Task> GetOperationContentAsync( DirectContentActor actor, string kind, AdminLimitFilter filter, CancellationToken cancellationToken = default) { var items = NormalizeOperationKind(kind) switch { "banners" => (await jobsOperationsPersistence.Banners.AsNoTracking() .Where(item => item.TenantId == actor.TenantId) .Where(item => !filter.RegionId.HasValue || item.RegionId == filter.RegionId.Value) .Where(item => string.Equals(filter.Status, "all", StringComparison.OrdinalIgnoreCase) || item.IsActive) .OrderBy(item => item.SortOrder) .ThenByDescending(item => item.CreatedAt) .Take(ResolveLimit(filter.Limit)) .ToArrayAsync(cancellationToken)).Select(ToOperationItem).ToArray(), "faqs" => (await jobsOperationsPersistence.Faqs.AsNoTracking() .Where(item => item.TenantId == actor.TenantId) .Where(item => !filter.RegionId.HasValue || item.RegionId == filter.RegionId.Value) .Where(item => string.Equals(filter.Status, "all", StringComparison.OrdinalIgnoreCase) || item.IsActive) .OrderBy(item => item.SortOrder) .ThenBy(item => item.CreatedAt) .Take(ResolveLimit(filter.Limit)) .ToArrayAsync(cancellationToken)).Select(ToOperationItem).ToArray(), "announcements" => (await jobsOperationsPersistence.Announcements.AsNoTracking() .Where(item => item.TenantId == actor.TenantId) .Where(item => string.Equals(filter.Status, "all", StringComparison.OrdinalIgnoreCase) || item.IsActive) .OrderBy(item => item.SortOrder) .ThenByDescending(item => item.CreatedAt) .Take(ResolveLimit(filter.Limit)) .ToArrayAsync(cancellationToken)).Select(ToOperationItem).ToArray(), "exam-dates" => (await learningPersistence.ExamDates.AsNoTracking() .Where(item => item.TenantId == actor.TenantId) .Where(item => !filter.RegionId.HasValue || item.RegionId == filter.RegionId.Value) .Where(item => !filter.SchoolId.HasValue || item.SchoolId == filter.SchoolId.Value) .Where(item => string.Equals(filter.Status, "all", StringComparison.OrdinalIgnoreCase) || item.IsActive) .OrderBy(item => item.ExamAt == null) .ThenBy(item => item.ExamAt) .ThenBy(item => item.SortOrder) .Take(ResolveLimit(filter.Limit)) .ToArrayAsync(cancellationToken)).Select(ToOperationItem).ToArray(), _ => throw new ContentManagementException("Operation content kind is invalid.", "operation_content_kind_invalid") }; return new CatalogList(items); } public async Task> UpsertOperationContentAsync( DirectContentActor actor, string kind, OperationContentCommand command, CancellationToken cancellationToken = default) { var item = NormalizeOperationKind(kind) switch { "banners" => ToOperationItem(await UpsertBannerAsync(actor, command, cancellationToken)), "faqs" => ToOperationItem(await UpsertFaqAsync(actor, command, cancellationToken)), "announcements" => ToOperationItem(await UpsertAnnouncementAsync(actor, command, cancellationToken)), "exam-dates" => ToOperationItem(await UpsertExamDateAsync(actor, command, cancellationToken)), _ => throw new ContentManagementException("Operation content kind is invalid.", "operation_content_kind_invalid") }; return new ContentManagementResult(item); } }