Aller au contenu

Individual Subscription For Front

Ce document décrit ce que les fronts doivent ajouter ou adapter après l'introduction du modèle individual sur les capabilities et quotas.

Périmètre:

  • configuration admin des plans perso
  • lecture du plan courant côté utilisateur
  • impacts front sur les actions event et event_proposal

Les exemples ci-dessous utilisent le préfixe /v1/web/api. Les mêmes routes existent aussi sous /v1/mobile/api et /v1/dev/api.

État Des Endpoints

Aucun nouvel endpoint n'est requis pour la V1 individual.

Les routes à utiliser existent déjà:

  • GET /subscription-plans
  • GET /subscription-plans/{idPlan}
  • POST /subscription-plans
  • PATCH /subscription-plans/{idPlan}
  • GET /me/subscription

Les actions produit déjà branchées sur ce modèle sont:

  • POST /events
  • PATCH /events/{idEvent}
  • POST /events/{idEvent}/register
  • POST /event-proposals
  • PATCH /event-proposals/{idEventProposal}

Ce Que Le Front Admin Doit Gérer

Le front admin doit continuer à gérer 4 blocs distincts sur un plan:

  • rights: droits solidarité personne
  • organizerCapabilities: capabilities de configuration solidarité sur event
  • capabilities: capabilities individual uniquement
  • quotas et individualQuotas: limites numériques

Important:

  • sur les endpoints admin, capabilities ne sert qu'au sous-ensemble individual
  • le front ne doit pas essayer d'y poster les capabilities canoniques solidarité
  • les droits solidarité restent portés par rights
  • les capabilities de configuration event solidarité restent portées par organizerCapabilities

Catalogue Admin En Écriture

rights

Valeurs supportées:

  • hosting.offer
  • hosting.request
  • carpool.offer
  • carpool.request
  • equipment.offer
  • equipment.request

organizerCapabilities

Valeurs supportées:

  • enable_hosting
  • enable_carpool
  • enable_equipment
  • allow_external_helpers

capabilities

Valeurs supportées:

  • events.individual.create
  • events.register
  • event_proposals.create

quotas

Le champ legacy quotas reste réservé au domaine solidarité.

Format:

{
  "module": "hosting|carpool|equipment",
  "metric": "open_requests|consumed_completed",
  "period": "none|subscription_month",
  "limitValue": 0
}

individualQuotas

Format:

{
  "key": "string",
  "limitValue": 0
}

Clés supportées:

  • events.individual.create_per_subscription_month
  • events.register_per_subscription_month
  • event_proposals.create_per_subscription_month
  • events.individual.max_seats_per_event
  • event_proposals.max_seats_per_proposal
  • event_proposals.max_invitees_per_proposal

Sémantique Des Payloads Admin

Create

POST /subscription-plans accepte:

  • code
  • name
  • active
  • isDefault
  • rights
  • organizerCapabilities
  • capabilities
  • quotas
  • individualQuotas

Exemple minimal avec le nouveau bloc individual:

{
  "code": "ESSENTIAL",
  "name": "Essentiel",
  "active": true,
  "isDefault": true,
  "rights": [
    "hosting.request",
    "carpool.request",
    "equipment.request"
  ],
  "organizerCapabilities": [
    "enable_hosting",
    "enable_carpool",
    "enable_equipment"
  ],
  "capabilities": [
    "events.individual.create",
    "events.register",
    "event_proposals.create"
  ],
  "individualQuotas": [
    {
      "key": "events.individual.create_per_subscription_month",
      "limitValue": 2
    },
    {
      "key": "events.register_per_subscription_month",
      "limitValue": 10
    },
    {
      "key": "event_proposals.create_per_subscription_month",
      "limitValue": 3
    },
    {
      "key": "events.individual.max_seats_per_event",
      "limitValue": 12
    },
    {
      "key": "event_proposals.max_seats_per_proposal",
      "limitValue": 8
    },
    {
      "key": "event_proposals.max_invitees_per_proposal",
      "limitValue": 10
    }
  ]
}

Patch

PATCH /subscription-plans/{idPlan} est partiel.

Règles importantes:

  • champ absent => ne change rien
  • rights présent => remplace tout le mask rights
  • organizerCapabilities présent => remplace tout le mask organizerCapabilities
  • capabilities présent => remplace toutes les capabilities individual
  • quotas présent => remplace tous les quotas legacy solidarité
  • individualQuotas présent => remplace tous les quotas individual
  • [] est validé et signifie "vider complètement ce bloc"
  • isDefault n'est pas patchable

Exemple:

{
  "capabilities": [
    "events.register",
    "event_proposals.create"
  ],
  "individualQuotas": [
    {
      "key": "events.register_per_subscription_month",
      "limitValue": 12
    },
    {
      "key": "event_proposals.create_per_subscription_month",
      "limitValue": 4
    }
  ]
}

Contrat De Lecture Admin

