< Summary

Information
Class: Chronicis.Api.Controllers.CampaignArcsController
Assembly: Chronicis.Api
File(s): /home/runner/work/chronicis/chronicis/src/Chronicis.Api/Controllers/ArcsController.cs
Line coverage
100%
Covered lines: 8
Uncovered lines: 0
Coverable lines: 8
Total lines: 179
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/ArcsController.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 Arc management.
 11/// </summary>
 12[ApiController]
 13[Route("arcs")]
 14[Authorize]
 15public class ArcsController : ControllerBase
 16{
 17    private readonly IArcService _arcService;
 18    private readonly ICurrentUserService _currentUserService;
 19    private readonly ILogger<ArcsController> _logger;
 20
 21    public ArcsController(
 22        IArcService arcService,
 23        ICurrentUserService currentUserService,
 24        ILogger<ArcsController> logger)
 25    {
 26        _arcService = arcService;
 27        _currentUserService = currentUserService;
 28        _logger = logger;
 29    }
 30
 31    /// <summary>
 32    /// GET /api/arcs/{id} - Get a specific arc.
 33    /// </summary>
 34    [HttpGet("{id:guid}")]
 35    public async Task<ActionResult<ArcDto>> GetArc(Guid id)
 36    {
 37        var user = await _currentUserService.GetRequiredUserAsync();
 38        _logger.LogTraceSanitized("Getting arc {ArcId} for user {UserId}", id, user.Id);
 39
 40        var arc = await _arcService.GetArcAsync(id, user.Id);
 41
 42        if (arc == null)
 43        {
 44            return NotFound(new { error = "Arc not found or access denied" });
 45        }
 46
 47        return Ok(arc);
 48    }
 49
 50    /// <summary>
 51    /// POST /api/arcs - Create a new arc.
 52    /// </summary>
 53    [HttpPost]
 54    public async Task<ActionResult<ArcDto>> CreateArc([FromBody] ArcCreateDto 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.CampaignId == Guid.Empty)
 64        {
 65            return BadRequest(new { error = "CampaignId is required" });
 66        }
 67
 68        _logger.LogTraceSanitized("Creating arc '{Name}' in campaign {CampaignId} for user {UserId}",
 69            dto.Name, dto.CampaignId, user.Id);
 70
 71        var arc = await _arcService.CreateArcAsync(dto, user.Id);
 72
 73        if (arc == null)
 74        {
 75            return StatusCode(403, new { error = "Access denied or failed to create arc" });
 76        }
 77
 78        return CreatedAtAction(nameof(GetArc), new { id = arc.Id }, arc);
 79    }
 80
 81    /// <summary>
 82    /// PUT /api/arcs/{id} - Update an arc.
 83    /// </summary>
 84    [HttpPut("{id:guid}")]
 85    public async Task<ActionResult<ArcDto>> UpdateArc(Guid id, [FromBody] ArcUpdateDto dto)
 86    {
 87        var user = await _currentUserService.GetRequiredUserAsync();
 88
 89        if (dto == null || string.IsNullOrWhiteSpace(dto.Name))
 90        {
 91            return BadRequest(new { error = "Name is required" });
 92        }
 93
 94        _logger.LogTraceSanitized("Updating arc {ArcId} for user {UserId}", id, user.Id);
 95
 96        var arc = await _arcService.UpdateArcAsync(id, dto, user.Id);
 97
 98        if (arc == null)
 99        {
 100            return NotFound(new { error = "Arc not found or access denied" });
 101        }
 102
 103        return Ok(arc);
 104    }
 105
 106    /// <summary>
 107    /// DELETE /api/arcs/{id} - Delete an arc (only if empty).
 108    /// </summary>
 109    [HttpDelete("{id:guid}")]
 110    public async Task<IActionResult> DeleteArc(Guid id)
 111    {
 112        var user = await _currentUserService.GetRequiredUserAsync();
 113        _logger.LogTraceSanitized("Deleting arc {ArcId} for user {UserId}", id, user.Id);
 114
 115        var success = await _arcService.DeleteArcAsync(id, user.Id);
 116
 117        if (!success)
 118        {
 119            return BadRequest(new { error = "Arc not found, access denied, or arc is not empty" });
 120        }
 121
 122        return NoContent();
 123    }
 124
 125    /// <summary>
 126    /// POST /api/arcs/{id}/activate - Activate an arc for quick session creation.
 127    /// </summary>
 128    [HttpPost("{id:guid}/activate")]
 129    public async Task<IActionResult> ActivateArc(Guid id)
 130    {
 131        var user = await _currentUserService.GetRequiredUserAsync();
 132        _logger.LogTraceSanitized("Activating arc {ArcId} for user {UserId}", id, user.Id);
 133
 134        var success = await _arcService.ActivateArcAsync(id, user.Id);
 135
 136        if (!success)
 137        {
 138            return BadRequest(new { error = "Unable to activate arc. Arc not found or you don't have permission." });
 139        }
 140
 141        return NoContent();
 142    }
 143}
 144
 145/// <summary>
 146/// Campaign-scoped arc endpoints.
 147/// </summary>
 148[ApiController]
 149[Route("campaigns/{campaignId:guid}/arcs")]
 150[Authorize]
 151public class CampaignArcsController : ControllerBase
 152{
 153    private readonly IArcService _arcService;
 154    private readonly ICurrentUserService _currentUserService;
 155    private readonly ILogger<CampaignArcsController> _logger;
 156
 1157    public CampaignArcsController(
 1158        IArcService arcService,
 1159        ICurrentUserService currentUserService,
 1160        ILogger<CampaignArcsController> logger)
 161    {
 1162        _arcService = arcService;
 1163        _currentUserService = currentUserService;
 1164        _logger = logger;
 1165    }
 166
 167    /// <summary>
 168    /// GET /api/campaigns/{campaignId}/arcs - Get all arcs for a campaign.
 169    /// </summary>
 170    [HttpGet]
 171    public async Task<ActionResult<List<ArcDto>>> GetArcsByCampaign(Guid campaignId)
 172    {
 173        var user = await _currentUserService.GetRequiredUserAsync();
 174        _logger.LogTraceSanitized("Getting arcs for campaign {CampaignId} for user {UserId}", campaignId, user.Id);
 175
 176        var arcs = await _arcService.GetArcsByCampaignAsync(campaignId, user.Id);
 177        return Ok(arcs);
 178    }
 179}