proposal-system/api/src/ProposalSystem.Api/Controllers/PricingLibraryController.cs

97 lines
3.3 KiB
C#
Raw Normal View History

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using ProposalSystem.Application.DTOs;
using ProposalSystem.Application.Interfaces;
namespace ProposalSystem.Api.Controllers;
/// <summary>
/// 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.
/// </summary>
[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<PricingLibraryItemResponse>), 200)]
public async Task<ActionResult<PagedResponse<PricingLibraryItemResponse>>> List(
[FromQuery] int page = 1,
[FromQuery] int pageSize = 25,
CancellationToken ct = default)
{
var result = await _pricingLibraryService.ListAsync(page, pageSize, ct);
return Ok(result);
}
/// <summary>
/// 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).
/// </summary>
[HttpGet("{id:guid}")]
[Authorize(Roles = "admins,sysadmins")]
[ProducesResponseType(typeof(PricingLibraryItemResponse), 200)]
[ProducesResponseType(404)]
public async Task<ActionResult<PricingLibraryItemResponse>> 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<ActionResult<PricingLibraryItemResponse>> 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<ActionResult<PricingLibraryItemResponse>> 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<IActionResult> Delete(
Guid id,
CancellationToken ct)
{
var deleted = await _pricingLibraryService.DeleteAsync(id, ct);
if (!deleted) return NotFound();
return NoContent();
}
}