Skip to content

fix(tasks): ancrer la récurrence hebdomadaire sur le jour de semaine voulu - #31

Merged
SKOHscripts merged 1 commit into
mainfrom
claude/recurring-weekly-tasks-j74deb
Sep 5, 2026
Merged

SKOHscripts merged 1 commit into
mainfrom
claude/recurring-weekly-tasks-j74deb

Conversation

@SKOHscripts

Copy link
Copy Markdown
Owner

Résumé

Corrige la récurrence hebdomadaire des tâches (recurrence="weekly"), qui dérivait vers le jour de semaine de la complétion au lieu de revenir sur le jour voulu par l'utilisateur.

Bug : une tâche « tous les jeudis » cochée en retard un vendredi revenait le vendredi suivant, pas le jeudi suivant. spawn_next_occurrence calculait next_deadline("weekly", base) = base + 7 jours, où base = max(deadline, aujourd'hui) — en cas de complétion tardive, base valait aujourd'hui (le jour de la complétion), pas l'échéance d'origine, et l'occurrence suivante héritait de ce nouveau jour de semaine. La dérive était cumulative : chaque complétion tardive décalait un peu plus le jour réel de la tâche.

Les autres règles (daily, weekdays, monthly) et la récurrence calendaire (monthly_on_day, « le … du mois ») étaient déjà correctes — non modifiées.

Correctif : ajout de Task.recurrence_day_of_week (0=lundi..6=dimanche), miroir de recurrence_day_of_month déjà utilisé pour la récurrence calendaire. Il est posé automatiquement depuis deadline par la route d'édition dès que recurrence == "weekly" (pas de nouveau champ de formulaire : le jour se déduit sans ambiguïté de la deadline déjà saisie). next_deadline/spawn_next_occurrence recalent désormais toujours l'échéance suivante sur ce jour ancré, et le reportent sur l'occurrence créée pour que l'ancre survive à plusieurs complétions tardives consécutives. Repli sur deadline.weekday() pour les tâches existantes créées avant l'ajout du champ (recurrence_day_of_week IS NULL en base) — pas de backfill nécessaire, correction effective dès la première complétion.

Changements

  • app/tasks_models.py : nouveau champ Task.recurrence_day_of_week.
  • app/tasks_db.py : migration légère (ALTER TABLE) pour les bases SQLite existantes.
  • app/tasks_recurrence.py : next_deadline prend un paramètre day_of_week optionnel ; spawn_next_occurrence calcule l'ancre, la transmet, et la propage sur l'occurrence suivante (+ paramètre today optionnel pour la testabilité déterministe, même patron que ensure_calendar_occurrences).
  • app/main.py : la route d'édition pose/efface recurrence_day_of_week selon la récurrence choisie.
  • docs/spec/recurrence.md, docs/spec/modele-donnees.md : spec de domaine mise à jour (bijectivité code/spec, décisions tracées).
  • Tests : nouveaux cas côté tests/test_tasks_recurrence.py (dont la reproduction exacte du bug signalé) et tests/test_kairos_route.py.

Test plan

  • pytest tests/test_tasks_recurrence.py tests/test_kairos_route.py (nouveaux tests + existants) — verts.
  • Suite complète (pytest, hors test_settings_route.py/test_settings_store.py — échecs préexistants sur cette machine, dépendance native _cffi_backend absente, sans rapport avec ce changement) — 496 tests verts.
  • ruff check sur les fichiers modifiés — propre.
  • Vérification manuelle : base SQLite fraîche crée bien la colonne ; base existante sans la colonne la reçoit via la migration légère.

🤖 Generated with Claude Code

https://claude.ai/code/session_01QJgD9rNBUcU34f1CHzxtK5


Generated by Claude Code

…voulu

Une tâche récurrente hebdomadaire complétée un autre jour que son jour
d'origine (en retard, typiquement) dérivait vers le jour de la complétion :
spawn_next_occurrence calculait next_deadline("weekly", base) = base + 7
jours, où base = max(deadline, aujourd'hui) — si complétée en retard, base
valait aujourd'hui, pas l'échéance voulue, et l'occurrence suivante héritait
de ce nouveau jour de semaine, dérivant à chaque complétion tardive.

Ajoute Task.recurrence_day_of_week (mirroring recurrence_day_of_month),
posé automatiquement depuis deadline par la route d'édition quand
recurrence == "weekly" (pas de champ de formulaire dédié, jour déjà connu
via la deadline). next_deadline et spawn_next_occurrence recalent
désormais toujours sur ce jour ancré, avec repli sur deadline.weekday()
pour les tâches existantes jamais repassées par l'édition depuis l'ajout
du champ. L'ancre se propage d'occurrence en occurrence, sans dérive
cumulative même sur plusieurs complétions tardives consécutives.

Récurrences quotidienne/jours ouvrés/mensuelle et récurrence calendaire
("le … du mois") : déjà correctes, non modifiées.

Spec de domaine (docs/spec/recurrence.md, modele-donnees.md) mise à jour
en conséquence, avec traçage de la décision de dériver l'ancre depuis
deadline plutôt que d'ajouter un sélecteur de formulaire redondant.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QJgD9rNBUcU34f1CHzxtK5
@SKOHscripts
SKOHscripts marked this pull request as ready for review September 5, 2026 20:33
@SKOHscripts
SKOHscripts merged commit ada773e into main Sep 5, 2026
1 check passed
@SKOHscripts
SKOHscripts deleted the claude/recurring-weekly-tasks-j74deb branch September 5, 2026 20:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants