Aller au contenu principal

Notes de version — 3 avril 2026

Cette version complète le système d'application du dépassement de limite lors du rétrogradement — backend, frontend et e-mails — pour assurer que les utilisateurs ayant rétrogradé vers FREE ne puissent pas continuer à utiliser les ressources au-delà des limites de leur niveau.


Application du dépassement de limite lors du rétrogradement

Limites par niveau

NiveauMembresProjetsTâchesEntrées de temps
FREE3315100
PRO20Illimité701 000
ENTERPRISEIllimitéIllimitéIllimitéIllimité

Middleware Backend : requireNotOverLimitLocked

Un nouveau middleware requireNotOverLimitLocked a été appliqué à tous les points de terminaison d'écriture (projets, tâches, membres de l'équipe, entrées de temps).

Les utilisateurs dont le compte est verrouillé (isOverLimitLocked: true) reçoivent 403 LIMIT_EXCEEDED sur toute opération d'écriture.

Points de terminaison protégés :

Point de terminaisonEffet du verrouillage
POST /time-entries Création bloquée
PUT /time-entries/:id Modification bloquée
DELETE /time-entries/:id Suppression bloquée
POST /projects Création bloquée
POST /tasks Création bloquée
POST /team/invite Invitation bloquée
POST /timer/start 403 LIMIT_EXCEEDED

Blocage du démarrage du minuteur

Le démarrage du minuteur est également bloqué lorsque le nombre d'entrées de temps dans la période de facturation actuelle dépasse la limite du niveau.

Webhook de verrouillage des membres

Lors d'un événement de rétrogradement d'abonnement Stripe (customer.subscription.updated), un webhook verrouille automatiquement les membres excédentaires.

Logique de verrouillage :

  • Les membres sont triés par date d'adhésion (du plus récent au plus ancien)
  • Les membres excédentaires au-delà de la limite du niveau sont verrouillés
  • Les statuts active et pending comptent dans le total (correctif de bogue)

E-mails

E-mail de résumé de rétrogradement (au propriétaire) :

  • Résumé de tous les membres verrouillés
  • Liste des ressources excédentaires (projets, tâches)
  • Lien pour mettre à niveau l'abonnement

E-mail de notification d'accès limité (à chaque membre verrouillé) :

  • Informations sur les raisons du verrouillage
  • Détails de contact du propriétaire de l'espace de travail
  • Conseils pour obtenir un accès

Mises à jour Frontend

Bannière globale pour les utilisateurs verrouillés

AppShell.tsx affiche désormais une bannière persistante pour les utilisateurs dont le compte est verrouillé (isOverLimitLocked: true).

La bannière reste visible sur toutes les pages jusqu'à ce que le propriétaire mette à niveau l'abonnement.

Bannières de dépassement de limite par page

Des bannières d'alerte contextuelles ont été ajoutées aux pages suivantes :

PageConditionMessage
Page ProjetsprojectCount > maxProjects"Dépassement de limite de projets"
Page TâchestaskCount > maxTasks"Dépassement de limite de tâches"
Page Suivi du tempsentryCount > maxEntries"Dépassement de limite d'entrées"
Page ÉquipememberCount > maxMembers"Dépassement de limite de membres"

Correction stricte > : La bannière de la page Membres de l'équipe utilisait >= (affiché à la limite exacte). Elle utilise maintenant > (strictement au-dessus). Être à la limite est normal ; la dépasser est un état exceptionnel.

Projets excédentaires en lecture seule

ProjectDetailsPage et ProjectTasksTab affichent une bannière en lecture seule pour les projets marqués isExcessProject: true.

La création de tâches est désactivée sur les projets excédentaires.

États désactivés dans les sélecteurs

