Référence: Individual Capabilities And Quotas¶
Objectif¶
Poser un document de référence stable pour le modèle cible V1 des capabilities et quotas du compte individual.
Ce document couvre:
- le socle runtime déjà en place autour du plan effectif
- l'existant réel sur la solidarité
- les manques actuels sur
event,event registrationetevent proposal - le catalogue canonique V1 retenu et implémenté côté backend
- les règles d'enforcement métier attendues
Statut: référence V1 implémentée côté backend, valeurs plans encore à peupler via admin/front Date de mise à jour: 2026-04-12
Périmètre¶
- Compte
individualuniquement - Pas de traitement du modèle
prosauf pour éviter les collisions de vocabulaire - Point de vue "capabilities et quotas liés à la souscription effective"
- Cycle temporel de référence: mois de souscription ancré sur
person_subscriptions.cycle_anchor_at
Décisions Retenues¶
- Le runtime
individualrepose sur la souscription effective explicite, pas sur un fallback implicite vers le plan par défaut. - V1 ne retient pas de quotas
future_*. - V1 retient des quotas mensuels de consommation d'actions réalisées.
- V1 retient aussi des quotas de gabarit pour limiter la taille maximale d'un
eventou d'uneevent_proposal. event_proposaldoit avoir son propre quota de création, car une proposal est déjà une action sortante vers d'autres utilisateurs.- Pour
event_proposal, limiter seulement le nombre de créations ne suffit pas: il faut aussi borner le nombre de places, et idéalement le nombre d'invitées.
État Actuel Du Code¶
Plan effectif¶
Source de vérité actuelle:
person_subscriptionsporte la souscription explicite de la personneservices/subscription/active_plan.gocharge la souscription et le plan effectifs- le signup matérialise une vraie souscription sur le plan par défaut
Points importants:
- le plan par défaut sert à attribuer une souscription gratuite initiale
- le runtime ne doit plus "inventer" un plan gratuit si la souscription explicite manque
- le mois de souscription se calcule à partir de
cycle_anchor_at
Références code:
models/person_subscription.goservices/subscription/active_plan.goservices/subscription/person_subscription_write.goservices/signup/service.go
Capabilities existantes¶
Le plan porte aujourd'hui uniquement deux familles de droits:
- des droits solidarité "person" par module et par intention
- des capabilities organisateur pour la configuration de la solidarité d'un event
Catalogue actuel côté plan:
hosting.offerhosting.requestcarpool.offercarpool.requestequipment.offerequipment.requestenable_hostingenable_carpoolenable_equipmentallow_external_helpers
Références code:
models/subscription_plan.gomodels/solidarity_rights.gomodels/solidarity_event_capabilities.goservices/subscription/plan_parsing.goservices/subscription/plan_format.go
Quotas existants¶
Les quotas plans existants sont aujourd'hui strictement limités au domaine solidarité.
Catalogue actuel:
module=hosting|carpool|equipmentmetric=open_requestsmetric=consumed_completedperiod=noneperiod=subscription_month
Usage runtime:
open_requestsborne le stock de demandesOPENconsumed_completedborne le nombre d'aides complétées pendant le mois de souscription
Des bonus de quotas peuvent être ajoutés via benefit_tiers.
Références code:
models/plan_quota.gomodels/benefit_tier.goservices/solidarity/resolver.go
Overrides existants¶
Overrides réellement branchés au runtime:
- overrides de droits solidarité au niveau personne
- overrides de droits solidarité au niveau event
Override présent en modèle mais pas branché au runtime actuel:
person_solidarity_event_capabilities_overrides
Références code:
models/person_solidarity_rights_override.gomodels/event_solidarity_rights_override.gomodels/person_solidarity_event_capabilities_override.goservices/solidarity/resolver.go
Exposition au front¶
Le front peut aujourd'hui lire:
- le plan effectif courant via
GET /me/subscription - la configuration admin d'un plan via
GET /subscription-plansetGET /subscription-plans/{idPlan} - les organizer capabilities solidarité via
GET /solidarity/organizer-capabilities - les self capabilities solidarité request/offer sur un event
Expose réellement aujourd'hui:
/me/subscriptionexpose le plan effectif, lesrights, lesorganizerCapabilities, lescapabilitiescanoniques, lesquotaset lequotaUsagedes quotas mensuels consommables- les endpoints admin
subscription-plansexposentrights,organizerCapabilities,capabilitiescôtéindividual,quotaslegacy solidarité etindividualQuotas - le snapshot riche
solidarity.GetCapabilities()existe mais n'est pas exposé
Doc front dédiée:
Références code:
controllers/subscription_plans.gomodels/subscription_plan_dto.gocontrollers/solidarity_organizer_capabilities.gocontrollers/event.goservices/solidarity/self_capabilities_service.goservices/solidarity/resolver_types.go
Enforcement runtime réel¶
Ce qui est déjà contrôlé au moment des actions:
- création de
solidarity_request - création de
solidarity_proposal - completion des assignments solidarité
- activation/configuration de la solidarité sur un event
- création d'event
- inscription à un event
- création d'event proposal
- patch
event proposalsur les capsmaxSeats/ invitées - auto-conversion
event proposal -> eventavec revérification du create event
Références code:
services/solidarity/request_service.goservices/solidarity/proposal_service.goservices/solidarity/assignment_service.goservices/solidarity/event_config_service.goservices/eventsvc/service.goservices/eventsvc/participation.goservices/eventproposal/write.goservices/eventproposal/event_creator.go
Manques À Combler Côté Individual¶
Valeurs plans encore absentes¶
- peupler les vraies valeurs
individualplan par plan - vérifier les choix produit finaux à travers l'admin/front avant seed ou migration définitive
Lectures runtime encore absentes¶
- exposer
used/remainingsi le front veut afficher la consommation réelle des quotas mensuels - exposer un catalogue dynamique si l'on veut éviter le hardcode front des clés autorisées
Points de contrat à garder explicites¶
- côté admin,
rightsetorganizerCapabilitiesrestent la source de vérité pour la solidarité - côté admin,
capabilitiesne porte que le sous-ensembleindividual - côté self,
GET /me/subscriptionexpose un cataloguecapabilitiescanonique de lecture et desquotasde limite seulement
Références code:
controllers/subscription_plans.goservices/eventproposal/write.goservices/eventproposal/event_creator.go
Modèle Cible V1¶
Principe général¶
Le modèle cible V1 doit distinguer 3 choses:
- une capability booléenne: l'action existe pour ce plan
- un quota de consommation mensuel: combien de fois l'action peut être réalisée sur le mois de souscription
- un quota de gabarit: taille maximale autorisée pour l'objet créé ou modifié
V1 ne retient pas de quotas de stock futur.
Catalogue canonique V1 des capabilities stockées¶
Capabilities de participation/event:
events.individual.createevents.registerevent_proposals.create
Capabilities de configuration event solidarité:
event_solidarity.hosting.enableevent_solidarity.carpool.enableevent_solidarity.equipment.enableevent_solidarity.external_helpers.allow
Capabilities solidarité personne:
solidarity.hosting.requestsolidarity.hosting.offersolidarity.carpool.requestsolidarity.carpool.offersolidarity.equipment.requestsolidarity.equipment.offer
Capabilities dérivées mais non stockées¶
Ces capabilities peuvent être dérivées à la lecture et ne doivent pas devenir la source de vérité:
event_solidarity.configuresolidarity.requestsolidarity.offer
Mapping de transition depuis l'existant¶
hosting.request->solidarity.hosting.requesthosting.offer->solidarity.hosting.offercarpool.request->solidarity.carpool.requestcarpool.offer->solidarity.carpool.offerequipment.request->solidarity.equipment.requestequipment.offer->solidarity.equipment.offerenable_hosting->event_solidarity.hosting.enableenable_carpool->event_solidarity.carpool.enableenable_equipment->event_solidarity.equipment.enableallow_external_helpers->event_solidarity.external_helpers.allow
Catalogue canonique V1 des quotas¶
Quotas mensuels de consommation¶
Events¶
events.individual.create_per_subscription_month- 1 unité consommée quand un event est créé avec succès
-
pas de remboursement si l'event est ensuite supprimé ou annulé
-
events.register_per_subscription_month - 1 unité consommée à la première inscription réussie sur un event donné pendant la période courante
- un
unregisterne rembourse pas - un
registerultérieur sur le même event dans la même période ne doit pas reconsommer
Event proposals¶
event_proposals.create_per_subscription_month- 1 unité consommée quand une proposal est créée avec succès
- pas de remboursement si la proposal expire, est annulée ou ne se convertit jamais
Solidarité¶
solidarity.hosting.requests.completed_per_subscription_monthsolidarity.carpool.requests.completed_per_subscription_monthsolidarity.equipment.requests.completed_per_subscription_month
Ces quotas correspondent à l'actuel consumed_completed.
Quotas de gabarit¶
Events¶
events.individual.max_seats_per_event- borne la valeur maximale de
maxSeats - doit être enforce à la création et au patch
Event proposals¶
event_proposals.max_seats_per_proposal- borne la valeur maximale de
maxSeats -
doit être enforce à la création et au patch
-
event_proposals.max_invitees_per_proposal - borne le nombre total d'invitées uniques d'une proposal
- doit être enforce à la création et sur le patch add-only des invitées
- ce quota est retenu car
max_seats_per_proposalseul ne suffit pas à borner la surface de spam
Solidarité¶
solidarity.hosting.requests.opensolidarity.carpool.requests.opensolidarity.equipment.requests.open
Ces quotas correspondent à l'actuel open_requests.
Règles D'Enforcement V1¶
Event create¶
Service cible:
services/eventsvc.Service.CreateEventV2
Enforcement attendu:
- capability
events.individual.create - quota
events.individual.create_per_subscription_month - quota de gabarit
events.individual.max_seats_per_event
Event patch¶
Service cible:
services/eventsvc.Service.UpdateEvent
Enforcement attendu:
- si
maxSeatsaugmente ou est modifié: - revalider
events.individual.max_seats_per_event - le patch ne doit pas reconsommer le quota mensuel de création
Event register¶
Service cible:
services/eventsvc.Service.RegisterForEvent
Enforcement attendu:
- capability
events.register - quota
events.register_per_subscription_month - consommation idempotente par
(person_id, event_id, periode_de_souscription)
Event proposal create¶
Service cible:
services/eventproposal.Service.Create
Enforcement attendu:
- capability
event_proposals.create - quota
event_proposals.create_per_subscription_month - quota de gabarit
event_proposals.max_seats_per_proposal - quota de gabarit
event_proposals.max_invitees_per_proposal
Event proposal patch¶
Service cible:
services/eventproposal.Service.Patch
Enforcement attendu:
- si
maxSeatschange: - revalider
event_proposals.max_seats_per_proposal - si des invitées sont ajoutées:
- revalider
event_proposals.max_invitees_per_proposal - le patch ne doit pas reconsommer le quota mensuel de création
Event proposal conversion vers event¶
Services cibles:
services/eventproposal.Service.maybeAutoConvertProposalToEventservices/eventproposal.EventCreatorImpl.CreateEventFromProposalSlot
Enforcement attendu:
- la conversion doit revalider la capability
events.individual.create - la conversion doit consommer
events.individual.create_per_subscription_monthsi aucun event n'a encore été créé pour cette proposal - la conversion ne doit pas bypass
events.individual.max_seats_per_event - une proposal conforme côté proposal ne doit pas pouvoir produire un event non conforme côté event
Recommandation Nette Bool vs Quota¶
Doit être une capability booléenne:
events.individual.createevents.registerevent_proposals.create- toutes les capabilities
event_solidarity.* - toutes les capabilities
solidarity.*.request|offer
Doit être un quota mensuel de consommation:
events.individual.create_per_subscription_monthevents.register_per_subscription_monthevent_proposals.create_per_subscription_monthsolidarity.*.requests.completed_per_subscription_month
Doit être un quota de gabarit:
events.individual.max_seats_per_eventevent_proposals.max_seats_per_proposalevent_proposals.max_invitees_per_proposalsolidarity.*.requests.open
Hors Scope V1¶
- quotas
future_* - remboursement de quota après delete/cancel/unregister
- quotas helper côté solidarité
- quota mensuel sur les updates d'event ou de proposal
- monétisation ou quota spécifique des réponses aux
event_proposals
Notes De Mise En Œuvre¶
- Le modèle actuel
SubscriptionPlanetPlanQuotaest encore solidarité-centrique. - L'implémentation V1 a introduit un catalogue
individualdédié sans casser le runtime solidarité déjà en place. - Tant que la migration n'est pas faite, il faut garder une couche de mapping explicite entre l'ancien catalogue solidarité et le nouveau catalogue canonique
individual. - Les valeurs effectives des plans
individualne sont pas encore peuplées en base à la date de cette mise à jour.