using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using ProposalSystem.Application.DTOs; using ProposalSystem.Application.Interfaces; namespace ProposalSystem.Api.Controllers; /// /// PR5: Pricing Library CRUD endpoints. Admins seed/manage reusable priced /// reference items that feed the Bedrock RAG corpus. /// /// GET {id} is reachable by the internal API key middleware (which assigns /// the "admins" role) so the library-ingest Lambda can fetch item details. /// [ApiController] [Route("api/pricing-library")] [Authorize] public class PricingLibraryController : ControllerBase { private readonly IPricingLibraryService _pricingLibraryService; public PricingLibraryController(IPricingLibraryService pricingLibraryService) { _pricingLibraryService = pricingLibraryService; } [HttpGet("list")] [Authorize(Roles = "admins,sysadmins")] [ProducesResponseType(typeof(PagedResponse), 200)] public async Task>> List( [FromQuery] int page = 1, [FromQuery] int pageSize = 25, CancellationToken ct = default) { var result = await _pricingLibraryService.ListAsync(page, pageSize, ct); return Ok(result); } /// /// Get a single pricing library item. Accessible by admins/sysadmins role, /// which includes internal Lambda callers (the internal API key middleware /// assigns the "admins" role). /// [HttpGet("{id:guid}")] [Authorize(Roles = "admins,sysadmins")] [ProducesResponseType(typeof(PricingLibraryItemResponse), 200)] [ProducesResponseType(404)] public async Task> GetById( Guid id, CancellationToken ct) { var result = await _pricingLibraryService.GetByIdAsync(id, ct); if (result == null) return NotFound(); return Ok(result); } [HttpPost] [Authorize(Roles = "admins,sysadmins")] [ProducesResponseType(typeof(PricingLibraryItemResponse), 201)] [ProducesResponseType(400)] public async Task> Create( [FromBody] CreatePricingLibraryItemRequest request, CancellationToken ct) { var result = await _pricingLibraryService.CreateAsync(request, ct); return CreatedAtAction(nameof(GetById), new { id = result.Id }, result); } [HttpPut("{id:guid}")] [Authorize(Roles = "admins,sysadmins")] [ProducesResponseType(typeof(PricingLibraryItemResponse), 200)] [ProducesResponseType(400)] [ProducesResponseType(404)] public async Task> Update( Guid id, [FromBody] UpdatePricingLibraryItemRequest request, CancellationToken ct) { var result = await _pricingLibraryService.UpdateAsync(id, request, ct); if (result == null) return NotFound(); return Ok(result); } [HttpDelete("{id:guid}")] [Authorize(Roles = "admins,sysadmins")] [ProducesResponseType(204)] [ProducesResponseType(404)] public async Task Delete( Guid id, CancellationToken ct) { var deleted = await _pricingLibraryService.DeleteAsync(id, ct); if (!deleted) return NotFound(); return NoContent(); } }