SélecteurConditionAffichage
Créer une tâche — ProjetisExcessProject: true🔒 Badge "Dépassement de limite"
Modifier une tâche — ProjetisExcessProject: true🔒 Badge "Dépassement de limite"
Créer une tâche — ResponsablesisOverLimitLocked: true🔒 Badge "Accès limité"
Modifier une tâche — ResponsablesisOverLimitLocked: true🔒 Badge "Accès limité"
Minuteur / Saisie manuelle — Projet/TâcheisExcessProject: true🔒 Badge "Dépassement de limite"

Corrections de bogues

Requête de verrouillage des membres : membres en attente inclus

markExcessMembersAsLocked() ne cherchait précédemment que les membres avec status: 'active'. Puisque les membres pending comptent également dans la limite d'utilisation dans UsageTrackingService, cela créait une incohérence entre la logique de verrouillage et le compteur.

Correction : La requête utilise désormais { status: { $in: ['active', 'pending'] } }.

Limites de niveau du modèle Unit corrigées

Le hook pré-sauvegarde du modèle Unit avait des valeurs codées en dur (FREE: 5 membres, PRO: 25 membres) qui étaient en conflit avec les valeurs faisant autorité dans tiers.config.ts.

Correction : Le hook pré-sauvegarde utilise maintenant les valeurs correctes : FREE: 3, PRO: 20.


Outils Développeur / Ops

Script manual-downgrade-to-free.mjs

Rétrograde manuellement une unité vers FREE dans la base de données — utile pour les tests et les flux de travail de support sans déclencher un vrai événement Stripe.

node scripts/manual-downgrade-to-free.mjs <unitBundle>

Actions : Définit le niveau, les limites, cancelAtPeriodEnd, currentPeriodEnd, et exécute markExcessMembersAsLocked() immédiatement.

Script test-downgrade-enforcement.mjs

Simule le cycle complet d'application de rétrogradement/mise à niveau sans Stripe.

node scripts/test-downgrade-enforcement.mjs <unitBundle> [status|downgrade|upgrade]
ScénarioEffet
statusAfficher l'état de verrouillage actuel de tous les membres
downgradeSimuler PRO → FREE, verrouiller les membres excédentaires
upgradeSimuler une mise à niveau, déverrouiller tous les membres

Résumé

ZoneModification
BackendVérification de limite startTimer() — minuteur déjà appliqué (confirmé)
BackendVérification de limite de membres inviteUser() — déjà appliqué (confirmé)
BackendMiddleware requireNotOverLimitLocked — appliqué à toutes les routes d'écriture
BackendmarkExcessMembersAsLocked inclut maintenant les membres pending
BackendLimites du hook pré-sauvegarde Unit.model.ts corrigées (FREE: 3, PRO: 20)
BackendLe webhook de rétrogradement envoie un e-mail récapitulatif au propriétaire
BackendLes membres verrouillés reçoivent un e-mail de notification d'accès limité
FrontendBannière de la page Membres de l'équipe : >=> (dépassement strict)
FrontendDialogue Créer une tâche : membres verrouillés affichés comme désactivés avec badge
FrontendDialogue Modifier une tâche : membres verrouillés affichés comme désactivés avec badge
FrontendDialogue Créer une tâche : projets excédentaires affichés comme désactivés avec badge
FrontendDialogue Modifier une tâche : projets excédentaires affichés comme désactivés avec badge
FrontendSélecteur Projet/Tâche : ressources verrouillées affichées comme désactivées avec badge
FrontendAppShell.tsx : bannière persistante globale pour les utilisateurs verrouillés
FrontendProjectDetailsPage : bannière en lecture seule sur les projets excédentaires
FrontendProjectTasksTab : bannière de désactivation de création de tâches sur les projets excédentaires
FrontendTimeTrackingPage : bannière de dépassement + blocage du widget minuteur
FrontendProjectsPage : bannière de dépassement
FrontendTaskManagementPage : bannière de dépassement
Scriptsmanual-downgrade-to-free.mjs ajouté
Scriptstest-downgrade-enforcement.mjs ajouté

Disponibilité : Tous les plans (l'application s'active automatiquement lors du rétrogradement)