Aller au contenu

Projet fil rouge : BiblioTech

La médiathèque d’une école d’ingénieurs gère son catalogue avec des fichiers XML échangés avec un réseau de bibliothèques partenaires. Elle veut une application web moderne pour :

  • consulter le catalogue et rechercher des ouvrages ;
  • gérer les emprunts des adhérents ;
  • recueillir des avis et proposer des recommandations.

Le projet se fait en binôme et avance en trois jalons, un par module. Tout est rendu dans le dépôt git du binôme, chaque jalon étant marqué par un tag (voir Remise des travaux).

erDiagram
  AUTHOR ||--o{ BOOK_AUTHOR : ecrit
  BOOK ||--o{ BOOK_AUTHOR : "a pour auteur"
  BOOK ||--o{ LOAN : "est emprunté"
  MEMBER ||--o{ LOAN : emprunte
  BOOK ||--o{ REVIEW : "reçoit"
  MEMBER ||--o{ REVIEW : "rédige"

  BOOK { string isbn PK
         string title
         int year
         string genre
         int copies
         string summary }
  AUTHOR { string id PK
           string firstName
           string lastName
           string country }
  MEMBER { string id PK
           string name
           string email }
  LOAN { string id PK
         date loanDate
         date dueDate
         date returnDate }
  REVIEW { int rating
           string comment
           date createdAt }

Genres autorisés : roman, science, informatique, histoire, jeunesse, bd.

Livrables dans projet/ (tag jalon-1-xml) :

  1. catalogue.xml : au moins 15 livres, 8 auteurs et 5 adhérents, dans l’espace de noms urn:bibliotech:catalogue.
  2. catalogue.dtd : le document valide est accepté et un document erroné est refusé.
  3. catalogue.xsd : ISBN-13 contrôlé par un pattern, genre par une énumération, année entre 1450 et l’année courante, xs:key/xs:keyref entre livres et auteurs.
  4. requetes-xpath.md : 15 requêtes, chacune avec sa question, son expression et son résultat attendu.
  5. catalogue.xsl : page HTML du catalogue triée par genre puis par titre, avec le nombre d’exemplaires et un badge « indisponible » quand exemplaires = 0.

Commandes de vérification :

Fenêtre de terminal
xmllint --noout --valid catalogue.xml
xmllint --noout --schema catalogue.xsd catalogue.xml
npx xslt3 -s:catalogue.xml -xsl:catalogue.xsl -o:catalogue.html

Livrables dans projet/ (tag jalon-2-fullstack) :

  • api/ : Node.js + Express 5 + Zod + Prisma (SQLite).
    • Script npm run import : lit catalogue.xml et remplit la base.
    • Endpoints : GET/POST /books, GET/PATCH/DELETE /books/:isbn, GET /authors, POST /loans, PATCH /loans/:id/return.
    • Pagination (?page=&limit=), filtre ?genre=, recherche ?q=.
    • Toutes les entrées validées par Zod ; les erreurs sont renvoyées au format { error: { code, message, details? } }.
    • Règle métier : un emprunt est refusé si aucun exemplaire n’est disponible (code 409).
  • web/ : React + Vite.
    • Pages : catalogue (liste, filtre, recherche), détail d’un livre, formulaire d’ajout, emprunts d’un adhérent.
    • États chargement, erreur et vide gérés sur chaque page.
  • README.md : installation, variables d’environnement, déclaration de l’usage de l’IA.

Livrables dans projet/ (tag jalon-3-nosql) :

  1. MongoDB : collection reviews (ou avis imbriqués dans books, choix justifié dans le README), validation $jsonSchema, index adaptés, endpoint GET /stats en pipeline d’agrégation (note moyenne par genre, top 5 des livres).
  2. Redis : cache-aside sur GET /books avec invalidation à l’écriture, limite de 100 requêtes par minute par IP, classement des livres les plus empruntés en sorted set.
  3. Une fonctionnalité au choix :
    • Graphe (Neo4j) : « les lecteurs qui ont emprunté ce livre ont aussi emprunté… » ;
    • Séries temporelles : nombre d’emprunts par semaine dans une collection time series MongoDB ;
    • Vectoriel : recherche sémantique sur les résumés (embeddings et k-NN).
  4. ARCHITECTURE.md : quelles données dans quel SGBD, et pourquoi (une page maximum).
  • Code lisible, nommage cohérent, pas de secrets dans le dépôt (.env.example fourni).
  • Historique git régulier et partagé entre les deux membres (au moins un commit par séance de TP).
  • Démonstration de 5 min et une question individuelle par étudiant.