GET /subscription-plans et GET /subscription-plans/{idPlan} renvoient:

  • rights
  • organizerCapabilities
  • capabilities
  • quotas
  • individualQuotas

Important:

  • côté admin, capabilities renvoie uniquement le sous-ensemble individual
  • le front peut donc relire puis re-poster ce champ tel quel sans convertir les droits solidarité

Exemple de forme:

{
  "id": 2,
  "code": "ESSENTIAL",
  "name": "Essentiel",
  "active": true,
  "isDefault": true,
  "rights": [
    "hosting.request",
    "carpool.request",
    "equipment.request"
  ],
  "organizerCapabilities": [
    "enable_hosting",
    "enable_carpool",
    "enable_equipment"
  ],
  "capabilities": [
    "events.individual.create",
    "events.register",
    "event_proposals.create"
  ],
  "quotas": [],
  "individualQuotas": []
}

Contrat De Lecture Self

GET /me/subscription reste le point d'entrée front pour connaître le plan effectif de l'utilisateur connecté.

La réponse contient:

  • plan
  • hasExplicitSubscription
  • subscription
  • rights
  • organizerCapabilities
  • capabilities
  • quotas
  • quotaUsage

Important:

  • côté self, capabilities est un catalogue canonique de lecture
  • il agrège les capabilities individual et les mappings canoniques issus de rights et organizerCapabilities
  • quotas contient uniquement les limites configurées
  • quotaUsage contient les usages des quotas mensuels consommables
  • quotaUsage ne couvre pas les quotas de gabarit

Exemple de capabilities canoniques possibles dans GET /me/subscription:

  • events.individual.create
  • events.register
  • event_proposals.create
  • solidarity.hosting.request
  • solidarity.hosting.offer
  • solidarity.carpool.request
  • solidarity.carpool.offer
  • solidarity.equipment.request
  • solidarity.equipment.offer
  • event_solidarity.hosting.enable
  • event_solidarity.carpool.enable
  • event_solidarity.equipment.enable
  • event_solidarity.external_helpers.allow

Exemple de quotas canoniques possibles dans GET /me/subscription:

  • events.individual.create_per_subscription_month
  • events.register_per_subscription_month
  • event_proposals.create_per_subscription_month
  • events.individual.max_seats_per_event
  • event_proposals.max_seats_per_proposal
  • event_proposals.max_invitees_per_proposal
  • solidarity.hosting.requests.open
  • solidarity.hosting.requests.completed_per_subscription_month
  • solidarity.carpool.requests.open
  • solidarity.carpool.requests.completed_per_subscription_month
  • solidarity.equipment.requests.open
  • solidarity.equipment.requests.completed_per_subscription_month

quotaUsage renvoie aujourd'hui uniquement les quotas mensuels consommables:

  • events.individual.create_per_subscription_month
  • events.register_per_subscription_month
  • event_proposals.create_per_subscription_month
  • solidarity.hosting.requests.completed_per_subscription_month
  • solidarity.carpool.requests.completed_per_subscription_month
  • solidarity.equipment.requests.completed_per_subscription_month

Forme:

{
  "key": "events.register_per_subscription_month",
  "limitValue": 12,
  "used": 4,
  "remaining": 8,
  "periodStart": "2026-04-08T10:29:05Z",
  "periodEnd": "2026-05-08T10:29:05Z"
}

Impacts Front Sur Les Actions Produit

Les fronts qui créent ou modifient des objets doivent maintenant prendre en compte des refus backend liés au plan individual.

Actions concernées:

  • création d'event
  • augmentation de maxSeats sur un event
  • inscription à un event
  • création d'event proposal
  • patch d'event proposal quand maxSeats ou les invitées changent
  • auto-conversion proposal -> event

Règle front:

  • le backend reste la source de vérité
  • si le front veut pré-checker une feature, il peut s'appuyer sur GET /me/subscription
  • mais le front doit quand même gérer les erreurs HTTP renvoyées par l'action

Sémantique utile:

  • 400 = payload invalide ou limite de gabarit violée
  • 403 = capability ou quota mensuel bloqué
  • 409 = conflit d'état métier, surtout côté event_proposal

Le front doit afficher le message d'erreur backend tel quel.

Exemples de messages possibles:

  • Event creation is not allowed for the current subscription
  • Monthly event creation quota exceeded
  • maxSeats too high for current subscription (max X)
  • Event registration is not allowed for the current subscription
  • Monthly event registration quota exceeded
  • Event proposal creation is not allowed for the current subscription
  • Monthly event proposal quota exceeded

Ce Qui N'Existe Pas Encore

Il n'existe pas encore:

  • d'endpoint de catalogue dynamique pour lister les clés autorisées
  • de payload admin unifie qui remplace rights et organizerCapabilities

Pour la V1 front, il faut donc:

  • continuer à utiliser rights et organizerCapabilities pour la solidarité
  • ajouter capabilities et individualQuotas sur l'admin des plans
  • consommer GET /me/subscription pour la lecture du plan effectif, des limites et des usages mensuels