Repository navigation
Appliquer les parcours Premium, le déblocage à l'unité et la limite anti-spam dans l'API #66
Description
Contexte
Epic : #11
Maquette : E-17, E-05 · validées le 2026-09-29 (D-072 à D-074)
Compte-et-Monetisation · API · Ecrans › E-05 · D-002, D-014
Requalifié par D-014 : les « parcours signature » deviennent des parcours Premium. Premium = routes.access = premium, réservé aux abonnés, quel que soit le créateur ; Signature = parcours de l'équipe Widoo (is_official), sans effet sur l'accès. Les deux se cumulent.
À trancher par Ilan : la règle d'attribution de Premium, c'est-à-dire quels parcours deviennent Premium et qui en décide au-delà du rôle editor.
Requalifié par D-023 : freemium recentré, tout est gratuit et sans limite, favoris et programmations compris, sauf les parcours Premium.
Révisé par D-073 (décision d'Ilan du 2026-09-28, Compte-et-Monetisation › Freemium) : la création est gratuite et sans limite ; l'ancienne règle free.max_routes (premier parcours offert) et le 402 create_limit sont abandonnés. Seule limite : l'anti-spam max_pending_routes.
Comportement attendu
- Limite anti-spam dans
settings:max_pending_routes(3 parcours en attente de modération au plus par compte), réglable sans déploiement ; au-delà,POST /routes/:id/submitrépond 429rate_limited(D-073). Aucune cléfree.max_routes. - Plus aucun quota de favoris ni de programmations :
PUT /me/favorites/:idetPOST /me/plannedn'ont plus de limite, et le codequota_exceededdisparaît.POST /me/plannedsur un parcoursaccess = premiumrenvoie toujours 402premium_required. POST /routesn'a aucune limite de création, compte gratuit ou Premium ;details.reason = create_limitn'est plus émis.GET /meexposeplanetplanExpiresAt.canCreateRoutesort du périmètre de ce ticket : la page API le décrit encore selon l'ancienne règle, son sort est à trancher par DESIGN (Aligner Modele-de-Donnees et API sur la création sans limite (D-073) #383).routes.accessmodifiable par le rôleeditor;RouteCardexpose séparément Signature (is_official) et Premium (access).- Même règle de réduction côté serveur que
GET /routes/:id(Exposer GET /routes/:id et /routes/:id/timeline, stocker computed #36) pour un non-abonné sur un parcours Premium. - Un abonné qui repasse en gratuit garde tous ses parcours, publiés ou non, et continue d'en créer ; les parcours Premium redeviennent verrouillés.
- Le commentaire de
packages/shared/src/schemas/route.ts(l. 47) décrit encorepremiumcomme « signature route » : le corriger selon D-014. - Go d'un parcours Premium sans abonnement : comportement dessiné avec la planche 2 de Design — E-07 et E-15 journée en cours et fin de parcours #74, à reprendre ici une fois validée (D-029).
- Sortie d'un parcours Premium (D-033) : si l'abonnement prend fin pendant la sortie, elle continue sans interruption ; relancer ensuite un parcours Premium sans abonnement ouvre E-17.
Critères d'acceptation
- Tests : un compte gratuit crée plusieurs parcours sans 402 ; un compte qui a 3 parcours en attente de modération reçoit 429
rate_limitedà la quatrième soumission ; un parcours sorti de l'attente libère la place - Le seuil
max_pending_routeschange sans redéploiement - Favoris et programmations sans limite pour tous ; plus aucune occurrence de
quota_exceededdans l'API,packages/sharedet l'app - Pass 7 jours et déblocage à l'unité entrent dans la règle de droit au parcours, calculée en un seul endroit (livrée par Retirer les coordonnées des étapes d'un parcours Premium de la recherche #161) et partagée par la recherche et la fiche : tests, pour un pass actif et pour un parcours débloqué à l'unité, card de
/routes/searchdéverrouillée (isLocked: false, toutes les étapes) et fiche/routes/:idcomplète ; pass terminé → card verrouillée et fiche réduite (D-075)
Activity
[-]Appliquer les quotas gratuits et les parcours signature dans l'API[/-][+]Appliquer les quotas gratuits et les parcours Premium dans l'API[/+][-]Appliquer les quotas gratuits et les parcours Premium dans l'API[/-][+]Appliquer la limite de création et les parcours Premium dans l'API[/+]IlanAMG commentedon Sep 25, 2026
D-044 (https://github.com/Inprogress-Agency/widoo-app/wiki/Design-Changelog) : débloquer le parcours dès le webhook RevenueCat, y compris après un achat d'abord en attente de validation.
[-]Appliquer la limite de création et les parcours Premium dans l'API[/-][+]Appliquer les parcours Premium, le déblocage à l'unité et la limite anti-spam dans l'API[/+]IlanAMG commentedon Sep 28, 2026
Révision du 2026-09-28 (décision d'Ilan, https://github.com/Inprogress-Agency/widoo-app/wiki/Compte-et-Monetisation#freemium-mvp) :
create_limit(402) surPOST /routessettings.max_pending_routes), 429rate_limitedsursubmitusers.plan,plan_expires_at) ou ligneroute_unlockspour ce parcoursroute_unlocks; pass →plan_expires_at= achat + 7 joursVoir Modele-de-Donnees › route_unlocks. Écrans dans Design — révision du freemium : création gratuite, pass 7 jours et déblocage à l'unité (E-17, E-05, E-08, E-09) #210.
IlanAMG commentedon Sep 28, 2026
Règle d'attribution Premium (décision d'Ilan du 2026-09-28, https://github.com/Inprogress-Agency/widoo-app/wiki/Compte-et-Monetisation#freemium-mvp) : automatique,
access = premiumsi 4 étapes ou plus, ou au moins 50 avis avec une note moyenne > 4,5 ; seuils danssettings(premium.min_steps,premium.min_ratings,premium.min_rating), recalcul à la publication et chaque nuit ; une sortie déjà programmée garde l'accès si le parcours devient Premium.IlanAMG commentedon Sep 29, 2026
D-072 (https://github.com/Inprogress-Agency/widoo-app/wiki/Design-Changelog) :
plan_expires_at= achat + 7 jours exactement) ;route_unlocks) ;logIn).Points techniques à trancher ici : type de produit du déblocage (un seul produit à 1,99 € rattaché au parcours côté serveur, consommable, ou un non consommable par parcours, impossible à l'échelle) ; restauration du pass et des déblocages sans compte (reçus du store via RevenueCat).
IlanAMG commentedon Sep 29, 2026
D-073 (https://github.com/Inprogress-Agency/widoo-app/wiki/Design-Changelog) :
plan_expires_at+= 7 jours (au bout du pass en cours, pas depuis l'achat)users.idà la connexion ; les déblocages ne sont pas restaurables par le store, ils suivent le compterate_limitedà la soumission au-delà de 3 parcours en relecturePaulThiberville commentedon Sep 29, 2026
📋 Report de D-075 (2026-09-29, correction de D-066 sur la card de recherche Premium, décision de Paul au nom d'Ilan ; voir #161) : critère ajouté au corps. Le pass 7 jours et le déblocage à l'unité entrent dans la règle de droit au parcours livrée par #161, calculée en un seul endroit et partagée par
/routes/searchet/routes/:id.IlanAMG commentedon Sep 29, 2026
Décision d'Ilan (2026-09-29) sur le rattachement des achats faits sans compte :
logIn), les achats de l'identifiant anonyme passent au compte connecté, y compris si ce compte n'est pas celui de l'acheteur (téléphone partagé) ;route_unlocksde l'identifiant anonyme sont transférées versusers.idau même moment ;feat(api): decide the right to a route in one place, per caller
PaulThiberville commentedon Oct 13, 2026
📋 Amendement MANAGER du 2026-10-13, suite à la découverte de CODE sur l'Inbox : le corps reprend enfin la révision du 2026-09-28 (D-073, Compte-et-Monetisation › Freemium), déjà annoncée en commentaire mais jamais reportée dans le corps.
free.max_routes, le 402create_limitsurPOST /routes, les critères « le deuxième parcours reçoit 402create_limit» et « le seuilfree.max_routeschange sans redéploiement », et « ne peut plus en créer » après la fin de l'abonnement.max_pending_routes(3, 429rate_limitedsursubmit), avec ses critères.canCreateRoutedeGET /mesort du périmètre : la page API le décrit selon l'ancienne règle, DESIGN tranche dans Aligner Modele-de-Donnees et API sur la création sans limite (D-073) #383.Le ticket reste
status:ready: tout son périmètre restant est spécifié et validé.PaulThiberville commentedon Oct 14, 2026
🔨 Démarrage — plan, sur la branche
issue/66-premium-access-anti-spam:route_unlocks(migration additive0007, Modele-de-Donnees › route_unlocks) et droit au parcours étendu au déblocage à l'unité danscanAccessRoute, seul endroit de la règle, lu par la recherche (cards) et par la programmation (POSTetPATCH /me/planned). Le pass 7 jours passe parusers.planetplan_expires_at, déjà lus par la règle : tests d'intégration ajoutés pour un pass en cours, un pass terminé et un parcours débloqué à l'unité.max_pending_routes(3 par défaut, lue danssettingsà chaque soumission) : règle danspackages/shared, contrôle côté API qui répond 429rate_limited, testé contre la base.POST /routes/:id/submitn'existe pas encore (Gérer PUT /routes/:id/steps, submit, statuts et lien privé #48) : le contrôle est livré prêt à brancher dans sa transaction.quota_exceededdepackages/sharedet de l'API, correction du commentaire « signature route » deroute.ts(D-014).Hors de cette PR, et signalé dans le rapport :
canCreateRoute(attend DESIGN dans #383, comportement actuel conservé : le champ n'existe pas dansGET /me),GET /routes/:id(#36), le webhook RevenueCat (#67), l'édition deroutes.accesspareditor(aucune route d'édition n'existe encore).PaulThiberville commentedon Oct 14, 2026
✅ Vérifié en staging le 2026-10-14 vers 11:20Z (vérification en lecture par l'orchestrateur, consignée par MANAGER) :
deploy-staging.ymlvert sur4d2f320(PR #410), exécutionwidoo-api-migrate-74s7zréussie à 11:10:14Z (migration0007,route_unlocks), révision Cloud Runwidoo-api-00156-yaj,/v1/healthok. Status du Project → Terminés.