Widget Devoir Finition
This commit is contained in:
parent
099c3b61bd
commit
4ce912e34d
@ -1,104 +0,0 @@
|
|||||||
# 🐛 Debug : Bouton couleur manquant
|
|
||||||
|
|
||||||
## Diagnostic
|
|
||||||
|
|
||||||
Le code est bien présent dans le fichier `app/missions/equipe/page.tsx` :
|
|
||||||
- ✅ Import de `Palette` (ligne 4)
|
|
||||||
- ✅ Fonction `handleOpenColorPicker` (ligne 503)
|
|
||||||
- ✅ Bouton avec icône Palette (ligne 1040-1049)
|
|
||||||
- ✅ Dialog de sélection de couleur (ligne 1377+)
|
|
||||||
|
|
||||||
## Vérifications à faire
|
|
||||||
|
|
||||||
### 1. Êtes-vous sur la bonne page ?
|
|
||||||
|
|
||||||
Votre screenshot montre : **"Gestion des équipes"** avec onglet **"Groupes (7)"**
|
|
||||||
|
|
||||||
✅ C'est bien la page `/missions/equipe` avec l'onglet Groupes activé.
|
|
||||||
|
|
||||||
### 2. Vérifier le cache Next.js
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Dans le terminal :
|
|
||||||
cd /Users/alma/Documents/NeahStable
|
|
||||||
|
|
||||||
# Supprimer le cache Next.js
|
|
||||||
rm -rf .next
|
|
||||||
|
|
||||||
# Rebuild
|
|
||||||
npm run dev
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Vérifier le cache du navigateur
|
|
||||||
|
|
||||||
Dans votre navigateur :
|
|
||||||
- **Chrome/Edge** : Ctrl+Shift+R (Windows) ou Cmd+Shift+R (Mac)
|
|
||||||
- **Firefox** : Ctrl+F5 (Windows) ou Cmd+Shift+R (Mac)
|
|
||||||
- Ou ouvrir DevTools (F12) → Onglet Network → Cocher "Disable cache"
|
|
||||||
|
|
||||||
### 4. Vérifier que le serveur dev tourne
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Arrêter le serveur actuel (Ctrl+C)
|
|
||||||
# Puis relancer :
|
|
||||||
npm run dev
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5. Vérifier dans le code source de la page
|
|
||||||
|
|
||||||
1. Ouvrir la page `/missions/equipe`
|
|
||||||
2. Clic droit → "Inspecter" (F12)
|
|
||||||
3. Onglet "Elements" ou "Inspector"
|
|
||||||
4. Chercher "Palette" dans le HTML (Ctrl+F)
|
|
||||||
5. Est-ce que vous trouvez `<svg>` avec la classe contenant "Palette" ?
|
|
||||||
|
|
||||||
### 6. Vérifier les erreurs console
|
|
||||||
|
|
||||||
1. F12 → Onglet "Console"
|
|
||||||
2. Y a-t-il des erreurs en rouge ?
|
|
||||||
3. Copier/coller les erreurs si présentes
|
|
||||||
|
|
||||||
## Solution temporaire
|
|
||||||
|
|
||||||
Si le bouton n'apparaît toujours pas, utilisez la page `/groups` à la place :
|
|
||||||
|
|
||||||
1. Aller sur `/groups`
|
|
||||||
2. Dans la colonne ACTIONS, cliquer sur **⋮** (trois points)
|
|
||||||
3. Sélectionner "Couleur du calendrier"
|
|
||||||
|
|
||||||
Le code est identique dans `components/groups/groups-table.tsx` et devrait fonctionner.
|
|
||||||
|
|
||||||
## Code exact du bouton
|
|
||||||
|
|
||||||
Voici le code exact qui devrait être rendu (ligne 1040-1049) :
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
<Button
|
|
||||||
variant="ghost"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => handleOpenColorPicker(group)}
|
|
||||||
disabled={actionLoading === group.id}
|
|
||||||
className="h-8 w-8 p-0"
|
|
||||||
title="Couleur du calendrier"
|
|
||||||
>
|
|
||||||
<Palette className="h-4 w-4 text-gray-500" />
|
|
||||||
</Button>
|
|
||||||
```
|
|
||||||
|
|
||||||
Ce bouton devrait apparaître entre le bouton "Modifier" (Edit2) et "Gérer les membres" (Users).
|
|
||||||
|
|
||||||
## Ordre des boutons attendu
|
|
||||||
|
|
||||||
Dans la colonne ACTIONS, vous devriez voir **4 boutons** :
|
|
||||||
|
|
||||||
1. ✏️ **Edit2** - Modifier le nom du groupe
|
|
||||||
2. 🎨 **Palette** - Couleur du calendrier ← NOUVEAU
|
|
||||||
3. 👥 **Users** - Gérer les membres
|
|
||||||
4. 🗑️ **Trash2** - Supprimer le groupe
|
|
||||||
|
|
||||||
## Si rien ne fonctionne
|
|
||||||
|
|
||||||
Envoyez-moi :
|
|
||||||
1. Screenshot de la console (F12 → Console)
|
|
||||||
2. Screenshot du code source HTML (F12 → Elements, autour de la table)
|
|
||||||
3. Résultat de : `ls -la .next` dans le terminal
|
|
||||||
356
DEPLOYMENT.md
356
DEPLOYMENT.md
@ -1,356 +0,0 @@
|
|||||||
# Guide de Déploiement Docker - Production
|
|
||||||
|
|
||||||
Ce guide explique comment déployer l'application Neah en production avec Docker.
|
|
||||||
|
|
||||||
## 📋 Prérequis
|
|
||||||
|
|
||||||
- Docker Engine 20.10+
|
|
||||||
- Docker Compose 2.0+
|
|
||||||
- Au moins 4GB de RAM disponible
|
|
||||||
- Au moins 10GB d'espace disque
|
|
||||||
|
|
||||||
## 🚀 Déploiement Rapide
|
|
||||||
|
|
||||||
### 1. Préparation de l'environnement
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Cloner le repository (si ce n'est pas déjà fait)
|
|
||||||
git clone <repository-url>
|
|
||||||
cd NeahStable
|
|
||||||
|
|
||||||
# Créer le fichier .env.production avec vos variables
|
|
||||||
cp .env.example .env.production
|
|
||||||
nano .env.production # Éditez avec vos valeurs
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Configuration des variables d'environnement
|
|
||||||
|
|
||||||
Créez un fichier `.env.production` avec toutes les variables nécessaires :
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Copier le fichier d'exemple
|
|
||||||
cp env.production.example .env.production
|
|
||||||
|
|
||||||
# Éditer avec vos valeurs
|
|
||||||
nano .env.production
|
|
||||||
```
|
|
||||||
|
|
||||||
**Important** : Toutes les commandes `docker-compose` doivent utiliser `--env-file .env.production` pour charger les variables.
|
|
||||||
|
|
||||||
```env
|
|
||||||
# Database
|
|
||||||
POSTGRES_USER=neah_user
|
|
||||||
POSTGRES_PASSWORD=VOTRE_MOT_DE_PASSE_SECURISE
|
|
||||||
POSTGRES_DB=calendar_db
|
|
||||||
DATABASE_URL=postgresql://neah_user:VOTRE_MOT_DE_PASSE_SECURISE@db:5432/calendar_db?schema=public
|
|
||||||
|
|
||||||
# Redis
|
|
||||||
REDIS_PASSWORD=VOTRE_MOT_DE_PASSE_REDIS_SECURISE
|
|
||||||
REDIS_URL=redis://:VOTRE_MOT_DE_PASSE_REDIS_SECURISE@redis:6379
|
|
||||||
|
|
||||||
# NextAuth
|
|
||||||
NEXTAUTH_URL=https://hub.slm-lab.net
|
|
||||||
NEXTAUTH_SECRET=VOTRE_SECRET_NEXTAUTH_TRES_LONG_ET_SECURISE
|
|
||||||
|
|
||||||
# Keycloak
|
|
||||||
KEYCLOAK_ISSUER=https://connect.slm-lab.net/realms/cercle
|
|
||||||
KEYCLOAK_CLIENT_ID=lab
|
|
||||||
KEYCLOAK_CLIENT_SECRET=VOTRE_CLIENT_SECRET
|
|
||||||
KEYCLOAK_REALM=cercle
|
|
||||||
NEXT_PUBLIC_KEYCLOAK_ISSUER=https://connect.slm-lab.net/realms/cercle
|
|
||||||
|
|
||||||
# Application
|
|
||||||
APP_PORT=3000
|
|
||||||
NODE_ENV=production
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Build et démarrage
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Build l'image Docker
|
|
||||||
docker-compose -f docker-compose.prod.yml --env-file .env.production build
|
|
||||||
|
|
||||||
# Démarrer les services (base de données et Redis)
|
|
||||||
docker-compose -f docker-compose.prod.yml --env-file .env.production up -d db redis
|
|
||||||
|
|
||||||
# Attendre que les services soient prêts (environ 10 secondes)
|
|
||||||
sleep 10
|
|
||||||
|
|
||||||
# Appliquer les migrations Prisma
|
|
||||||
docker-compose -f docker-compose.prod.yml --env-file .env.production run --rm app npx --yes prisma@6.4.1 migrate deploy
|
|
||||||
|
|
||||||
# Démarrer l'application
|
|
||||||
docker-compose -f docker-compose.prod.yml --env-file .env.production up -d app
|
|
||||||
|
|
||||||
# Vérifier les logs
|
|
||||||
docker-compose -f docker-compose.prod.yml --env-file .env.production logs -f app
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🔧 Configuration Avancée
|
|
||||||
|
|
||||||
### Variables d'environnement importantes
|
|
||||||
|
|
||||||
#### Base de données PostgreSQL
|
|
||||||
- `POSTGRES_USER` : Utilisateur PostgreSQL
|
|
||||||
- `POSTGRES_PASSWORD` : **Changez absolument le mot de passe par défaut !**
|
|
||||||
- `POSTGRES_DB` : Nom de la base de données
|
|
||||||
|
|
||||||
#### Redis
|
|
||||||
- `REDIS_PASSWORD` : **Changez absolument le mot de passe par défaut !**
|
|
||||||
|
|
||||||
#### NextAuth
|
|
||||||
- `NEXTAUTH_URL` : URL publique de votre application (ex: `https://hub.slm-lab.net`)
|
|
||||||
- `NEXTAUTH_SECRET` : Secret pour signer les tokens JWT (générez avec `openssl rand -base64 32`)
|
|
||||||
|
|
||||||
#### Keycloak
|
|
||||||
- `KEYCLOAK_ISSUER` : URL de votre instance Keycloak
|
|
||||||
- `KEYCLOAK_CLIENT_ID` : ID du client OAuth
|
|
||||||
- `KEYCLOAK_CLIENT_SECRET` : Secret du client OAuth
|
|
||||||
- `KEYCLOAK_REALM` : Nom du realm Keycloak
|
|
||||||
|
|
||||||
### Ports exposés
|
|
||||||
|
|
||||||
Par défaut, les ports suivants sont exposés :
|
|
||||||
- **3000** : Application Next.js
|
|
||||||
- **5432** : PostgreSQL (uniquement sur localhost)
|
|
||||||
- **6379** : Redis (uniquement sur localhost)
|
|
||||||
|
|
||||||
Pour modifier les ports, éditez `docker-compose.prod.yml` :
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
app:
|
|
||||||
ports:
|
|
||||||
- "80:3000" # Exposer sur le port 80
|
|
||||||
```
|
|
||||||
|
|
||||||
### Volumes et persistance
|
|
||||||
|
|
||||||
Les données sont stockées dans des volumes Docker :
|
|
||||||
- `postgres_data` : Base de données PostgreSQL
|
|
||||||
- `redis_data` : Données Redis
|
|
||||||
|
|
||||||
Pour sauvegarder :
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Sauvegarder PostgreSQL
|
|
||||||
docker exec neah-postgres-prod pg_dump -U ${POSTGRES_USER:-neah_user} ${POSTGRES_DB:-calendar_db} > backup.sql
|
|
||||||
|
|
||||||
# Restaurer PostgreSQL
|
|
||||||
docker exec -i neah-postgres-prod psql -U ${POSTGRES_USER:-neah_user} ${POSTGRES_DB:-calendar_db} < backup.sql
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🔄 Mises à jour
|
|
||||||
|
|
||||||
### Mettre à jour l'application
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Arrêter l'application
|
|
||||||
docker-compose -f docker-compose.prod.yml --env-file .env.production stop app
|
|
||||||
|
|
||||||
# Rebuild l'image
|
|
||||||
docker-compose -f docker-compose.prod.yml --env-file .env.production build app
|
|
||||||
|
|
||||||
# Appliquer les migrations si nécessaire
|
|
||||||
docker-compose -f docker-compose.prod.yml --env-file .env.production run --rm app npx --yes prisma@6.4.1 migrate deploy
|
|
||||||
|
|
||||||
# Redémarrer
|
|
||||||
docker-compose -f docker-compose.prod.yml --env-file .env.production up -d app
|
|
||||||
```
|
|
||||||
|
|
||||||
### Appliquer les migrations Prisma
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Vérifier le statut des migrations
|
|
||||||
docker-compose -f docker-compose.prod.yml --env-file .env.production run --rm app npx --yes prisma@6.4.1 migrate status
|
|
||||||
|
|
||||||
# Appliquer les migrations
|
|
||||||
docker-compose -f docker-compose.prod.yml --env-file .env.production run --rm app npx --yes prisma@6.4.1 migrate deploy
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📊 Monitoring et Logs
|
|
||||||
|
|
||||||
### Voir les logs
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Tous les services
|
|
||||||
docker-compose -f docker-compose.prod.yml --env-file .env.production logs -f
|
|
||||||
|
|
||||||
# Un service spécifique
|
|
||||||
docker-compose -f docker-compose.prod.yml --env-file .env.production logs -f app
|
|
||||||
docker-compose -f docker-compose.prod.yml --env-file .env.production logs -f db
|
|
||||||
docker-compose -f docker-compose.prod.yml --env-file .env.production logs -f redis
|
|
||||||
```
|
|
||||||
|
|
||||||
### Health Check
|
|
||||||
|
|
||||||
L'application expose un endpoint de health check :
|
|
||||||
- `GET http://localhost:3000/api/health`
|
|
||||||
|
|
||||||
Réponse :
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"status": "ok",
|
|
||||||
"timestamp": "2024-01-01T00:00:00.000Z",
|
|
||||||
"uptime": 3600,
|
|
||||||
"checks": {
|
|
||||||
"database": { "status": "ok", "latency": 5 },
|
|
||||||
"redis": { "status": "ok", "latency": 2 }
|
|
||||||
},
|
|
||||||
"latency": 7
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🔒 Sécurité
|
|
||||||
|
|
||||||
### Checklist de sécurité
|
|
||||||
|
|
||||||
- [ ] Tous les mots de passe par défaut ont été changés
|
|
||||||
- [ ] `NEXTAUTH_SECRET` est un secret fort et unique
|
|
||||||
- [ ] Les ports ne sont exposés que si nécessaire
|
|
||||||
- [ ] Un reverse proxy (Nginx/Traefik) est configuré avec SSL/TLS
|
|
||||||
- [ ] Les volumes sont sauvegardés régulièrement
|
|
||||||
- [ ] Les logs sont surveillés pour détecter les anomalies
|
|
||||||
|
|
||||||
### Reverse Proxy avec Nginx
|
|
||||||
|
|
||||||
Exemple de configuration Nginx :
|
|
||||||
|
|
||||||
```nginx
|
|
||||||
server {
|
|
||||||
listen 80;
|
|
||||||
server_name hub.slm-lab.net;
|
|
||||||
|
|
||||||
# Redirection HTTPS
|
|
||||||
return 301 https://$server_name$request_uri;
|
|
||||||
}
|
|
||||||
|
|
||||||
server {
|
|
||||||
listen 443 ssl http2;
|
|
||||||
server_name hub.slm-lab.net;
|
|
||||||
|
|
||||||
ssl_certificate /path/to/cert.pem;
|
|
||||||
ssl_certificate_key /path/to/key.pem;
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_pass http://localhost:3000;
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection 'upgrade';
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
proxy_cache_bypass $http_upgrade;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🛠️ Dépannage
|
|
||||||
|
|
||||||
### L'application ne démarre pas
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Vérifier les logs
|
|
||||||
docker-compose -f docker-compose.prod.yml --env-file .env.production logs app
|
|
||||||
|
|
||||||
# Vérifier que les services dépendants sont démarrés
|
|
||||||
docker-compose -f docker-compose.prod.yml --env-file .env.production ps
|
|
||||||
|
|
||||||
# Vérifier la santé des services
|
|
||||||
docker-compose -f docker-compose.prod.yml --env-file .env.production exec app curl http://localhost:3000/api/health
|
|
||||||
```
|
|
||||||
|
|
||||||
### Problèmes de connexion à la base de données
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Tester la connexion PostgreSQL
|
|
||||||
docker-compose -f docker-compose.prod.yml --env-file .env.production exec db psql -U neah_user -d calendar_db -c "SELECT 1;"
|
|
||||||
|
|
||||||
# Vérifier les variables d'environnement
|
|
||||||
docker-compose -f docker-compose.prod.yml --env-file .env.production exec app env | grep DATABASE
|
|
||||||
```
|
|
||||||
|
|
||||||
### Problèmes de connexion Redis
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Tester Redis
|
|
||||||
docker-compose -f docker-compose.prod.yml --env-file .env.production exec redis redis-cli -a VOTRE_MOT_DE_PASSE ping
|
|
||||||
```
|
|
||||||
|
|
||||||
### Rebuild complet
|
|
||||||
|
|
||||||
Si vous avez des problèmes persistants :
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Arrêter tous les services
|
|
||||||
docker-compose -f docker-compose.prod.yml --env-file .env.production down
|
|
||||||
|
|
||||||
# Supprimer les volumes (⚠️ PERDREZ LES DONNÉES)
|
|
||||||
docker-compose -f docker-compose.prod.yml --env-file .env.production down -v
|
|
||||||
|
|
||||||
# Rebuild tout
|
|
||||||
docker-compose -f docker-compose.prod.yml --env-file .env.production build --no-cache
|
|
||||||
|
|
||||||
# Redémarrer
|
|
||||||
docker-compose -f docker-compose.prod.yml --env-file .env.production up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📦 Sauvegardes
|
|
||||||
|
|
||||||
### Script de sauvegarde automatique
|
|
||||||
|
|
||||||
Créez un script `backup.sh` :
|
|
||||||
|
|
||||||
```bash
|
|
||||||
#!/bin/bash
|
|
||||||
BACKUP_DIR="/backups/neah"
|
|
||||||
DATE=$(date +%Y%m%d_%H%M%S)
|
|
||||||
|
|
||||||
# Créer le dossier de backup
|
|
||||||
mkdir -p $BACKUP_DIR
|
|
||||||
|
|
||||||
# Sauvegarder PostgreSQL
|
|
||||||
docker exec neah-postgres-prod pg_dump -U neah_user calendar_db | gzip > $BACKUP_DIR/db_$DATE.sql.gz
|
|
||||||
|
|
||||||
# Sauvegarder Redis (optionnel)
|
|
||||||
docker exec neah-redis-prod redis-cli --rdb - | gzip > $BACKUP_DIR/redis_$DATE.rdb.gz
|
|
||||||
|
|
||||||
# Garder seulement les 7 derniers jours
|
|
||||||
find $BACKUP_DIR -name "*.gz" -mtime +7 -delete
|
|
||||||
|
|
||||||
echo "Backup completed: $DATE"
|
|
||||||
```
|
|
||||||
|
|
||||||
Ajoutez dans crontab pour exécution quotidienne :
|
|
||||||
```bash
|
|
||||||
0 2 * * * /path/to/backup.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🚀 Déploiement avec Traefik (Optionnel)
|
|
||||||
|
|
||||||
Pour un déploiement avec Traefik comme reverse proxy :
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# Ajoutez dans docker-compose.prod.yml
|
|
||||||
app:
|
|
||||||
labels:
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.neah.rule=Host(`hub.slm-lab.net`)"
|
|
||||||
- "traefik.http.routers.neah.entrypoints=websecure"
|
|
||||||
- "traefik.http.routers.neah.tls.certresolver=letsencrypt"
|
|
||||||
- "traefik.http.services.neah.loadbalancer.server.port=3000"
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📝 Notes importantes
|
|
||||||
|
|
||||||
1. **Migrations Prisma** : Toujours exécuter `prisma migrate deploy` avant de démarrer l'application en production
|
|
||||||
2. **Secrets** : Ne jamais commiter les fichiers `.env` dans Git
|
|
||||||
3. **Ports** : Limiter l'exposition des ports aux services nécessaires uniquement
|
|
||||||
4. **Monitoring** : Configurer des alertes pour les health checks
|
|
||||||
5. **Sauvegardes** : Automatiser les sauvegardes de la base de données
|
|
||||||
|
|
||||||
## 🔗 Ressources
|
|
||||||
|
|
||||||
- [Documentation Docker](https://docs.docker.com/)
|
|
||||||
- [Documentation Next.js](https://nextjs.org/docs)
|
|
||||||
- [Documentation Prisma](https://www.prisma.io/docs)
|
|
||||||
@ -1,398 +0,0 @@
|
|||||||
# 🎨 Fonctionnalité : Modification de la couleur des calendriers de groupes
|
|
||||||
|
|
||||||
## 📋 Vue d'ensemble
|
|
||||||
|
|
||||||
Cette fonctionnalité permet aux membres d'un groupe de personnaliser la couleur de la pastille du calendrier associé à leur groupe. Chaque groupe créé possède un calendrier automatique nommé `"Groupe: {nom}"`, et cette couleur est visible dans tous les affichages de calendrier (agenda, vision, etc.).
|
|
||||||
|
|
||||||
## ✨ Fonctionnalités implémentées
|
|
||||||
|
|
||||||
### 1. **API Backend** (`/app/api/groups/[groupId]/calendar/route.ts`)
|
|
||||||
|
|
||||||
#### Nouveaux endpoints :
|
|
||||||
|
|
||||||
**GET `/api/groups/[groupId]/calendar`**
|
|
||||||
- Récupère le calendrier associé à un groupe
|
|
||||||
- Retourne l'objet calendrier avec sa couleur actuelle
|
|
||||||
|
|
||||||
**PATCH `/api/groups/[groupId]/calendar`**
|
|
||||||
- Modifie uniquement la couleur du calendrier d'un groupe
|
|
||||||
- Body : `{ "color": "#FF5733" }`
|
|
||||||
- Validation du format hexadécimal
|
|
||||||
- Vérification que l'utilisateur est membre du groupe
|
|
||||||
- Retourne le calendrier mis à jour
|
|
||||||
|
|
||||||
#### Sécurité :
|
|
||||||
- ✅ Authentification requise
|
|
||||||
- ✅ Vérification de l'appartenance au groupe via Keycloak
|
|
||||||
- ✅ Validation du format de couleur (hex : `#RRGGBB` ou `#RGB`)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 2. **Interface utilisateur - Page Groupes** (`/components/groups/groups-table.tsx`)
|
|
||||||
|
|
||||||
#### Modifications :
|
|
||||||
|
|
||||||
1. **Affichage de la pastille de couleur**
|
|
||||||
- Chaque groupe affiche maintenant une pastille colorée à côté de son nom
|
|
||||||
- Couleur par défaut : `#4f46e5` (indigo)
|
|
||||||
|
|
||||||
2. **Nouveau bouton "Couleur du calendrier"**
|
|
||||||
- Accessible via le menu actions (icône ⋯)
|
|
||||||
- Icône palette (🎨)
|
|
||||||
|
|
||||||
3. **Dialog de sélection de couleur**
|
|
||||||
- Palette de 16 couleurs prédéfinies
|
|
||||||
- Input manuel pour code hexadécimal
|
|
||||||
- Aperçu en temps réel de la couleur sélectionnée
|
|
||||||
- Validation avant sauvegarde
|
|
||||||
|
|
||||||
#### Palette de couleurs disponibles :
|
|
||||||
```typescript
|
|
||||||
const colorPalette = [
|
|
||||||
"#4f46e5", // Indigo
|
|
||||||
"#0891b2", // Cyan
|
|
||||||
"#0e7490", // Teal
|
|
||||||
"#16a34a", // Green
|
|
||||||
"#65a30d", // Lime
|
|
||||||
"#ca8a04", // Amber
|
|
||||||
"#d97706", // Orange
|
|
||||||
"#dc2626", // Red
|
|
||||||
"#e11d48", // Rose
|
|
||||||
"#9333ea", // Purple
|
|
||||||
"#7c3aed", // Violet
|
|
||||||
"#2563eb", // Blue
|
|
||||||
"#0284c7", // Sky
|
|
||||||
"#059669", // Emerald
|
|
||||||
"#84cc16", // Lime
|
|
||||||
"#eab308", // Yellow
|
|
||||||
];
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 3. **Interface utilisateur - Page Missions/Équipe** (`/app/missions/equipe/page.tsx`)
|
|
||||||
|
|
||||||
#### Modifications identiques à GroupsTable :
|
|
||||||
|
|
||||||
1. **Affichage de la couleur**
|
|
||||||
- Icône du groupe (👥) affichée sur fond de la couleur du calendrier
|
|
||||||
- Texte en blanc pour meilleure lisibilité
|
|
||||||
|
|
||||||
2. **Bouton direct dans la table**
|
|
||||||
- Icône palette (🎨) directement dans les actions
|
|
||||||
- Tooltip "Couleur du calendrier"
|
|
||||||
|
|
||||||
3. **Dialog de sélection**
|
|
||||||
- Même interface que dans GroupsTable
|
|
||||||
- Sauvegarde avec loader pendant l'opération
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 4. **Suppression automatique du calendrier** (`/app/api/groups/[groupId]/route.ts`) ✨ **NOUVEAU**
|
|
||||||
|
|
||||||
#### Modifications au DELETE endpoint :
|
|
||||||
|
|
||||||
Lorsqu'un groupe est supprimé, le calendrier associé est maintenant automatiquement supprimé :
|
|
||||||
|
|
||||||
1. **Récupération du nom du groupe**
|
|
||||||
- Appel à Keycloak avant suppression pour obtenir le nom du groupe
|
|
||||||
|
|
||||||
2. **Suppression du calendrier**
|
|
||||||
- Recherche du calendrier nommé `"Groupe: {nom}"`
|
|
||||||
- Suppression via `prisma.calendar.deleteMany()`
|
|
||||||
- Logs en cas de succès ou d'échec
|
|
||||||
|
|
||||||
3. **Suppression du groupe**
|
|
||||||
- Suppression du groupe de Keycloak
|
|
||||||
- Même si la suppression du calendrier échoue, le groupe est quand même supprimé
|
|
||||||
|
|
||||||
#### Impact :
|
|
||||||
- ✅ Plus de calendriers orphelins dans la base
|
|
||||||
- ✅ Nettoyage automatique de la base de données
|
|
||||||
- ✅ Agenda plus propre après suppression de groupes
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 5. **Enrichissement API groupes utilisateur** (`/app/api/users/[userId]/groups/route.ts`) ✨ **NOUVEAU**
|
|
||||||
|
|
||||||
#### Modifications au GET endpoint :
|
|
||||||
|
|
||||||
L'API qui récupère les groupes d'un utilisateur enrichit maintenant les données avec les couleurs des calendriers :
|
|
||||||
|
|
||||||
1. **Récupération des groupes**
|
|
||||||
- Appel à Keycloak pour obtenir les groupes de l'utilisateur
|
|
||||||
|
|
||||||
2. **Enrichissement avec couleurs**
|
|
||||||
- Pour chaque groupe, recherche du calendrier associé dans Prisma
|
|
||||||
- Ajout de la propriété `calendarColor` à chaque groupe
|
|
||||||
- Valeur `null` si pas de calendrier trouvé
|
|
||||||
|
|
||||||
3. **Retour enrichi**
|
|
||||||
- Les groupes retournés contiennent maintenant `calendarColor`
|
|
||||||
- Visible immédiatement dans la page Vision
|
|
||||||
|
|
||||||
#### Impact :
|
|
||||||
- ✅ La page Vision affiche les bonnes couleurs
|
|
||||||
- ✅ Pas besoin de requêtes supplémentaires côté client
|
|
||||||
- ✅ Une seule API call pour tout charger
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔄 Flux de données
|
|
||||||
|
|
||||||
### Chargement initial :
|
|
||||||
```
|
|
||||||
1. Page charge les groupes via GET /api/groups
|
|
||||||
2. Pour chaque groupe :
|
|
||||||
└─> GET /api/groups/{groupId}/calendar
|
|
||||||
└─> Récupère la couleur du calendrier
|
|
||||||
└─> Stocke dans state local : group.calendarColor
|
|
||||||
```
|
|
||||||
|
|
||||||
### Modification de couleur :
|
|
||||||
```
|
|
||||||
1. Utilisateur clique sur icône palette
|
|
||||||
2. Dialog s'ouvre avec couleur actuelle
|
|
||||||
3. Utilisateur sélectionne nouvelle couleur
|
|
||||||
4. Clic "Enregistrer"
|
|
||||||
└─> PATCH /api/groups/{groupId}/calendar { color: "#newcolor" }
|
|
||||||
└─> Vérification membre du groupe (Keycloak)
|
|
||||||
└─> Mise à jour en base de données (Prisma)
|
|
||||||
└─> Mise à jour du state local
|
|
||||||
└─> Toast de confirmation
|
|
||||||
5. Couleur visible immédiatement partout
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 Points d'affichage de la couleur
|
|
||||||
|
|
||||||
La couleur du calendrier de groupe est maintenant visible dans :
|
|
||||||
|
|
||||||
1. **`/groups`** - Page groupes
|
|
||||||
- Table des groupes (pastille à côté du nom)
|
|
||||||
|
|
||||||
2. **`/missions/equipe`** - Page gestion équipe
|
|
||||||
- Table des groupes (icône colorée)
|
|
||||||
|
|
||||||
3. **`/agenda`** - Page agenda
|
|
||||||
- Liste des calendriers (pastille à gauche)
|
|
||||||
- Événements dans le calendrier (barre colorée)
|
|
||||||
|
|
||||||
4. **`/vision`** - Page visioconférences ✨ **NOUVEAU**
|
|
||||||
- Cercle coloré autour de l'icône groupe
|
|
||||||
- Icône en blanc si couleur personnalisée, en bleu sinon
|
|
||||||
- Couleur par défaut : `#DBEAFE` (bleu clair)
|
|
||||||
|
|
||||||
5. **Widgets calendrier** - Tous les composants calendrier
|
|
||||||
- `calendar-widget.tsx`
|
|
||||||
- `calendar-client.tsx`
|
|
||||||
- `calendar.tsx`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🧪 Tests suggérés
|
|
||||||
|
|
||||||
### Test 1 : Modification de couleur
|
|
||||||
1. Aller sur `/groups` ou `/missions/equipe`
|
|
||||||
2. Cliquer sur ⋯ → "Couleur du calendrier"
|
|
||||||
3. Choisir une nouvelle couleur
|
|
||||||
4. Cliquer "Enregistrer"
|
|
||||||
5. ✅ Vérifier : Pastille mise à jour immédiatement
|
|
||||||
|
|
||||||
### Test 2 : Validation format
|
|
||||||
1. Ouvrir dialog couleur
|
|
||||||
2. Entrer manuellement un code invalide : `#GGGGGG`
|
|
||||||
3. Cliquer "Enregistrer"
|
|
||||||
4. ✅ Vérifier : Message d'erreur affiché
|
|
||||||
|
|
||||||
### Test 3 : Permissions
|
|
||||||
1. Se connecter avec utilisateur NON membre du groupe
|
|
||||||
2. Essayer de modifier la couleur
|
|
||||||
3. ✅ Vérifier : Erreur 403 "Vous devez être membre du groupe"
|
|
||||||
|
|
||||||
### Test 4 : Persistance
|
|
||||||
1. Modifier couleur d'un groupe
|
|
||||||
2. Actualiser la page
|
|
||||||
3. ✅ Vérifier : Couleur conservée
|
|
||||||
4. Aller sur `/agenda`
|
|
||||||
5. ✅ Vérifier : Couleur visible dans le calendrier
|
|
||||||
|
|
||||||
### Test 5 : Affichage dans Vision ✨ **NOUVEAU**
|
|
||||||
1. Modifier la couleur d'un groupe
|
|
||||||
2. Aller sur `/vision`
|
|
||||||
3. ✅ Vérifier : Le cercle autour de l'icône du groupe a la bonne couleur
|
|
||||||
4. ✅ Vérifier : L'icône est en blanc si couleur personnalisée
|
|
||||||
|
|
||||||
### Test 6 : Suppression du calendrier ✨ **NOUVEAU**
|
|
||||||
1. Créer un nouveau groupe
|
|
||||||
2. Vérifier dans `/agenda` que le calendrier est créé
|
|
||||||
3. Supprimer le groupe dans `/missions/equipe`
|
|
||||||
4. Aller sur `/agenda`
|
|
||||||
5. ✅ Vérifier : Le calendrier du groupe a été supprimé
|
|
||||||
6. ✅ Vérifier : Aucune erreur dans la console
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📁 Fichiers modifiés
|
|
||||||
|
|
||||||
### Nouveaux fichiers :
|
|
||||||
- `app/api/groups/[groupId]/calendar/route.ts` (nouveau endpoint API)
|
|
||||||
|
|
||||||
### Fichiers modifiés :
|
|
||||||
|
|
||||||
#### 1. Gestion des couleurs :
|
|
||||||
|
|
||||||
- `components/groups/groups-table.tsx`
|
|
||||||
- Import `Palette` de lucide-react
|
|
||||||
- Ajout interface `calendarColor?` à Group
|
|
||||||
- Ajout états `colorPickerDialog`, `selectedGroupForColor`, `selectedColor`
|
|
||||||
- Fonction `fetchGroups()` modifiée pour charger couleurs
|
|
||||||
- Fonctions `handleOpenColorPicker()` et `handleSaveColor()`
|
|
||||||
- Palette de couleurs `colorPalette`
|
|
||||||
- Dialog de sélection de couleur
|
|
||||||
- Affichage pastille dans table
|
|
||||||
|
|
||||||
- `app/missions/equipe/page.tsx`
|
|
||||||
- Import `Palette` de lucide-react
|
|
||||||
- Ajout interface `calendarColor?` à Group
|
|
||||||
- Ajout états color picker
|
|
||||||
- Fonction `fetchData()` modifiée pour charger couleurs
|
|
||||||
- Fonctions `handleOpenColorPicker()` et `handleSaveColor()`
|
|
||||||
- Palette de couleurs
|
|
||||||
- Bouton palette dans actions
|
|
||||||
- Dialog de sélection de couleur
|
|
||||||
- Affichage icône colorée
|
|
||||||
|
|
||||||
#### 2. Affichage dans Vision : ✨ **NOUVEAU**
|
|
||||||
|
|
||||||
- `app/vision/page.tsx`
|
|
||||||
- Ajout `calendarColor?` à interface `Group`
|
|
||||||
- Modification affichage du cercle groupe pour utiliser `group.calendarColor`
|
|
||||||
- Style dynamique : couleur personnalisée ou défaut `#DBEAFE`
|
|
||||||
- Icône blanche si couleur personnalisée, bleue sinon
|
|
||||||
|
|
||||||
#### 3. Suppression automatique : ✨ **NOUVEAU**
|
|
||||||
|
|
||||||
- `app/api/groups/[groupId]/route.ts`
|
|
||||||
- Endpoint DELETE modifié
|
|
||||||
- Import `prisma` et `logger`
|
|
||||||
- Récupération des détails du groupe avant suppression
|
|
||||||
- Suppression du calendrier associé via `prisma.calendar.deleteMany()`
|
|
||||||
- Logs détaillés
|
|
||||||
|
|
||||||
#### 4. Enrichissement API : ✨ **NOUVEAU**
|
|
||||||
|
|
||||||
- `app/api/users/[userId]/groups/route.ts`
|
|
||||||
- Import `prisma`
|
|
||||||
- Endpoint GET enrichi
|
|
||||||
- Recherche du calendrier pour chaque groupe
|
|
||||||
- Ajout de `calendarColor` aux données retournées
|
|
||||||
- Gestion d'erreurs pour chaque groupe
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔮 Améliorations futures possibles
|
|
||||||
|
|
||||||
1. **Color picker avancé**
|
|
||||||
- Utiliser un vrai color picker (ex: `react-color`)
|
|
||||||
- Support HSL, RGB en plus de hex
|
|
||||||
|
|
||||||
2. **Thèmes prédéfinis**
|
|
||||||
- Palettes thématiques (pastel, vif, entreprise, etc.)
|
|
||||||
- Sauvegarde de palettes personnalisées
|
|
||||||
|
|
||||||
3. **Permissions granulaires**
|
|
||||||
- Seuls les admins du groupe peuvent changer la couleur
|
|
||||||
- Rôle "gestionnaire de groupe" dans Keycloak
|
|
||||||
|
|
||||||
4. **Historique des couleurs**
|
|
||||||
- Log des changements de couleur
|
|
||||||
- Possibilité de revenir en arrière
|
|
||||||
|
|
||||||
5. **Synchronisation**
|
|
||||||
- Webhook pour notifier les autres utilisateurs en temps réel
|
|
||||||
- WebSocket pour mise à jour instantanée sans refresh
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 Impact sur les performances
|
|
||||||
|
|
||||||
- **Chargement initial** : +1 requête API par groupe (GET calendar)
|
|
||||||
- **Modification** : 1 requête PATCH, pas de refresh complet
|
|
||||||
- **Cache** : Les calendriers sont déjà en cache Redis (GET /api/calendars)
|
|
||||||
- **Optimisation** : Possibilité de batch les requêtes GET calendar en une seule
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🐛 Problèmes résolus
|
|
||||||
|
|
||||||
### ✅ Problème 1 : Calendriers orphelins après suppression de groupe
|
|
||||||
**Symptôme** : Quand on supprimait un groupe, son calendrier restait dans la base de données et s'affichait dans l'agenda.
|
|
||||||
|
|
||||||
**Solution** : Modification du endpoint DELETE pour supprimer automatiquement le calendrier associé lors de la suppression du groupe.
|
|
||||||
|
|
||||||
**Commit** : Ajout de la suppression automatique dans `/app/api/groups/[groupId]/route.ts`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### ✅ Problème 2 : Couleurs non visibles dans la page Vision
|
|
||||||
**Symptôme** : Les couleurs de calendrier personnalisées n'apparaissaient pas dans `/vision`, tous les groupes avaient la même couleur bleue.
|
|
||||||
|
|
||||||
**Solution** :
|
|
||||||
1. Enrichissement de l'API `/api/users/[userId]/groups` pour inclure `calendarColor`
|
|
||||||
2. Modification de l'interface `Group` dans `vision/page.tsx`
|
|
||||||
3. Affichage dynamique des couleurs dans l'UI
|
|
||||||
|
|
||||||
**Commit** : Enrichissement API et affichage dans Vision
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🐛 Problèmes connus
|
|
||||||
|
|
||||||
Aucun problème connu pour le moment.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✅ Checklist de déploiement
|
|
||||||
|
|
||||||
- [x] API créée et testée
|
|
||||||
- [x] Interface utilisateur implémentée
|
|
||||||
- [x] Validation des permissions
|
|
||||||
- [x] Gestion des erreurs
|
|
||||||
- [x] Pas d'erreurs de linting
|
|
||||||
- [ ] Tests unitaires (à ajouter)
|
|
||||||
- [ ] Tests E2E (à ajouter)
|
|
||||||
- [ ] Documentation utilisateur (à ajouter)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📞 Support
|
|
||||||
|
|
||||||
Pour toute question ou problème :
|
|
||||||
1. Vérifier que l'utilisateur est bien membre du groupe
|
|
||||||
2. Vérifier le format de la couleur (hex valide)
|
|
||||||
3. Vérifier les logs serveur pour les erreurs Keycloak
|
|
||||||
4. Vérifier que le calendrier du groupe existe en base
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Date de création** : 20 janvier 2026
|
|
||||||
**Dernière mise à jour** : 21 janvier 2026
|
|
||||||
**Version** : 1.2
|
|
||||||
**Auteur** : Senior Developer Assistant
|
|
||||||
|
|
||||||
### 📝 Changelog
|
|
||||||
|
|
||||||
#### v1.2 (21 janvier 2026)
|
|
||||||
- ✨ Ajout : Suppression automatique du calendrier lors de la suppression d'un groupe
|
|
||||||
- ✨ Ajout : Affichage des couleurs dans la page Vision (`/vision`)
|
|
||||||
- 🔧 Modification : Enrichissement de l'API `/api/users/[userId]/groups` avec les couleurs
|
|
||||||
- 📚 Documentation : Ajout de nouveaux tests et problèmes résolus
|
|
||||||
|
|
||||||
#### v1.1 (20 janvier 2026)
|
|
||||||
- 🐛 Fix : Problèmes de déploiement Docker
|
|
||||||
- 📚 Documentation : Ajout du guide de déploiement
|
|
||||||
|
|
||||||
#### v1.0 (20 janvier 2026)
|
|
||||||
- ✨ Version initiale avec modification des couleurs de calendrier
|
|
||||||
@ -1,192 +0,0 @@
|
|||||||
# Flow complet des tâches Leantime dans le widget Devoirs
|
|
||||||
|
|
||||||
## 1. BACKEND - API Route `/api/leantime/tasks` (app/api/leantime/tasks/route.ts)
|
|
||||||
|
|
||||||
### Étape 1.1 : Vérification de session
|
|
||||||
- **Ligne 91-95** : Vérifie la session utilisateur
|
|
||||||
- Si pas de session → retourne 401 Unauthorized
|
|
||||||
|
|
||||||
### Étape 1.2 : Vérification du cache Redis
|
|
||||||
- **Ligne 103-141** : Si `forceRefresh=false`, vérifie le cache Redis
|
|
||||||
- **Ligne 107-123** : **FILTRE 1** - Filtre les tâches "done" du cache :
|
|
||||||
- Statuts filtrés : `0`, `3`, `5` (ou strings `'0'`, `'3'`, `'5'`, `'Done'`, `'done'`, `'DONE'`)
|
|
||||||
- Si des tâches "done" sont trouvées dans le cache, elles sont supprimées
|
|
||||||
- Le cache est mis à jour avec les tâches filtrées
|
|
||||||
- Si cache valide → retourne les tâches filtrées du cache (ligne 139)
|
|
||||||
|
|
||||||
### Étape 1.3 : Récupération de l'ID utilisateur Leantime
|
|
||||||
- **Ligne 146** : `getLeantimeUserId(session.user.email)`
|
|
||||||
- Appelle l'API Leantime `leantime.rpc.users.getAll`
|
|
||||||
- Trouve l'utilisateur par `username === email`
|
|
||||||
- Retourne `user.id` ou `null`
|
|
||||||
|
|
||||||
### Étape 1.4 : Appel API Leantime
|
|
||||||
- **Ligne 165-178** : Appelle `leantime.rpc.tickets.getAll` avec :
|
|
||||||
- `userId: userId`
|
|
||||||
- `status: "all"` (récupère TOUTES les tâches, tous statuts confondus)
|
|
||||||
- **Ligne 193-195** : Log toutes les tâches brutes reçues de Leantime
|
|
||||||
|
|
||||||
### Étape 1.5 : Filtrage des tâches
|
|
||||||
- **Ligne 217-249** : **FILTRE 2** - Filtre les tâches :
|
|
||||||
|
|
||||||
**a) Filtre par statut "done" (ligne 223-240)** :
|
|
||||||
- Statuts filtrés : `0`, `3`, `5` (ou strings `'0'`, `'3'`, `'5'`, `'done'`)
|
|
||||||
- Si `isDone === true` → la tâche est exclue (`return false`)
|
|
||||||
|
|
||||||
**b) Filtre par éditeur (ligne 242-248)** :
|
|
||||||
- Seules les tâches où `task.editorId === userId` sont gardées
|
|
||||||
- Si `taskEditorId !== currentUserId` → la tâche est exclue
|
|
||||||
|
|
||||||
### Étape 1.6 : Transformation des données
|
|
||||||
- **Ligne 250-266** : Transforme les tâches Leantime en format standard :
|
|
||||||
```typescript
|
|
||||||
{
|
|
||||||
id: task.id.toString(),
|
|
||||||
headline: task.headline,
|
|
||||||
projectName: task.projectName,
|
|
||||||
projectId: task.projectId,
|
|
||||||
status: task.status, // ⚠️ LE STATUT EST INCLUS ICI
|
|
||||||
dateToFinish: task.dateToFinish || null,
|
|
||||||
milestone: task.type || null,
|
|
||||||
details: task.description || null,
|
|
||||||
createdOn: task.dateCreated,
|
|
||||||
editedOn: task.editedOn || null,
|
|
||||||
editorId: task.editorId,
|
|
||||||
editorFirstname: task.editorFirstname,
|
|
||||||
editorLastname: task.editorLastname,
|
|
||||||
type: task.type || null,
|
|
||||||
dependingTicketId: task.dependingTicketId || null
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Étape 1.7 : Mise en cache
|
|
||||||
- **Ligne 292** : Met en cache les tâches filtrées dans Redis
|
|
||||||
- **Ligne 294** : Retourne les tâches filtrées en JSON
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. FRONTEND - Widget Devoirs (components/flow.tsx)
|
|
||||||
|
|
||||||
### Étape 2.1 : Appel API
|
|
||||||
- **Ligne 107-113** : Appelle `/api/leantime/tasks` (ou `/api/leantime/tasks?refresh=true`)
|
|
||||||
- **Ligne 117-127** : Récupère les données JSON et les assigne à `leantimeTasks`
|
|
||||||
- **Ligne 121-126** : Log toutes les tâches reçues avec leur statut
|
|
||||||
|
|
||||||
### Étape 2.2 : Détection des tâches "done" (pour log uniquement)
|
|
||||||
- **Ligne 129-143** : Détecte les tâches avec statut `5` ou `'done'` (⚠️ NE FILTRE PAS LE STATUT 0)
|
|
||||||
- Affiche un warning si des tâches "done" sont trouvées
|
|
||||||
|
|
||||||
### Étape 2.3 : Analyse des statuts (pour log uniquement)
|
|
||||||
- **Ligne 164-178** : Crée `leantimeStatusDetails` avec calcul de `isDone`
|
|
||||||
- **Ligne 168** : `isDone = statusNum === 0 || statusNum === 3 || statusNum === 5 || ...`
|
|
||||||
- **Ligne 193** : Filtre les tâches "done" pour le log `doneTasksCount`
|
|
||||||
- **Ligne 201-206** : Log le breakdown des statuts
|
|
||||||
|
|
||||||
### Étape 2.4 : Combinaison avec Twenty CRM
|
|
||||||
- **Ligne 161** : Combine `leantimeTasks` et `twentyCrmTasks` dans `allTasks`
|
|
||||||
|
|
||||||
### Étape 2.5 : Filtrage frontend
|
|
||||||
- **Ligne 242-281** : **FILTRE 3** - Filtre les tâches :
|
|
||||||
|
|
||||||
**a) Filtre par statut "done" (ligne 245-260)** :
|
|
||||||
- Statuts filtrés : `0`, `3`, `5` (ou strings `'0'`, `'3'`, `'5'`, `'done'`)
|
|
||||||
- Si le statut correspond → la tâche est exclue (`return false`)
|
|
||||||
|
|
||||||
**b) Filtre par date (ligne 262-280)** :
|
|
||||||
- Exclut les tâches sans `dateToFinish`
|
|
||||||
- Garde uniquement les tâches avec `dateToFinish <= today` (overdue ou due today)
|
|
||||||
|
|
||||||
### Étape 2.6 : Tri
|
|
||||||
- **Ligne 296-317** : Trie les tâches :
|
|
||||||
1. Par `dateToFinish` (oldest first)
|
|
||||||
2. Si dates égales, par statut (statut `4` en premier)
|
|
||||||
|
|
||||||
### Étape 2.7 : Notification badge
|
|
||||||
- **Ligne 362-366** : Met à jour le badge de notification avec le nombre de tâches
|
|
||||||
|
|
||||||
### Étape 2.8 : Affichage
|
|
||||||
- **Ligne 368** : `setTasks(sortedTasks)` - Met à jour l'état React
|
|
||||||
|
|
||||||
### Étape 2.9 : Filtrage avant notification Outlook
|
|
||||||
- **Ligne 372-390** : **FILTRE 4** - Filtre les tâches avant d'envoyer l'événement `tasks-updated` :
|
|
||||||
- **Ligne 380** : ⚠️ **PROBLÈME ICI** - Ne filtre que `3` et `5`, PAS le statut `0` !
|
|
||||||
- Si `isDone === true` → la tâche est exclue
|
|
||||||
- **Ligne 391-398** : Transforme les tâches pour l'événement (sans inclure le `status`)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. PROBLÈMES IDENTIFIÉS
|
|
||||||
|
|
||||||
### Problème 1 : Filtre ligne 380 dans flow.tsx
|
|
||||||
- **Ligne 380** : `isDone = taskStatus === 3 || taskStatus === 5 || ...`
|
|
||||||
- **Manque** : `taskStatus === 0`
|
|
||||||
- **Impact** : Les tâches avec statut `0` passent le filtre et sont envoyées dans l'événement `tasks-updated`
|
|
||||||
|
|
||||||
### Problème 2 : Détection ligne 129-135 dans flow.tsx
|
|
||||||
- **Ligne 134** : Ne détecte que le statut `5`, pas `0` ni `3`
|
|
||||||
- **Impact** : Le log `⚠️ Received done tasks` ne détecte pas toutes les tâches "done"
|
|
||||||
|
|
||||||
### Problème 3 : Le statut n'est pas inclus dans l'événement tasks-updated
|
|
||||||
- **Ligne 391-398** : L'objet envoyé dans l'événement ne contient pas le champ `status`
|
|
||||||
- **Impact** : Les hooks qui écoutent `tasks-updated` ne peuvent pas filtrer par statut
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4. FLOW RÉSUMÉ
|
|
||||||
|
|
||||||
```
|
|
||||||
1. API Leantime (toutes les tâches, tous statuts)
|
|
||||||
↓
|
|
||||||
2. FILTRE 1 (cache) : Exclut statuts 0, 3, 5
|
|
||||||
↓
|
|
||||||
3. FILTRE 2 (API backend) : Exclut statuts 0, 3, 5 + filtre par editorId
|
|
||||||
↓
|
|
||||||
4. Transformation + Cache Redis
|
|
||||||
↓
|
|
||||||
5. Frontend reçoit les tâches (avec statut inclus)
|
|
||||||
↓
|
|
||||||
6. FILTRE 3 (frontend) : Exclut statuts 0, 3, 5 + filtre par date
|
|
||||||
↓
|
|
||||||
7. Tri par date
|
|
||||||
↓
|
|
||||||
8. FILTRE 4 (avant notification) : ⚠️ Exclut seulement statuts 3, 5 (MANQUE 0)
|
|
||||||
↓
|
|
||||||
9. Événement tasks-updated (sans statut dans l'objet)
|
|
||||||
↓
|
|
||||||
10. Affichage dans le widget
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 5. CORRECTIONS NÉCESSAIRES
|
|
||||||
|
|
||||||
1. **Ligne 380 dans flow.tsx** : Ajouter `taskStatus === 0` au filtre ✅ CORRIGÉ
|
|
||||||
2. **Ligne 134 dans flow.tsx** : Ajouter détection des statuts `0` et `3` ✅ CORRIGÉ
|
|
||||||
3. **Ligne 391-398 dans flow.tsx** : Inclure le champ `status` dans l'objet envoyé dans l'événement
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 6. SIGNIFICATION DES STATUTS LEANTIME
|
|
||||||
|
|
||||||
D'après le code :
|
|
||||||
|
|
||||||
### Mapping standard (app/api/leantime/status-labels/route.ts) :
|
|
||||||
- **Status 1** = 'NEW'
|
|
||||||
- **Status 2** = 'INPROGRESS'
|
|
||||||
- **Status 3** = 'DONE' ⚠️
|
|
||||||
- **Status 0** = Non défini (tombe dans `default: 'UNKNOWN'`)
|
|
||||||
|
|
||||||
### Mapping dans le widget (components/flow.tsx) :
|
|
||||||
- **Status 1** = 'New'
|
|
||||||
- **Status 2** = 'Blocked'
|
|
||||||
- **Status 3** = 'In Progress' ⚠️ **INCOHÉRENCE avec status-labels**
|
|
||||||
- **Status 4** = 'Waiting for Approval'
|
|
||||||
- **Status 5** = 'Done'
|
|
||||||
- **Status 0** = 'Unknown' (par défaut)
|
|
||||||
|
|
||||||
### Statuts filtrés comme "done" :
|
|
||||||
- **Status 0** = "Done" (dans votre instance Leantime, configuration personnalisée)
|
|
||||||
- **Status 3** = "Done" (selon `status-labels/route.ts`)
|
|
||||||
- **Status 5** = "Done" (selon `flow.tsx`)
|
|
||||||
|
|
||||||
**Note** : Il y a une incohérence entre les deux mappings. Le statut 3 est mappé à "DONE" dans `status-labels` mais à "In Progress" dans `flow.tsx`. Le statut 0 n'est pas standard dans Leantime mais semble être utilisé comme "done" dans votre instance.
|
|
||||||
@ -1,65 +0,0 @@
|
|||||||
# 🚀 Démarrage Rapide - Production Docker
|
|
||||||
|
|
||||||
## Installation en 5 minutes
|
|
||||||
|
|
||||||
### 1. Préparer l'environnement
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Copier le fichier d'exemple
|
|
||||||
cp env.production.example .env.production
|
|
||||||
|
|
||||||
# Éditer avec vos valeurs
|
|
||||||
nano .env.production
|
|
||||||
```
|
|
||||||
|
|
||||||
**⚠️ IMPORTANT** : Changez au minimum :
|
|
||||||
- `POSTGRES_PASSWORD`
|
|
||||||
- `REDIS_PASSWORD`
|
|
||||||
- `NEXTAUTH_SECRET` (générez avec `openssl rand -base64 32`)
|
|
||||||
|
|
||||||
### 2. Déployer
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Option A: Utiliser le script automatique
|
|
||||||
./scripts/deploy-prod.sh
|
|
||||||
|
|
||||||
# Option B: Commandes manuelles
|
|
||||||
docker-compose -f docker-compose.prod.yml --env-file .env.production build
|
|
||||||
docker-compose -f docker-compose.prod.yml --env-file .env.production up -d db redis
|
|
||||||
sleep 15
|
|
||||||
docker-compose -f docker-compose.prod.yml --env-file .env.production run --rm app npx --yes prisma@6.4.1 migrate deploy
|
|
||||||
docker-compose -f docker-compose.prod.yml --env-file .env.production up -d app
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Vérifier
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Vérifier que tout fonctionne
|
|
||||||
curl http://localhost:3000/api/health
|
|
||||||
|
|
||||||
# Voir les logs
|
|
||||||
docker-compose -f docker-compose.prod.yml logs -f app
|
|
||||||
```
|
|
||||||
|
|
||||||
## Commandes utiles
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Arrêter
|
|
||||||
docker-compose -f docker-compose.prod.yml --env-file .env.production down
|
|
||||||
|
|
||||||
# Redémarrer
|
|
||||||
docker-compose -f docker-compose.prod.yml --env-file .env.production restart app
|
|
||||||
|
|
||||||
# Voir les logs
|
|
||||||
docker-compose -f docker-compose.prod.yml --env-file .env.production logs -f
|
|
||||||
|
|
||||||
# Appliquer les migrations
|
|
||||||
docker-compose -f docker-compose.prod.yml --env-file .env.production run --rm app npx --yes prisma@6.4.1 migrate deploy
|
|
||||||
|
|
||||||
# Accéder à la base de données
|
|
||||||
docker-compose -f docker-compose.prod.yml --env-file .env.production exec db psql -U neah_user -d calendar_db
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📖 Documentation complète
|
|
||||||
|
|
||||||
Voir `DEPLOYMENT.md` pour la documentation complète.
|
|
||||||
Loading…
Reference in New Issue
Block a user