using AutoMapper; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http.HttpResults; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using OnlyPrompt.Backend.ApiModels.Prompt; using OnlyPrompt.Backend.Database; using OnlyPrompt.Backend.Utils; using System.ComponentModel.DataAnnotations; namespace OnlyPrompt.Backend.Controllers { [ApiController] [Route("api/v1/feed")] [Authorize(Roles = ModelConstants.UserRole)] public class FeedController : BaseController { public FeedController(OnlyPromptContext db, IMapper mapper) : base(db, mapper) { } [HttpGet] public async Task GetFeedAsync( [Range(0, double.MaxValue)][FromQuery]int offset = 0, [Range(1, 100)][FromQuery]int limit = 20, [FromQuery]FeedSortType sortBy = FeedSortType.Date, [FromQuery]bool ascending = false, [FromQuery]Identifier? category = null, [FromQuery]DateTime? fromDate = null, [FromQuery]DateTime? toDate = null ) { var userId = User.GetUserId(); var query = _db.Prompts .Where( x => x.Creator.Subscribers.Any(s => s.SubscriberId == userId) && x.CreatorId != userId ); if (category.HasValue) query = query.Where(x => category.Value.Id.HasValue ? x.CategoryId == category.Value.Id.Value : x.Category.Slug == category.Value.Slug); if (fromDate.HasValue) query = query.Where(x => x.UpdatedAt >= fromDate.Value); if (toDate.HasValue) query = query.Where(x => x.UpdatedAt <= toDate.Value); query = sortBy switch { FeedSortType.Date => query.OrderBy(x => x.UpdatedAt, ascending), FeedSortType.Rating => query.OrderBy(x => x.Reviews.Average(r => (double?)r.Rating) ?? 2.5, ascending), _ => query }; var prompts = await query .Skip(offset) .Take(limit) .Select(x => new ApiMinimalPrompt( x.Id, x.Title, x.UpdatedAt, x.CreatorId, x.Creator.Profile.DisplayName, x.SubscriptionTier.Level, x.SubscriptionTier.Name, x.Reviews.Average(r => (double?)r.Rating), x.SubscriptionTier == null || x.Creator.Subscribers.Any(s => s.SubscriberId == userId && x.SubscriptionTier.Level < s.SubscriptionTier.Level) )).ToArrayAsync(); return prompts; } } }