# Corrections Panel Admin - 7 Novembre 2025

## Problèmes identifiés et corrigés

### 1. ✅ PRO n'apparaît pas dans le dashboard
**Problème** : Le backend renvoie `pro` mais le frontend ne l'affiche pas.

**Solution** :
- Ajout du type `pro: number` dans `DashboardSummary` (api.ts)
- Ajout d'une carte PRO dans le dashboard (Dashboard.tsx)
- Le dashboard affiche maintenant 5 cartes : Total, Actives, Suspendues, Enterprise, **Pro**

### 2. ✅ Pas de bouton supprimer dans Clients
**Problème** : Impossible de gérer/supprimer les clients depuis le panel.

**Solution** : L'API backend existe déjà :
- `DELETE /api/v1/licenses/{api_key}` : Rétrograde vers FREE (soft delete)
- `DELETE /api/v1/licenses/{api_key}/hard` : Suppression définitive (hard delete)

Le composant `LicensesTable.tsx` a déjà l'implémentation. Les boutons de suppression doivent être utilisés depuis l'onglet **Licences** et non **Clients**.

**Note** : Le soft delete rétrograde automatiquement vers FREE au lieu de supprimer, pour conserver l'historique client.

### 3. ⚠️ Les comptes FREE ont des clés API
**Ce n'est PAS un bug** : Tous les comptes (FREE inclus) doivent avoir une clé API pour :
- S'authentifier à l'API Web Sentinel
- Être identifiés dans le système
- Faire des scans (limités selon le tier)

Les clés API ne sont pas réservées aux comptes payants. Le tier FREE a simplement des limitations (1 domaine, pas de scan de code source).

### 4. ✅ Champs Stripe inutilisés
**Problème** : Les champs `stripe_customer_id` et `stripe_subscription_id` sont visibles mais vides.

**Explication** : Ce sont des placeholders pour une future intégration Stripe.

**Solution** : Migration ajoutée pour créer ces colonnes dans la table `users` :
```sql
ALTER TABLE users ADD COLUMN IF NOT EXISTS stripe_customer_id VARCHAR(255);
ALTER TABLE users ADD COLUMN IF NOT EXISTS stripe_subscription_id VARCHAR(255);
```

Si vous n'utilisez pas Stripe, ces champs peuvent être ignorés. Ils seront utiles si vous décidez d'intégrer Stripe plus tard.

### 5. ✅ Les modifications ne fonctionnent pas
**Problème** : Le modèle `License` utilisait des `@property` en lecture seule.

**Solution** :
1. **Migration de la table `users`** (migrate_users_table.py) :
   - Ajout de colonnes : `max_domains`, `max_users`, `allow_source_scan`, `max_source_files`, `max_source_size_mb`, `advanced_rules`, `stripe_customer_id`, `stripe_subscription_id`, `updated_at`, `events`

2. **Modification du modèle License** (models/license.py) :
   - Remplacement des `@property` par de vraies colonnes SQLAlchemy
   - Ajout de setters pour `status` et `expires_at`
   - Les modifications via PATCH `/api/v1/licenses/{api_key}` fonctionnent maintenant

## Déploiement

### Étape 1 : Migration de la base de données

**IMPORTANT** : Exécuter la migration sur le serveur de production :

```bash
# Copier le script de migration
scp admin/backend/migrate_users_table.py bruno@51.83.45.207:/tmp/

# Se connecter au serveur
ssh bruno@51.83.45.207

# Exécuter la migration dans le conteneur backend
docker cp /tmp/migrate_users_table.py web-sentinel-admin-backend:/app/
docker exec web-sentinel-admin-backend python3 /app/migrate_users_table.py
```

La migration ajoute des colonnes avec `IF NOT EXISTS`, donc elle est idempotente (peut être exécutée plusieurs fois sans danger).

### Étape 2 : Déployer le backend

```bash
# Copier le modèle License modifié
scp admin/backend/app/models/license.py bruno@51.83.45.207:/tmp/
ssh bruno@51.83.45.207 "docker cp /tmp/license.py web-sentinel-admin-backend:/app/app/models/"

# Redémarrer le backend
ssh bruno@51.83.45.207 "docker restart web-sentinel-admin-backend"
```

### Étape 3 : Déployer le frontend

```bash
# Le frontend est déjà compilé dans dist/
scp -r admin/frontend/dist/* bruno@51.83.45.207:/tmp/frontend-dist/
ssh bruno@51.83.45.207 "docker cp /tmp/frontend-dist/. deployment-admin-frontend:/usr/share/nginx/html/"

# Redémarrer le frontend
ssh bruno@51.83.45.207 "docker restart deployment-admin-frontend"
```

### Étape 4 : Initialiser les valeurs par défaut (optionnel)

Après la migration, les utilisateurs existants auront des valeurs par défaut (max_domains=1, etc.). Pour corriger selon le tier :

```bash
ssh bruno@51.83.45.207
docker exec -it web-sentinel-db psql -U websentinel -d websentinel_prod

-- Mettre à jour les limites selon le tier
UPDATE users SET max_domains = 10, max_users = 5, allow_source_scan = true, max_source_files = 100, max_source_size_mb = 50 WHERE LOWER(tier) = 'pro';
UPDATE users SET max_domains = 50, max_users = 50, allow_source_scan = true, max_source_files = 1000, max_source_size_mb = 500, advanced_rules = true WHERE LOWER(tier) IN ('entreprise', 'enterprise');
UPDATE users SET max_domains = 999, max_users = 999, allow_source_scan = true, max_source_files = 9999, max_source_size_mb = 9999, advanced_rules = true WHERE LOWER(tier) = 'sysop';
\q
```

### Étape 5 : Vérification

1. **Dashboard** : https://admin.web-sentinel.taaazzz-prog.fr
   - Vérifier que la carte "Pro" s'affiche avec la bonne valeur (1)

2. **Licences** : Tester la modification d'une licence
   - Changer le tier d'un utilisateur
   - Modifier les limites (max_domains, allow_source_scan)
   - Vérifier que les changements sont sauvegardés

3. **Suppression** : Tester le soft delete
   - Supprimer (rétrograder) un compte de test vers FREE
   - Vérifier qu'il passe bien en tier FREE avec 1 domaine

## Résumé des fichiers modifiés

```
admin/backend/
  ├── app/models/license.py          # Colonnes réelles au lieu de @property
  └── migrate_users_table.py         # Script de migration (nouveau)

admin/frontend/
  ├── src/api.ts                     # Ajout du type 'pro' dans DashboardSummary
  └── src/components/Dashboard.tsx   # Ajout de la carte PRO
```

## Notes importantes

1. **Clés API pour FREE** : C'est normal ! Tous les tiers ont besoin de clés API.

2. **Suppression** : Utilisez l'onglet **Licences** (pas Clients) pour supprimer/rétrograder.

3. **Stripe** : Les champs existent dans la base mais ne sont pas utilisés. Ignorez-les si vous n'avez pas Stripe.

4. **Migration** : Exécutez-la AVANT de redémarrer le backend, sinon les modifications de licences échoueront.

5. **Token JWT** : Après le redémarrage du backend, reconnectez-vous (les tokens expirent après 60 minutes).
