using MaBibli.Api.Services.Prets;
using MaBibli.Shared.Dtos;
namespace MaBibli.Api.Endpoints;
public static class PretsEndpoints
{
///
/// Prêts : qui a quoi, depuis quand, et l'historique de ce qui est revenu.
///
///
/// Aucun point d'entrée ne filtre sur l'utilisateur courant, et aucun n'enregistre qui
/// a saisi le prêt. La bibliothèque est commune : tout le foyer voit les mêmes prêts, et
/// n'importe qui peut noter le retour d'un livre qu'il a récupéré.
///
/// L'emprunteur est du texte libre : ce sont des personnes extérieures au foyer, sans
/// compte YunoHost. Ne jamais le rapprocher d'un identifiant d'utilisateur.
///
///
public static IEndpointRouteBuilder MapPretsEndpoints(this IEndpointRouteBuilder routes)
{
var prets = routes.MapGroup("/api/prets").WithTags("Prêts");
prets.MapGet("/en-cours", async (IServicePrets service, CancellationToken ct) =>
Results.Ok(await service.EnCoursAsync(ct)))
.WithName("ListerPretsEnCours")
.WithSummary("Les livres qui ne sont pas à la maison, du prêt le plus ancien au plus récent.")
.WithDescription(
"L'ordre est volontairement croissant : ce qu'on cherche ici, c'est le livre "
+ "sorti depuis des mois qu'on avait oublié, pas celui prêté hier.")
.Produces>();
prets.MapPost("/{id:int}/retour", async (
int id,
RetourPret retour,
IServicePrets service,
CancellationToken ct) =>
{
var resultat = await service.RendreAsync(id, retour, ct);
if (resultat.EstIntrouvable)
{
return Results.NotFound();
}
return resultat.Erreur is not null
? Results.BadRequest(new { erreur = resultat.Erreur })
: Results.Ok(resultat.Pret);
})
.WithName("MarquerPretRendu")
.WithSummary("Clôt un prêt en posant sa date de retour. Le prêt n'est pas supprimé : il devient l'historique.")
.Produces()
.Produces(StatusCodes.Status400BadRequest)
.Produces(StatusCodes.Status404NotFound);
var parLivre = routes.MapGroup("/api/livres/{livreId:int}/prets").WithTags("Prêts");
parLivre.MapGet("/", async (int livreId, IServicePrets service, CancellationToken ct) =>
{
var historique = await service.HistoriqueAsync(livreId, ct);
return historique is null ? Results.NotFound() : Results.Ok(historique);
})
.WithName("HistoriquePretsLivre")
.WithSummary("Tous les prêts de ce livre, clos comme en cours, du plus récent au plus ancien.")
.WithDescription(
"Une liste vide signifie « jamais prêté » ; un livre inconnu répond 404. "
+ "Les prêts clos ne disparaissent jamais : c'est la raison d'être de la table.")
.Produces>()
.Produces(StatusCodes.Status404NotFound);
parLivre.MapPost("/", async (
int livreId,
EnregistrementPret saisie,
IServicePrets service,
CancellationToken ct) =>
{
var resultat = await service.PreterAsync(livreId, saisie, ct);
if (resultat.EstIntrouvable)
{
return Results.NotFound();
}
return resultat.Erreur is not null
? Results.BadRequest(new { erreur = resultat.Erreur })
: Results.Created($"/api/prets/{resultat.Pret!.Id}", resultat.Pret);
})
.WithName("PreterLivre")
.WithSummary("Prête ce livre à quelqu'un.")
.WithDescription(
"Refusé si le livre est déjà sorti (un exemplaire ne se prête pas deux fois) ou "
+ "s'il est au format numérique (une fiche d'ebook n'a pas d'exemplaire à confier).")
.Produces(StatusCodes.Status201Created)
.Produces(StatusCodes.Status400BadRequest)
.Produces(StatusCodes.Status404NotFound);
return routes;
}
}