< Summary

Information
Class: Chronicis.Api.Services.DashboardReadService
Assembly: Chronicis.Api
File(s): /home/runner/work/chronicis/chronicis/src/Chronicis.Api/Services/DashboardReadService.cs
Line coverage
100%
Covered lines: 3
Uncovered lines: 0
Coverable lines: 3
Total lines: 145
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%

File(s)

/home/runner/work/chronicis/chronicis/src/Chronicis.Api/Services/DashboardReadService.cs

#LineLine coverage
 1using Chronicis.Api.Data;
 2using Chronicis.Shared.DTOs;
 3using Chronicis.Shared.Enums;
 4using Microsoft.EntityFrameworkCore;
 5
 6namespace Chronicis.Api.Services;
 7
 8public sealed class DashboardReadService : IDashboardReadService
 9{
 10    private readonly ChronicisDbContext _context;
 11    private readonly IPromptService _promptService;
 12
 13    public DashboardReadService(ChronicisDbContext context, IPromptService promptService)
 14    {
 215        _context = context;
 216        _promptService = promptService;
 217    }
 18
 19    public async Task<DashboardDto> GetDashboardAsync(Guid userId, string userDisplayName)
 20    {
 21        var worldIds = await _context.WorldMembers
 22            .Where(wm => wm.UserId == userId)
 23            .Select(wm => wm.WorldId)
 24            .ToListAsync();
 25
 26        var worlds = await _context.Worlds
 27            .Where(w => worldIds.Contains(w.Id))
 28            .Include(w => w.Campaigns)
 29                .ThenInclude(c => c.Arcs)
 30            .Include(w => w.Articles)
 31            .OrderBy(w => w.Name)
 32            .ToListAsync();
 33
 34        var claimedCharacters = await _context.Articles
 35            .Where(a => a.PlayerId == userId && a.Type == ArticleType.Character)
 36            .Where(a => a.WorldId.HasValue && worldIds.Contains(a.WorldId.Value))
 37            .Select(a => new ClaimedCharacterDto
 38            {
 39                Id = a.Id,
 40                Title = a.Title ?? "Unnamed Character",
 41                IconEmoji = a.IconEmoji,
 42                WorldId = a.WorldId!.Value,
 43                WorldName = a.World != null ? a.World.Name : "Unknown World",
 44                ModifiedAt = a.ModifiedAt,
 45                CreatedAt = a.CreatedAt
 46            })
 47            .ToListAsync();
 48
 49        var dashboardWorlds = new List<DashboardWorldDto>();
 50        foreach (var world in worlds)
 51        {
 52            var dashboardWorld = new DashboardWorldDto
 53            {
 54                Id = world.Id,
 55                Name = world.Name,
 56                Slug = world.Slug,
 57                Description = world.Description,
 58                CreatedAt = world.CreatedAt,
 59                ArticleCount = world.Articles?.Count ?? 0,
 60                Campaigns = new List<DashboardCampaignDto>(),
 61                MyCharacters = new List<DashboardCharacterDto>()
 62            };
 63
 64            var worldRoot = world.Articles?.FirstOrDefault(a => a.ParentId == null && a.Type == ArticleType.WikiArticle)
 65            dashboardWorld.WorldRootArticleId = worldRoot?.Id;
 66
 67            if (world.Campaigns != null)
 68            {
 69                foreach (var campaign in world.Campaigns.OrderByDescending(c => c.IsActive).ThenBy(c => c.Name))
 70                {
 71                    var sessionCount = await _context.Sessions
 72                        .AsNoTracking()
 73                        .CountAsync(s => s.Arc.CampaignId == campaign.Id);
 74
 75                    var dashboardCampaign = new DashboardCampaignDto
 76                    {
 77                        Id = campaign.Id,
 78                        Name = campaign.Name,
 79                        Description = campaign.Description,
 80                        CreatedAt = campaign.CreatedAt,
 81                        StartedAt = campaign.StartedAt,
 82                        IsActive = campaign.IsActive,
 83                        SessionCount = sessionCount,
 84                        ArcCount = campaign.Arcs?.Count ?? 0
 85                    };
 86
 87                    var activeArc = campaign.Arcs?
 88                        .Where(a => a.IsActive)
 89                        .OrderByDescending(a => a.SortOrder)
 90                        .FirstOrDefault();
 91
 92                    if (activeArc != null)
 93                    {
 94                        var arcSessionCount = await _context.Sessions
 95                            .AsNoTracking()
 96                            .CountAsync(s => s.ArcId == activeArc.Id);
 97
 98                        var latestSession = await _context.Sessions
 99                            .AsNoTracking()
 100                            .Where(s => s.ArcId == activeArc.Id)
 101                            .OrderByDescending(s => s.SessionDate ?? s.CreatedAt)
 102                            .FirstOrDefaultAsync();
 103
 104                        dashboardCampaign.CurrentArc = new DashboardArcDto
 105                        {
 106                            Id = activeArc.Id,
 107                            Name = activeArc.Name,
 108                            Description = activeArc.Description,
 109                            SessionCount = arcSessionCount,
 110                            LatestSessionDate = latestSession?.SessionDate ?? latestSession?.CreatedAt
 111                        };
 112                    }
 113
 114                    dashboardWorld.Campaigns.Add(dashboardCampaign);
 115                }
 116            }
 117
 118            dashboardWorld.MyCharacters = claimedCharacters
 119                .Where(c => c.WorldId == world.Id)
 120                .Select(c => new DashboardCharacterDto
 121                {
 122                    Id = c.Id,
 123                    Title = c.Title,
 124                    IconEmoji = c.IconEmoji,
 125                    ModifiedAt = c.ModifiedAt,
 126                    CreatedAt = c.CreatedAt
 127                })
 128                .ToList();
 129
 130            dashboardWorlds.Add(dashboardWorld);
 131        }
 132
 133        var dashboard = new DashboardDto
 134        {
 135            UserDisplayName = userDisplayName,
 136            Worlds = dashboardWorlds,
 137            ClaimedCharacters = claimedCharacters,
 138            Prompts = new List<PromptDto>()
 139        };
 140
 141        dashboard.Prompts = _promptService.GeneratePrompts(dashboard);
 142        return dashboard;
 143    }
 144}
 145