< Summary

Information
Class: Chronicis.Api.Controllers.WorldActiveContextController
Assembly: Chronicis.Api
File(s): /home/runner/work/chronicis/chronicis/src/Chronicis.Api/Controllers/CampaignsController.cs
Line coverage
100%
Covered lines: 8
Uncovered lines: 0
Coverable lines: 8
Total lines: 167
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/Controllers/CampaignsController.cs

#LineLine coverage
 1using Chronicis.Api.Infrastructure;
 2using Chronicis.Api.Services;
 3using Chronicis.Shared.DTOs;
 4using Microsoft.AspNetCore.Authorization;
 5using Microsoft.AspNetCore.Mvc;
 6
 7namespace Chronicis.Api.Controllers;
 8
 9/// <summary>
 10/// API endpoints for Campaign management.
 11/// </summary>
 12[ApiController]
 13[Route("campaigns")]
 14[Authorize]
 15public class CampaignsController : ControllerBase
 16{
 17    private readonly ICampaignService _campaignService;
 18    private readonly ICurrentUserService _currentUserService;
 19    private readonly ILogger<CampaignsController> _logger;
 20
 21    public CampaignsController(
 22        ICampaignService campaignService,
 23        ICurrentUserService currentUserService,
 24        ILogger<CampaignsController> logger)
 25    {
 26        _campaignService = campaignService;
 27        _currentUserService = currentUserService;
 28        _logger = logger;
 29    }
 30
 31    /// <summary>
 32    /// GET /api/campaigns/{id} - Get a specific campaign.
 33    /// </summary>
 34    [HttpGet("{id:guid}")]
 35    public async Task<ActionResult<CampaignDto>> GetCampaign(Guid id)
 36    {
 37        var user = await _currentUserService.GetRequiredUserAsync();
 38        _logger.LogTraceSanitized("Getting campaign {CampaignId} for user {UserId}", id, user.Id);
 39
 40        var campaign = await _campaignService.GetCampaignAsync(id, user.Id);
 41
 42        if (campaign == null)
 43        {
 44            return NotFound(new { error = "Campaign not found or access denied" });
 45        }
 46
 47        return Ok(campaign);
 48    }
 49
 50    /// <summary>
 51    /// POST /api/campaigns - Create a new campaign.
 52    /// </summary>
 53    [HttpPost]
 54    public async Task<ActionResult<CampaignDto>> CreateCampaign([FromBody] CampaignCreateDto dto)
 55    {
 56        var user = await _currentUserService.GetRequiredUserAsync();
 57
 58        if (dto == null || string.IsNullOrWhiteSpace(dto.Name))
 59        {
 60            return BadRequest(new { error = "Name is required" });
 61        }
 62
 63        if (dto.WorldId == Guid.Empty)
 64        {
 65            return BadRequest(new { error = "WorldId is required" });
 66        }
 67
 68        _logger.LogTraceSanitized("Creating campaign '{Name}' in world {WorldId} for user {UserId}",
 69            dto.Name, dto.WorldId, user.Id);
 70
 71        try
 72        {
 73            var campaign = await _campaignService.CreateCampaignAsync(dto, user.Id);
 74            return CreatedAtAction(nameof(GetCampaign), new { id = campaign.Id }, campaign);
 75        }
 76        catch (UnauthorizedAccessException ex)
 77        {
 78            return StatusCode(403, new { error = ex.Message });
 79        }
 80        catch (InvalidOperationException ex)
 81        {
 82            return BadRequest(new { error = ex.Message });
 83        }
 84    }
 85
 86    /// <summary>
 87    /// PUT /api/campaigns/{id} - Update a campaign.
 88    /// </summary>
 89    [HttpPut("{id:guid}")]
 90    public async Task<ActionResult<CampaignDto>> UpdateCampaign(Guid id, [FromBody] CampaignUpdateDto dto)
 91    {
 92        var user = await _currentUserService.GetRequiredUserAsync();
 93
 94        if (dto == null || string.IsNullOrWhiteSpace(dto.Name))
 95        {
 96            return BadRequest(new { error = "Name is required" });
 97        }
 98
 99        _logger.LogTraceSanitized("Updating campaign {CampaignId} for user {UserId}", id, user.Id);
 100
 101        var campaign = await _campaignService.UpdateCampaignAsync(id, dto, user.Id);
 102
 103        if (campaign == null)
 104        {
 105            return NotFound(new { error = "Campaign not found or access denied" });
 106        }
 107
 108        return Ok(campaign);
 109    }
 110
 111    /// <summary>
 112    /// POST /api/campaigns/{id}/activate - Activate a campaign.
 113    /// </summary>
 114    [HttpPost("{id:guid}/activate")]
 115    public async Task<IActionResult> ActivateCampaign(Guid id)
 116    {
 117        var user = await _currentUserService.GetRequiredUserAsync();
 118
 119        _logger.LogTraceSanitized("Activating campaign {CampaignId} for user {UserId}", id, user.Id);
 120
 121        var success = await _campaignService.ActivateCampaignAsync(id, user.Id);
 122
 123        if (!success)
 124        {
 125            return BadRequest(new { error = "Unable to activate campaign. Campaign not found or you don't have permissio
 126        }
 127
 128        return NoContent();
 129    }
 130}
 131
 132/// <summary>
 133/// Active context endpoints - nested under worlds but related to campaigns.
 134/// </summary>
 135[ApiController]
 136[Route("worlds/{worldId:guid}")]
 137[Authorize]
 138public class WorldActiveContextController : ControllerBase
 139{
 140    private readonly ICampaignService _campaignService;
 141    private readonly ICurrentUserService _currentUserService;
 142    private readonly ILogger<WorldActiveContextController> _logger;
 143
 1144    public WorldActiveContextController(
 1145        ICampaignService campaignService,
 1146        ICurrentUserService currentUserService,
 1147        ILogger<WorldActiveContextController> logger)
 148    {
 1149        _campaignService = campaignService;
 1150        _currentUserService = currentUserService;
 1151        _logger = logger;
 1152    }
 153
 154    /// <summary>
 155    /// GET /api/worlds/{worldId}/active-context - Get the active context for a world.
 156    /// </summary>
 157    [HttpGet("active-context")]
 158    public async Task<ActionResult<ActiveContextDto>> GetActiveContext(Guid worldId)
 159    {
 160        var user = await _currentUserService.GetRequiredUserAsync();
 161
 162        _logger.LogTraceSanitized("Getting active context for world {WorldId} for user {UserId}", worldId, user.Id);
 163
 164        var activeContext = await _campaignService.GetActiveContextAsync(worldId, user.Id);
 165        return Ok(activeContext);
 166    }
 167}