using MaBibli.Api.Services.Identite; using MaBibli.Api.Services.Revues; using MaBibli.Shared.Dtos; namespace MaBibli.Api.Endpoints; public static class RevuesEndpoints { /// /// Revues et magazines : une fiche par revue, les numéros à l'intérieur. /// /// /// Communes au foyer, comme le catalogue : aucun point d'entrée ne prend d'identité, /// et « ajoutePar » n'est qu'une trace. La lecture est unique — GET /api/revues rend /// les revues avec leurs numéros, ce qui donne un seul instantané hors-ligne. /// public static IEndpointRouteBuilder MapRevuesEndpoints(this IEndpointRouteBuilder routes) { var groupe = routes.MapGroup("/api/revues").WithTags("Revues"); groupe.MapGet("/", async (IServiceRevues service, CancellationToken ct) => Results.Ok(await service.ListerAsync(ct))) .WithName("ListerRevues") .WithSummary("Toutes les revues, avec les numéros possédés, du plus récent au plus ancien.") .Produces>(); groupe.MapPost("/", async ( EnregistrementRevue saisie, IServiceRevues service, IFournisseurUtilisateur utilisateurs, CancellationToken ct) => { var resultat = await service.CreerOuRetrouverAsync( saisie, utilisateurs.Obtenir().Identifiant, ct); return resultat.Erreur is not null ? Results.BadRequest(new { erreur = resultat.Erreur }) : Results.Ok(resultat.Revue); }) .WithName("CreerRevue") .WithSummary("Crée la revue, ou rend celle qui existe déjà (même ISSN, ou même titre).") .WithDescription( "« Créer ou retrouver » et non « créer » : scanner le code-barres d'un second " + "numéro retombe forcément sur la même revue, et le geste de l'utilisateur est " + "toujours « voici un numéro de plus ».") .Produces() .Produces(StatusCodes.Status400BadRequest); groupe.MapPut("/{id:int}", async ( int id, EnregistrementRevue saisie, IServiceRevues service, CancellationToken ct) => Repondre(await service.ModifierAsync(id, saisie, ct))) .WithName("ModifierRevue") .Produces() .Produces(StatusCodes.Status400BadRequest) .Produces(StatusCodes.Status404NotFound); groupe.MapDelete("/{id:int}", async (int id, IServiceRevues service, CancellationToken ct) => await service.SupprimerAsync(id, ct) ? Results.NoContent() : Results.NotFound()) .WithName("SupprimerRevue") .WithSummary("Supprime la revue et les numéros qu'elle porte : ils n'existent que par elle.") .Produces(StatusCodes.Status204NoContent) .Produces(StatusCodes.Status404NotFound); groupe.MapPost("/{id:int}/numeros", async ( int id, AjoutNumeroRevue saisie, IServiceRevues service, CancellationToken ct) => Repondre(await service.AjouterNumeroAsync(id, saisie, ct))) .WithName("AjouterNumeroRevue") .WithSummary("Ajoute un numéro possédé. Le numéro est obligatoire et unique dans la revue.") .Produces() .Produces(StatusCodes.Status400BadRequest) .Produces(StatusCodes.Status404NotFound); groupe.MapPut("/numeros/{numeroId:int}", async ( int numeroId, AjoutNumeroRevue saisie, IServiceRevues service, CancellationToken ct) => Repondre(await service.ModifierNumeroAsync(numeroId, saisie, ct))) .WithName("ModifierNumeroRevue") .WithSummary("Modifie un numéro : numéro, parution, note, couverture et articles à la une.") .WithDescription( "La couverture d'un numéro et sa une ne viennent d'aucune source — l'ISSN " + "désigne la revue, pas la parution — et se saisissent donc après coup.") .Produces() .Produces(StatusCodes.Status400BadRequest) .Produces(StatusCodes.Status404NotFound); groupe.MapDelete("/numeros/{numeroId:int}", async ( int numeroId, IServiceRevues service, CancellationToken ct) => await service.RetirerNumeroAsync(numeroId, ct) ? Results.NoContent() : Results.NotFound()) .WithName("RetirerNumeroRevue") .Produces(StatusCodes.Status204NoContent) .Produces(StatusCodes.Status404NotFound); return routes; } private static IResult Repondre(ResultatRevue resultat) { if (resultat.EstIntrouvable) { return Results.NotFound(); } return resultat.Erreur is not null ? Results.BadRequest(new { erreur = resultat.Erreur }) : Results.Ok(resultat.Revue); } }