Ajoute spec et plan d'implémentation TOUS_ABONNES
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
# Accès gratuit pour tous via `TOUS_ABONNES`
|
||||
|
||||
**Date :** 2026-06-26
|
||||
**Statut :** Design validé
|
||||
|
||||
## Contexte
|
||||
|
||||
La plateforme de paiement Frisbii doit effectuer un _background check_ avant
|
||||
d'autoriser la réception de paiements (plusieurs semaines). En attendant, on
|
||||
veut ouvrir gratuitement à tout utilisateur connecté les fonctionnalités
|
||||
normalement réservées aux abonnés, sans casser le code d'abonnement existant
|
||||
(qui sera réactivé tel quel une fois Frisbii validé).
|
||||
|
||||
## Objectif
|
||||
|
||||
Un drapeau d'environnement `TOUS_ABONNES` qui, lorsqu'il vaut `true` :
|
||||
|
||||
1. donne à tout utilisateur **connecté** l'accès aux fonctionnalités réservées
|
||||
aux abonnés ;
|
||||
2. affiche un bandeau d'information en haut de la page `/compte/abonnement` ;
|
||||
3. désactive (et grise) les boutons « S'abonner » sur `/compte/abonnement`.
|
||||
|
||||
Quand le drapeau est absent ou `false`, le comportement actuel est strictement
|
||||
inchangé.
|
||||
|
||||
## Architecture existante (rappel)
|
||||
|
||||
- `src/pages/_compte_shell.py` centralise l'accès :
|
||||
- `current_user_has_subscription()` → utilisé par `_nav` (sections visibles
|
||||
du menu) **et** `account_guard` (protection des pages réservées) ;
|
||||
- `SECTIONS` marque `archives`, `filtres`, `siret` avec
|
||||
`require_subscription: True`.
|
||||
- `db.has_active_subscription(user_id)` est le contrôle bas-niveau « vrai
|
||||
abonnement payant » ; appelé directement par :
|
||||
- `compte_abonnement.py` (`has_access` → vue « abonnement actif » vs cartes de
|
||||
plans) ;
|
||||
- `auth/routes.py::_post_login_url` (redirection post-login) ;
|
||||
- `subscriptions/routes.py::subscribe` (anti double-abonnement).
|
||||
- `compte_abonnement.py::_plan_card` rend le bouton « S'abonner ».
|
||||
|
||||
## Conception
|
||||
|
||||
### 1. Variable d'environnement
|
||||
|
||||
Dans `src/utils/__init__.py`, suivant la convention de `DEVELOPMENT` :
|
||||
|
||||
```python
|
||||
TOUS_ABONNES = os.getenv("TOUS_ABONNES", "False").lower() == "true"
|
||||
```
|
||||
|
||||
Documentée dans `.template.env`.
|
||||
|
||||
### 2. Déblocage de l'accès (point unique)
|
||||
|
||||
`src/pages/_compte_shell.py::current_user_has_subscription()` :
|
||||
|
||||
```python
|
||||
def current_user_has_subscription() -> bool:
|
||||
from src.subscriptions import db
|
||||
|
||||
if not current_user.is_authenticated:
|
||||
return False
|
||||
if TOUS_ABONNES:
|
||||
return True
|
||||
return db.has_active_subscription(current_user.id)
|
||||
```
|
||||
|
||||
Ce seul changement débloque les sections `archives`/`filtres`/`siret` dans le
|
||||
menu (`_nav`) **et** lève leur `account_guard`.
|
||||
|
||||
**On ne touche pas** à `db.has_active_subscription()` : il doit continuer à
|
||||
refléter un vrai abonnement payant. Conséquence voulue : sur
|
||||
`/compte/abonnement`, `has_access` reste `False` pour un utilisateur sans
|
||||
abonnement réel → il voit les cartes de plans (désactivées) + le bandeau, et
|
||||
non une fausse vue « abonnement actif ».
|
||||
|
||||
### 3. Bandeau d'information (page `/compte/abonnement` uniquement)
|
||||
|
||||
Dans `compte_abonnement.py::layout`, quand `TOUS_ABONNES`, insérer en haut du
|
||||
`body` (avant les cartes) un `dbc.Alert` (`color="info"`) :
|
||||
|
||||
> Les fonctionnalités normalement accessibles contre un abonnement de 20 € HT
|
||||
> par mois sont accessibles à tous et toutes en attendant la validation de mon
|
||||
> dossier pour recevoir des paiements.
|
||||
|
||||
### 4. Boutons « S'abonner » désactivés et gris
|
||||
|
||||
Dans `compte_abonnement.py::_plan_card`, quand `TOUS_ABONNES`, le bouton est
|
||||
rendu désactivé et gris (`className="btn btn-secondary disabled"`,
|
||||
`disabled=True`). Les cartes restent visibles à titre informatif.
|
||||
|
||||
### 5. Redirection post-login
|
||||
|
||||
**Inchangée.** `_post_login_url` s'appuie sur `db.has_active_subscription`, qui
|
||||
reste `False` pour les non-abonnés réels → redirection vers
|
||||
`/compte/abonnement`, ce qui est le comportement souhaité avec `TOUS_ABONNES`.
|
||||
|
||||
## Hors périmètre
|
||||
|
||||
- Aucune autre fonctionnalité « abonné » n'est gatée ailleurs que via
|
||||
`account_guard` (vérifié : pas de contrôle d'abonnement dans `tableau.py`,
|
||||
exports, sauvegarde de filtres).
|
||||
- Pas de modification du flux de paiement Frisbii ni du webhook.
|
||||
|
||||
## Tests
|
||||
|
||||
- `current_user_has_subscription()` : `True` si connecté + `TOUS_ABONNES`,
|
||||
`False` si non connecté même avec le drapeau, comportement DB normal si
|
||||
drapeau absent.
|
||||
- `visible_sections` : sections réservées visibles via le drapeau (en
|
||||
s'appuyant sur le helper).
|
||||
- `compte_abonnement` : bandeau présent et bouton désactivé quand `TOUS_ABONNES`
|
||||
est actif ; absents sinon.
|
||||
Reference in New Issue
Block a user