5.2 KiB
o# Feature: Archivage de tickets et de groupes
Résumé
Permettre d'archiver des tickets individuels (quand leur statut est final) et des groupes entiers (quand tous leurs tickets sont en statut final). Les éléments archivés disparaissent de la vue kanban et sont consultables via une page dédiée "Archives" dans le projet.
Modèle de données
TaskStatus — ajout isFinal
- Nouveau champ
isFinal: bool(defaultfalse) - Mis à
truesur le statut "Terminé" dans les fixtures - Exposé en lecture et écriture via API Platform (groupes de sérialisation
task_status:read,task_status:write, ettask:read) - Permet d'identifier dynamiquement quels statuts autorisent l'archivage
Task — ajout archived
- Nouveau champ
archived: bool(defaultfalse) - Filtre API Platform
BooleanFiltersurarchivedpour requêter?archived=falseou?archived=true - Le kanban charge les tickets avec
archived=false - La page archives charge les tickets avec
archived=true
TaskGroup — ajout archived
- Nouveau champ
archived: bool(defaultfalse) - Filtre API Platform
BooleanFiltersurarchived - Le kanban et le filtre groupe n'affichent que les groupes
archived=false
Migration
Une migration Doctrine unique pour les 3 champs (task_status.is_final, task.archived, task_group.archived).
Backend — logique métier
Archivage de groupe (bulk)
L'archivage d'un groupe est une opération frontend multi-appels :
- PATCH chaque ticket du groupe avec
{ archived: true } - PATCH le groupe avec
{ archived: true }
Pas de endpoint custom côté backend — on réutilise les PATCH existants.
Permissions
L'archivage suit le modèle de permissions existant : les opérations PATCH sur Task et TaskGroup requièrent ROLE_ADMIN. Pas de règle supplémentaire.
Pas de validation backend sur isFinal
La règle "archiver seulement si statut final" est appliquée côté frontend (visibilité du bouton). Pas de State Processor dédié — cohérent avec le reste de l'app qui ne valide pas les transitions de statut côté serveur.
Frontend
TaskDrawer — archivage et modale suppression
Bouton "Archiver" :
- Visible uniquement quand le ticket a un statut avec
isFinal: true - PATCH
{ archived: true }sur le ticket - Si un timer est actif sur ce ticket, l'arrêter avant d'archiver
- Ferme le drawer et rafraîchit la liste des tickets
Bouton "Désarchiver" :
- Visible quand on consulte un ticket archivé (depuis la page archives)
- PATCH
{ archived: false } - Ferme le drawer et rafraîchit la page archives
Modale de confirmation de suppression :
- Déclenchée au clic sur "Supprimer" dans le TaskDrawer
- Message : "Êtes-vous sûr de vouloir supprimer ce ticket ? Cette action est irréversible."
- Deux boutons : "Annuler" / "Supprimer" (style destructif, rouge)
- Suit le pattern existant de
ConfirmDeleteStatusModal
Page Archives — /projects/[id]/archives
- Nouveau sous-onglet "Archives" dans la navigation projet (à côté de "Groupes")
- Liste des tickets archivés du projet (
archived=true) - Colonnes affichées : numéro, titre, statut, groupe, assigné
- Clic sur un ticket → ouvre le TaskDrawer (avec bouton "Désarchiver")
- Filtre par groupe possible
Page Groupes — archivage de groupes
Vue par défaut : affiche uniquement les groupes non archivés.
Toggle "Voir les groupes archivés" : bascule pour afficher les groupes archivés.
Bouton "Archiver" sur un groupe :
- Visible uniquement si le groupe a au moins un ticket ET que tous ses tickets ont un statut
isFinal: true(un ticket sans statut bloque l'archivage) - Archive tous les tickets du groupe puis le groupe lui-même (appels PATCH séquentiels)
- Rafraîchit la liste
Bouton "Désarchiver" sur un groupe archivé :
- Désarchive le groupe + tous ses tickets (écrase l'état individuel des tickets)
- Rafraîchit la liste
Admin — toggle isFinal sur les statuts
- Ajout d'un checkbox/toggle "Statut final" dans l'AdminStatusTab (création et édition de statuts)
- Permet aux admins de configurer quels statuts sont considérés comme finaux
Kanban — filtrage
- Le filtre groupe dans le dropdown n'affiche que les groupes
archived=false - Les tickets
archived=truesont exclus du kanban
Time tracking
- Les entrées de temps liées à des tickets archivés restent visibles dans les vues time-tracking (pas de changement)
DTOs
TaskStatus
Ajout du champ isFinal: boolean dans les types TaskStatus et TaskStatusWrite.
Task
Ajout du champ archived: boolean dans les types Task et TaskWrite.
TaskGroup
Ajout du champ archived: boolean dans les types TaskGroup et TaskGroupWrite.
Traductions (i18n)
Clés à ajouter dans fr.json :
task.archive/task.unarchivetask.delete_confirm_title/task.delete_confirm_messagegroup.archive/group.unarchivegroup.show_archived/group.hide_archivedproject.tabs.archivesstatus.is_final
Hors périmètre
- Historique/date d'archivage (pourra être ajouté plus tard avec un champ
archivedAt) - Archivage automatique (cron/scheduler)
- Archivage en masse depuis la page archives
- Verrouillage des tickets archivés (modification de statut, etc.)