PLB / Abonnements / user_access_json

🔑 user_access_json — Anatomie complète

Comment les droits de chaque utilisateur sont construits, stockés et évalués — du SQL Postgres jusqu'à checkFeatureAccess() en Dart.

🗄️ 2 vues Postgres 📦 json_agg() 11 feature keys 2 types d'accès 4 plans 1 fonction Dart
🧬
Anatomie d'un objet user_access_json
Structure complète d'un élément du tableau
user_access_json est un tableau JSON retourné par la vue user_feature_usage_json_cache via json_agg(). Il contient une entrée par feature disponible pour le plan de l'utilisateur. Flutter le stocke dans FFAppState().userFeatureRights.
user_access_json[i] — 1 objet feature
[ // tableau complet = toutes les features du plan
  {
    "feature_key": "group_create", // clé unique     "access_type": "quota", // "flag" ou "quota"     "limit_value": 3, // null si flag     "used": 1, // COUNT(*) du log     "remaining": 2, // limit_value - used     "period_days": 30, // null si flag ou unlimited     "is_enabled": true, // killswitch admin     "has_access": true // ← résultat final   },
  { ... }, // 10 autres features
]
📋
Champs — cliquez pour détailler
feature_key text requis
Identifiant unique de la feature. Utilisé par checkFeatureAccess(featureKey) pour trouver le bon objet dans le tableau. Source : subscription_access.feature_key.
access_type text requis
Détermine la logique de calcul de has_access. Deux valeurs possibles : flag (booléen, pas de compteur) ou quota (limité avec COUNT sur le log).
limit_value int4 | null conditionnel
Nombre maximum d'utilisations autorisées pour les quotas. null si access_type = "flag". Pour les flags, la valeur 1 dans subscription_access signifie "accès autorisé", 0 signifie "refusé".
used int4 calculé
Nombre d'utilisations comptabilisées. Calculé par COUNT(*) sur feature_usage_log filtré par member_uuid, feature_key et la fenêtre temporelle. Exception : pour eventOpened_join, la source est EventsRegistration.
remaining int4 | null calculé
Utilisations restantes = limit_value - used. null pour les flags. Peut être négatif si des actions ont été effectuées sans log (incohérence). Utilisé uniquement pour l'affichage dans l'UI debug.
period_days int4 | null conditionnel
Durée de la fenêtre temporelle glissante en jours. null pour les flags et les quotas unlimited. Pour 30, le COUNT(*) ne compte que les lignes créées dans les 30 derniers jours.
is_enabled bool requis
Killswitch admin. Si false, checkFeatureAccess() retourne immédiatement false sans regarder has_access. Permet de désactiver une feature pour tous les plans sans toucher aux données.
has_access bool | string | num ⭐ résultat
Le champ décisif — lu en dernier par checkFeatureAccess(). Calculé par la vue : remaining > 0 pour un quota, ou limit_value = 1 pour un flag. Accepte 3 types : bool, String ("true"/"1"/"yes"), num (!= 0).
Origine des champs : 5 champs viennent directement de subscription_access (feature_key, access_type, limit_value, period_days, is_enabled). 3 champs sont calculés par la vue (used, remaining, has_access).