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; } }