Files
mabibli/MaBibli.Shared/Dtos/SouhaitDto.cs
T
mathieuandClaude Opus 5 8b8fe3be6e Ajouter la liste d'envies personnelle, son export et la bibliographie par auteur
La liste d'envies vit dans une table séparée (LivreSouhaite) plutôt que dans un
statut de plus sur Livre : un livre souhaité n'est pas possédé, et le loger dans
Livres l'aurait fait entrer dans le catalogue, les compteurs et les prêts, au
prix d'un « et qui n'est pas souhaité » à répéter dans chaque lecture. La portée
est personnelle, comme le statut de lecture — mais ici Utilisateur est une vraie
frontière : toute lecture filtre dessus.

Bibliographie : SRU BnF interrogé par bib.author, vérifié le 2026-08-18. Deux
filtres mesurés sur des réponses réelles sont indispensables — le type de
document (l'index mêle livres audio, jeux et spectacles) et surtout l'auteur
réel de la notice, « all » rapprochant les mots sur l'ensemble des auteurs :
« Émile Zola » remonte sinon toute l'œuvre de sa fille Denise Le Blond-Zola.
Les rééditions sont regroupées par clé d'œuvre (183 notices Werber -> 51
œuvres). Le rapprochement avec l'étagère se fait par titre, pas par ISBN, qui
désigne une édition et non une œuvre ; ses limites sont dites à l'écran.

Export en deux formats, tous deux du texte sans dépendance : .txt groupé par
auteur pour la librairie, .csv à séparateur point-virgule et BOM pour le
tableur.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 13:59:06 +02:00

138 lines
4.7 KiB
C#

using System.Text.Json.Serialization;
namespace MaBibli.Shared.Dtos;
/// <summary>
/// Une envie telle qu'exposée par l'API.
/// </summary>
/// <remarks>
/// Il n'y a <b>aucun champ « utilisateur »</b>, 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.
/// </remarks>
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; }
}
/// <summary>Charge utile d'ajout d'une envie.</summary>
/// <remarks>
/// Comme <see cref="EnregistrementLivre"/>, elle ne porte pas d'identité : le propriétaire est
/// déterminé par le serveur.
/// </remarks>
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; }
}
/// <summary>Formats d'export de la liste d'envies.</summary>
/// <remarks>
/// 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 <c>string</c>.
/// </remarks>
public enum FormatExportSouhaits
{
/// <summary>Liste lisible telle quelle, groupée par auteur.</summary>
Texte = 0,
/// <summary>Tableau ouvrable dans un tableur.</summary>
Csv = 1,
}
/// <summary>Une œuvre de la bibliographie d'un auteur, confrontée à ce que l'on possède déjà.</summary>
public record OeuvreBibliographie
{
public required string Titre { get; init; }
public string? Annee { get; init; }
public string? Editeur { get; init; }
/// <summary>ISBN d'une des éditions relevées, quand la notice en portait un.</summary>
public string? Isbn { get; init; }
/// <summary>
/// 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é.
/// </summary>
public int NombreEditions { get; init; }
/// <summary>
/// Vrai si un livre du catalogue porte le même titre d'œuvre.
/// <b>Rapprochement par titre, donc faillible</b> — voir <c>CleOeuvre</c>.
/// </summary>
public bool Possede { get; init; }
/// <summary>Le livre possédé, s'il y en a un : de quoi ouvrir sa fiche.</summary>
public int? LivreId { get; init; }
/// <summary>Vrai si l'appelant a déjà cette œuvre dans sa liste d'envies.</summary>
public bool Souhaite { get; init; }
public int? SouhaitId { get; init; }
/// <summary>Ni possédé, ni déjà souhaité : ce qui reste à découvrir.</summary>
[JsonIgnore]
public bool ADecouvrir => !Possede && !Souhaite;
}
/// <summary>
/// Bibliographie d'un auteur du catalogue, telle que la BnF la connaît.
/// </summary>
/// <remarks>
/// 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 <b>extrait classé par
/// pertinence</b>, et le taire ferait passer une liste partielle pour une bibliographie complète.
/// </remarks>
public record BibliographieDto
{
public required AuteurDto Auteur { get; init; }
public IReadOnlyList<OeuvreBibliographie> Oeuvres { get; init; } = [];
/// <summary>Nombre total de notices que la BnF déclare pour cet auteur.</summary>
public int NoticesAnnoncees { get; init; }
/// <summary>Nombre de notices réellement lues (plafonné).</summary>
public int NoticesLues { get; init; }
/// <summary>Notices écartées parce qu'aucun de leurs auteurs n'est celui demandé.</summary>
public int NoticesEcartees { get; init; }
/// <summary>Vrai si la BnF en annonce plus qu'on n'en a lu : la liste est un extrait.</summary>
public bool Tronquee => NoticesAnnoncees > NoticesLues;
/// <summary>Message à afficher quand la source n'a pas pu être interrogée normalement.</summary>
public string? Avertissement { get; init; }
}