Files
stripstream-librarian/openspec/changes/reading-progress/specs/reading-progress/spec.md
Froidefond Julien 648d86970f feat: suivi de la progression de lecture par livre
- API : nouvelle table book_reading_progress (migration 0016) et module
  reading_progress.rs avec GET/PATCH /books/:id/progress (token read)
- API : GET /books/:id enrichi avec reading_status, reading_current_page,
  reading_last_read_at via LEFT JOIN
- Backoffice : badge de statut (Non lu / En cours · p.N / Lu) sur la page
  de détail et overlay sur les BookCards
- OpenSpec : change reading-progress avec proposal/design/specs/tasks

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 21:53:52 +01:00

3.4 KiB

ADDED Requirements

Requirement: Consulter la progression de lecture d'un livre

Le système SHALL retourner la progression de lecture d'un livre via GET /books/:id/progress. Si aucune progression n'a été enregistrée, le système SHALL retourner { "status": "unread", "current_page": null, "last_read_at": null } sans erreur 404.

Scenario: Progression inexistante

  • WHEN le client appelle GET /books/:id/progress pour un livre sans progression enregistrée
  • THEN le système retourne HTTP 200 avec { "status": "unread", "current_page": null, "last_read_at": null }

Scenario: Progression existante — livre en cours

  • WHEN le client appelle GET /books/:id/progress pour un livre avec status = "reading"
  • THEN le système retourne HTTP 200 avec { "status": "reading", "current_page": <n>, "last_read_at": <timestamp> }

Scenario: Livre inexistant

  • WHEN le client appelle GET /books/:id/progress avec un UUID invalide ou inexistant
  • THEN le système retourne HTTP 404

Requirement: Mettre à jour la progression de lecture

Le système SHALL permettre de mettre à jour la progression de lecture via PATCH /books/:id/progress. Cette route SHALL être accessible avec un token read ou admin.

Scenario: Marquer un livre comme lu

  • WHEN le client envoie PATCH /books/:id/progress avec { "status": "read" }
  • THEN le système enregistre status = "read", current_page = null, last_read_at = NOW() et retourne HTTP 200 avec la progression mise à jour

Scenario: Marquer un livre comme en cours avec page courante

  • WHEN le client envoie PATCH /books/:id/progress avec { "status": "reading", "current_page": 42 }
  • THEN le système enregistre status = "reading", current_page = 42, last_read_at = NOW() et retourne HTTP 200 avec la progression mise à jour

Scenario: Réinitialiser la progression

  • WHEN le client envoie PATCH /books/:id/progress avec { "status": "unread" }
  • THEN le système enregistre status = "unread", current_page = null, last_read_at = NOW() et retourne HTTP 200 avec la progression mise à jour

Scenario: current_page manquant pour status reading

  • WHEN le client envoie PATCH /books/:id/progress avec { "status": "reading" } sans current_page
  • THEN le système retourne HTTP 422 avec un message d'erreur

Scenario: current_page invalide (zéro ou négatif)

  • WHEN le client envoie PATCH /books/:id/progress avec { "status": "reading", "current_page": 0 }
  • THEN le système retourne HTTP 422 avec un message d'erreur

Scenario: current_page ignoré pour status non-reading

  • WHEN le client envoie PATCH /books/:id/progress avec { "status": "read", "current_page": 42 }
  • THEN le système enregistre current_page = null (la valeur fournie est ignorée)

Scenario: Livre inexistant

  • WHEN le client envoie PATCH /books/:id/progress avec un UUID de livre inexistant
  • THEN le système retourne HTTP 404

Requirement: last_read_at mis à jour à chaque modification

Le système SHALL mettre à jour last_read_at à l'horodatage courant à chaque appel PATCH /books/:id/progress, quel que soit le statut.

Scenario: last_read_at actualisé sur tout changement

  • WHEN le client envoie PATCH /books/:id/progress avec n'importe quel statut valide
  • THEN last_read_at dans la réponse est égal à l'heure de la requête (NOW())