using System.Text.Json.Serialization; namespace MaBibli.Shared.Dtos; /// /// Une envie telle qu'exposée par l'API. /// /// /// Il n'y a aucun champ « utilisateur », et il ne doit jamais y en avoir : l'API ne rend /// que les envies de l'appelant, qu'elle identifie par les en-têtes SSOwat. Exposer le /// propriétaire laisserait croire qu'on peut demander celles d'un autre. /// public record SouhaitDto { public required int Id { get; init; } public required string Titre { get; init; } public string? Auteur { get; init; } public string? Editeur { get; init; } public string? Annee { get; init; } public string? Isbn { get; init; } public string? CoverUrl { get; init; } public string? Note { get; init; } public required DateTime DateAjout { get; init; } } /// Charge utile d'ajout d'une envie. /// /// Comme , elle ne porte pas d'identité : le propriétaire est /// déterminé par le serveur. /// public record EnregistrementSouhait { public string Titre { get; set; } = string.Empty; public string? Auteur { get; set; } public string? Editeur { get; set; } public string? Annee { get; set; } public string? Isbn { get; set; } public string? CoverUrl { get; set; } public string? Note { get; set; } } /// Formats d'export de la liste d'envies. /// /// Les deux usages décrits dans IDEES.md ne demandent pas la même chose : « l'emporter en /// librairie » veut un texte qui se lit tel quel sur un téléphone, « la partager avant un /// anniversaire » finit souvent dans un tableur pour se répartir les achats. Ni l'un ni l'autre /// n'exige de dépendance : ce sont deux fichiers texte produits par du string. /// public enum FormatExportSouhaits { /// Liste lisible telle quelle, groupée par auteur. Texte = 0, /// Tableau ouvrable dans un tableur. Csv = 1, } /// Une œuvre de la bibliographie d'un auteur, confrontée à ce que l'on possède déjà. public record OeuvreBibliographie { public required string Titre { get; init; } public string? Annee { get; init; } public string? Editeur { get; init; } /// ISBN d'une des éditions relevées, quand la notice en portait un. public string? Isbn { get; init; } /// /// Nombre de notices BnF réunies sous cette œuvre — c'est-à-dire le nombre de rééditions /// relevées. Sert à repérer les œuvres majeures d'un auteur très réédité. /// public int NombreEditions { get; init; } /// /// Vrai si un livre du catalogue porte le même titre d'œuvre. /// Rapprochement par titre, donc faillible — voir CleOeuvre. /// public bool Possede { get; init; } /// Le livre possédé, s'il y en a un : de quoi ouvrir sa fiche. public int? LivreId { get; init; } /// Vrai si l'appelant a déjà cette œuvre dans sa liste d'envies. public bool Souhaite { get; init; } public int? SouhaitId { get; init; } /// Ni possédé, ni déjà souhaité : ce qui reste à découvrir. [JsonIgnore] public bool ADecouvrir => !Possede && !Souhaite; } /// /// Ce qu'il est advenu de l'interrogation de la BnF. /// /// /// ⚠️ Une source muette n'est pas une bibliographie vide, et la différence n'est pas /// cosmétique : sans cet état, un délai dépassé produisait une liste vide, que l'écran /// commentait d'un rassurant « la BnF ne connaît aucun livre de cet auteur ». On affirmait donc /// une chose qu'on n'avait pas pu vérifier. C'est ce que cet énuméré rend impossible. /// /// Le motif est distingué parce qu'il ne demande pas la même chose à l'utilisateur : un délai /// dépassé se retente, une réponse illisible non. /// /// public enum EtatSourceBibliographie { /// La BnF a répondu. La liste rendue est ce qu'elle sait, y compris si elle est vide. Ok = 0, /// La BnF n'a pas répondu à temps. Cas le plus fréquent, et le plus souvent passager. DelaiDepasse = 1, /// La BnF n'a pas pu être jointe, ou a répondu par une erreur. Injoignable = 2, /// La BnF a répondu, mais sa réponse n'était pas exploitable. ReponseIllisible = 3, } /// /// Bibliographie d'un auteur du catalogue, telle que la BnF la connaît. /// /// /// Les compteurs ne sont pas décoratifs : ils disent à l'utilisateur ce qu'il regarde. Sur un /// auteur très réédité (Émile Zola : 2692 notices), on ne montre qu'un extrait classé par /// pertinence, et le taire ferait passer une liste partielle pour une bibliographie complète. /// public record BibliographieDto { public required AuteurDto Auteur { get; init; } public IReadOnlyList Oeuvres { get; init; } = []; /// Nombre total de notices que la BnF déclare pour cet auteur. public int NoticesAnnoncees { get; init; } /// Nombre de notices réellement lues (plafonné). public int NoticesLues { get; init; } /// Notices écartées parce qu'aucun de leurs auteurs n'est celui demandé. public int NoticesEcartees { get; init; } /// Vrai si la BnF en annonce plus qu'on n'en a lu : la liste est un extrait. public bool Tronquee => NoticesAnnoncees > NoticesLues; /// Message à afficher quand la source n'a pas pu être interrogée normalement. public string? Avertissement { get; init; } /// /// Ce qu'il est advenu de l'interrogation. ne veut /// pas dire « des résultats », mais « une réponse ». /// public EtatSourceBibliographie Etat { get; init; } /// /// Vrai quand la BnF n'a pas répondu : la liste vide ne prouve alors rien. /// /// /// C'est ce que l'interface doit consulter avant d'expliquer une absence de résultats. /// public bool SourceMuette => Etat != EtatSourceBibliographie.Ok; }