public class FeedJourneyService : IFeedJourneyService
{
private readonly IFeedService _feedService;
private readonly MediaService _mediaService;
private readonly EventsService _eventsService;
private readonly IFeedResponseTransformer _transformer;
private readonly CurrentUserAccessor _currentUserAccessor;
public async Task<TerritoryFeedJourneyResponse> GetTerritoryFeedAsync(
Guid territoryId,
Guid? userId,
int pageNumber,
int pageSize,
CancellationToken cancellationToken)
{
// 1. Buscar posts (paginado)
var pagination = new PaginationParameters(pageNumber, pageSize);
var pagedResult = await _feedService.ListForTerritoryPagedAsync(
territoryId,
userId,
null,
null,
pagination,
false,
cancellationToken);
// 2. Buscar contadores (batch)
var postIds = pagedResult.Items.Select(p => p.Id).ToList();
var counts = await _feedService.GetCountsByPostIdsAsync(postIds, cancellationToken);
// 3. Buscar mídias (batch)
var mediaUrls = await LoadMediaUrlsBatchAsync(postIds, cancellationToken);
// 4. Buscar eventos relacionados (batch)
var eventLookup = await LoadEventSummariesAsync(pagedResult.Items, cancellationToken);
// 5. Buscar interações do usuário (batch)
var userInteractions = userId.HasValue
? await LoadUserInteractionsAsync(userId.Value, postIds, cancellationToken)
: new Dictionary<Guid, UserInteractions>();
// 6. Transformar para formato de jornada
return _transformer.Transform(
pagedResult.Items,
counts,
mediaUrls,
eventLookup,
userInteractions,
pagedResult);
}
public async Task<CreatePostJourneyResponse> CreatePostAsync(
Guid territoryId,
Guid userId,
CreatePostJourneyRequest request,
CancellationToken cancellationToken)
{
// 1. Upload de mídias (se houver)
var mediaIds = new List<Guid>();
if (request.MediaFiles?.Any() == true)
{
foreach (var mediaFile in request.MediaFiles)
{
var uploadResult = await _mediaService.UploadMediaAsync(
territoryId,
userId,
mediaFile,
MediaOwnerType.Post,
null,
cancellationToken);
if (uploadResult.IsSuccess && uploadResult.Value is not null)
{
mediaIds.Add(uploadResult.Value.Id);
}
}
}
// 2. Criar post
var postResult = await _feedService.CreatePostAsync(
territoryId,
userId,
request.Title,
request.Content,
request.Type,
request.Visibility,
PostStatus.Published,
request.MapEntityId,
request.GeoAnchors,
request.AssetIds,
mediaIds,
cancellationToken,
request.Tags);
if (!postResult.IsSuccess || postResult.Value is null)
{
return new CreatePostJourneyResponse
{
Success = false,
Error = postResult.Error
};
}
// 3. Buscar post completo formatado
var post = postResult.Value;
var mediaUrls = await LoadMediaUrlsForPostAsync(post.Id, cancellationToken);
// 4. Buscar sugestões
var suggestions = await GetPostSuggestionsAsync(territoryId, post, cancellationToken);
return new CreatePostJourneyResponse
{
Success = true,
Post = TransformPostForUI(post, mediaUrls),
Suggestions = suggestions
};
}
}