116 lines
4.7 KiB
C#
116 lines
4.7 KiB
C#
using System.Text.Json;
|
|
using MealPlan.Api.DTOs.Generators;
|
|
using MealPlan.Api.Extensions;
|
|
using MealPlan.Api.Services.Generators;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
namespace MealPlan.Api.Controllers;
|
|
|
|
[ApiController]
|
|
[Route("api/recipe-generator")]
|
|
[Authorize]
|
|
public class RecipeGeneratorController : ControllerBase
|
|
{
|
|
private readonly IRecipeGeneratorService _service;
|
|
|
|
public RecipeGeneratorController(IRecipeGeneratorService service) => _service = service;
|
|
|
|
[HttpPost("sessions")]
|
|
[ProducesResponseType(typeof(RecipeGeneratorSessionDto), StatusCodes.Status201Created)]
|
|
public async Task<IActionResult> CreateSession([FromBody] RecipeGeneratorConstraintsDto dto, CancellationToken ct)
|
|
{
|
|
if (User.RequireUserId(out var userId) is { } unauthorized) return unauthorized;
|
|
var session = await _service.CreateSessionAsync(userId, dto, ct);
|
|
return CreatedAtAction(nameof(GetSession), new { id = session.Id }, session);
|
|
}
|
|
|
|
[HttpGet("sessions/{id:int}")]
|
|
[ProducesResponseType(typeof(RecipeGeneratorSessionDto), StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
public async Task<IActionResult> GetSession(int id, CancellationToken ct)
|
|
{
|
|
if (User.RequireUserId(out var userId) is { } unauthorized) return unauthorized;
|
|
var session = await _service.GetSessionAsync(userId, id, ct);
|
|
return session is null ? NotFound() : Ok(session);
|
|
}
|
|
|
|
[HttpPost("sessions/{id:int}/generate")]
|
|
[ProducesResponseType(typeof(RecipeGeneratorSessionDto), StatusCodes.Status200OK)]
|
|
public async Task<IActionResult> Generate(int id, [FromBody] GenerateRecipesRequestDto? request, CancellationToken ct)
|
|
{
|
|
if (User.RequireUserId(out var userId) is { } unauthorized) return unauthorized;
|
|
try
|
|
{
|
|
var session = await _service.GenerateAsync(userId, id, request, ct);
|
|
return session is null ? NotFound() : Ok(session);
|
|
}
|
|
catch (InvalidOperationException ex)
|
|
{
|
|
return BadRequest(new { error = ex.Message });
|
|
}
|
|
}
|
|
|
|
[HttpPost("sessions/{id:int}/regenerate")]
|
|
[ProducesResponseType(typeof(RecipeGeneratorSessionDto), StatusCodes.Status200OK)]
|
|
public async Task<IActionResult> Regenerate(int id, [FromBody] RegenerateRecipePartDto dto, CancellationToken ct)
|
|
{
|
|
if (User.RequireUserId(out var userId) is { } unauthorized) return unauthorized;
|
|
try
|
|
{
|
|
var session = await _service.RegeneratePartAsync(userId, id, dto, ct);
|
|
return session is null ? NotFound() : Ok(session);
|
|
}
|
|
catch (InvalidOperationException ex)
|
|
{
|
|
return BadRequest(new { error = ex.Message });
|
|
}
|
|
catch (JsonException)
|
|
{
|
|
return BadRequest(new { error = "Could not parse AI recipe response. Try again." });
|
|
}
|
|
}
|
|
|
|
[HttpPut("sessions/{id:int}/draft")]
|
|
[ProducesResponseType(typeof(RecipeGeneratorSessionDto), StatusCodes.Status200OK)]
|
|
public async Task<IActionResult> UpdateDraft(int id, [FromBody] GeneratedRecipeDraftDto dto, CancellationToken ct)
|
|
{
|
|
if (User.RequireUserId(out var userId) is { } unauthorized) return unauthorized;
|
|
var session = await _service.UpdateDraftAsync(userId, id, dto, ct);
|
|
return session is null ? NotFound() : Ok(session);
|
|
}
|
|
|
|
[HttpDelete("sessions/{id:int}/drafts/{draftId}")]
|
|
[ProducesResponseType(typeof(RecipeGeneratorSessionDto), StatusCodes.Status200OK)]
|
|
public async Task<IActionResult> RemoveDraft(int id, string draftId, CancellationToken ct)
|
|
{
|
|
if (User.RequireUserId(out var userId) is { } unauthorized) return unauthorized;
|
|
var session = await _service.RemoveDraftAsync(userId, id, draftId, ct);
|
|
return session is null ? NotFound() : Ok(session);
|
|
}
|
|
|
|
[HttpPost("sessions/{id:int}/commit")]
|
|
[ProducesResponseType(typeof(CommitRecipesResultDto), StatusCodes.Status200OK)]
|
|
public async Task<IActionResult> Commit(int id, [FromBody] CommitRecipesRequestDto? request, CancellationToken ct)
|
|
{
|
|
if (User.RequireUserId(out var userId) is { } unauthorized) return unauthorized;
|
|
try
|
|
{
|
|
var result = await _service.CommitAsync(userId, id, request, ct);
|
|
if (result is null)
|
|
{
|
|
return NotFound(new
|
|
{
|
|
error = "Nothing to save. The session may have expired, or the selected drafts were not found.",
|
|
});
|
|
}
|
|
|
|
return Ok(result);
|
|
}
|
|
catch (InvalidOperationException ex)
|
|
{
|
|
return BadRequest(new { error = ex.Message });
|
|
}
|
|
}
|
|
}
|