< 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: 146
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                        Slug = campaign.Slug,
 80                        Description = campaign.Description,
 81                        CreatedAt = campaign.CreatedAt,
 82                        StartedAt = campaign.StartedAt,
 83                        IsActive = campaign.IsActive,
 84                        SessionCount = sessionCount,
 85                        ArcCount = campaign.Arcs?.Count ?? 0
 86                    };
 87
 88                    var activeArc = campaign.Arcs?
 89                        .Where(a => a.IsActive)
 90                        .OrderByDescending(a => a.SortOrder)
 91                        .FirstOrDefault();
 92
 93                    if (activeArc != null)
 94                    {
 95                        var arcSessionCount = await _context.Sessions
 96                            .AsNoTracking()
 97                            .CountAsync(s => s.ArcId == activeArc.Id);
 98
 99                        var latestSession = await _context.Sessions
 100                            .AsNoTracking()
 101                            .Where(s => s.ArcId == activeArc.Id)
 102                            .OrderByDescending(s => s.SessionDate ?? s.CreatedAt)
 103                            .FirstOrDefaultAsync();
 104
 105                        dashboardCampaign.CurrentArc = new DashboardArcDto
 106                        {
 107                            Id = activeArc.Id,
 108                            Name = activeArc.Name,
 109                            Description = activeArc.Description,
 110                            SessionCount = arcSessionCount,
 111                            LatestSessionDate = latestSession?.SessionDate ?? latestSession?.CreatedAt
 112                        };
 113                    }
 114
 115                    dashboardWorld.Campaigns.Add(dashboardCampaign);
 116                }
 117            }
 118
 119            dashboardWorld.MyCharacters = claimedCharacters
 120                .Where(c => c.WorldId == world.Id)
 121                .Select(c => new DashboardCharacterDto
 122                {
 123                    Id = c.Id,
 124                    Title = c.Title,
 125                    IconEmoji = c.IconEmoji,
 126                    ModifiedAt = c.ModifiedAt,
 127                    CreatedAt = c.CreatedAt
 128                })
 129                .ToList();
 130
 131            dashboardWorlds.Add(dashboardWorld);
 132        }
 133
 134        var dashboard = new DashboardDto
 135        {
 136            UserDisplayName = userDisplayName,
 137            Worlds = dashboardWorlds,
 138            ClaimedCharacters = claimedCharacters,
 139            Prompts = new List<PromptDto>()
 140        };
 141
 142        dashboard.Prompts = _promptService.GeneratePrompts(dashboard);
 143        return dashboard;
 144    }
 145}
 146