💬 CAHIER DES CHARGES COMPLET - Site de Communauté (Community Platform)
🎯 OBJECTIF GLOBAL
Créer une plateforme communautaire en ligne complète où les utilisateurs peuvent :
- S'inscrire et créer un profil personnalisé
- Créer et rejoindre des communautés thématiques
- Discuter en temps réel via chat (WebSockets)
- Partager du contenu (texte, images, liens)
- Envoyer des messages directs (DM) à d'autres utilisateurs
- Se faire des amis et former des groupes
- Organiser des événements et consulter un calendrier
- Système de modération et de permissions
Comparaison avec d'autres plateformes : Mix entre Discord (chat temps réel), Reddit (communautés thématiques), et un forum moderne
👤 INFORMATIONS CRÉATEUR
| Information | Détail |
|---|---|
| Créateur | Garabou (Étudiant Bachelor Réseau Informatique) |
| Entreprise | Nicomatic (alternance) |
| Type de plateforme | Communauté généraliste multi-thèmes |
| Utilisateurs cibles | N'importe qui (amis, communautés d'intérêts, groupes) |
| Modèle économique | Gratuit de base → Abonnement premium (Phase futur) |
| Valeur pédagogique | Backend moderne, WebSockets, BD complexe, scalabilité |
🏗️ ARCHITECTURE TECHNIQUE COMPLÈTE
INFRASTRUCTURE D'HÉBERGEMENT
| Élément | Détail |
|---|---|
| Type VM | À définir (nouvelle VM OU VM 105 Nextcloud) |
| Système d'exploitation | Linux (Debian/Ubuntu/Arch) |
| Ressources recommandées | Min 4 CPU, 8 GB RAM, 100 GB disque |
| Adresse IP | À définir (ex: 192.168.0.xxx) |
| Domaine futur | co.garabou.com OU community.garabou.com |
| Port en développement | 3000 (Node.js recommandé) ou 8000 |
| Port en production | 80 (HTTP) / 443 (HTTPS avec reverse proxy) |
| Reverse proxy | Nginx (pour gérer HTTPS, routing) |
STACK TECHNIQUE RECOMMANDÉE
Backend
| Composant | Option A (Recommandé) | Option B (Alternative) |
|---|---|---|
| Langage | Node.js 18+ | Python 3.10+ |
| Framework | Express.js | FastAPI ou Django |
| Avantages | Meilleur pour WebSockets, plus rapide | Plus simple à maintenir long terme |
| WebSockets | Socket.io (facile) | FastAPI WebSockets (native) |
| Performance | ⭐⭐⭐ | ⭐⭐ |
Choix final recommandé : Node.js + Express + Socket.io
Frontend
| Élément | Recommandé |
|---|---|
| Framework | React 18+ OU Vue.js 3+ |
| Alternative simple | HTML5 + CSS3 + JavaScript Vanilla |
| Gestion d'état | Redux (React) OU Vuex (Vue) |
| HTTP Client | Axios OU Fetch API |
| Responsive | Mobile-first design |
| CSS Framework | Tailwind CSS OU Bootstrap OU custom |
Base de Données
| Aspect | Détail |
|---|---|
| Système principal | PostgreSQL 14+ (robuste, scalable) |
| Alternative | MongoDB (plus flexible mais moins relationnel) |
| Connexion | pg (Node.js) OU Sequelize (ORM) |
| Migrations | Flyway OU Alembic |
| Backup | Automatisé (pg_dump, logs WAL) |
Communication Temps Réel
| Élément | Détail |
|---|---|
| WebSockets | Socket.io (Node.js + Express) |
| Alternative | Native WebSockets avec fallback polling |
| Namespace | Séparation par communauté, DM, notifications |
| Événements | message:send, typing:start, user:status, etc. |
| Scaling futur | Redis pour partager état entre serveurs |
Stockage Fichiers
| Type | Détail |
|---|---|
| Avatars/Images | Dossier /uploads/ local OU S3-compatible |
| Fichiers partagés | Limiter à 10-50 MB par fichier |
| Optimisation | Compresser images, générer thumbnails |
Sécurité
| Aspect | Implémentation |
|---|---|
| Authentification | JWT (JSON Web Tokens) |
| Mot de passe | Bcrypt (hash) + salt |
| HTTPS | Certificat Let's Encrypt (gratuit) |
| CORS | Configuré strictement |
| Rate limiting | 100 req/min par IP |
| Validation input | Sanitisation (SQL injection, XSS) |
| Secrets | Variables d'env (.env file) |
📊 FEATURES PRINCIPALES (DÉTAILLÉES)
1. AUTHENTIFICATION & GESTION UTILISATEUR
1.1 - Inscription
- Email obligatoire (unique)
- Mot de passe (min 8 caractères, 1 majuscule, 1 chiffre)
- Confirmation email (lien de vérification)
- Nom d'utilisateur unique (3-30 caractères, alphanumériques + underscore)
- Acceptation conditions d'utilisation
- Optionnel : Avatar lors de l'inscription
1.2 - Connexion
- Email + Mot de passe
- OU OAuth (Google, GitHub) - Phase 2
- JWT Token généré (valide 7 jours)
- Refresh token (30 jours)
- Remember me option
- 2FA optionnel (Phase 3)
1.3 - Profil Utilisateur
{
"id": "uuid_string",
"username": "garabou",
"email": "garabou@example.com",
"avatar_url": "https://co.garabou.com/uploads/avatars/uuid.jpg",
"bio": "Étudiant en réseau, passionné par Linux et l'infra",
"status": "online|offline|away|dnd",
"last_seen": "2025-11-03T15:30:00Z",
"friends": ["user_id_456", "user_id_789"],
"blocked_users": ["user_id_999"],
"followers_count": 150,
"following_count": 80,
"is_verified": false,
"role": "user|moderator|admin",
"joined_at": "2025-11-03T10:00:00Z",
"updated_at": "2025-11-03T15:30:00Z"
}
1.4 - Paramètres Utilisateur
- Privacité : Public / Amis seulement / Privé
- Notifications : Activer/Désactiver par type
- Apparence : Mode clair / sombre / auto
- Langue : FR / EN / ES (futur)
- Blocage : Liste des utilisateurs bloqués
- Sessions actives : Voir/Déconnecter les appareils
2. COMMUNAUTÉS / SERVEURS
2.1 - Structure Communauté
{
"id": "uuid_community",
"name": "Linux Enthusiasts",
"slug": "linux-enthusiasts",
"description": "Communauté dédiée à Linux, Arch, Ubuntu, infrastructure",
"icon_url": "https://co.garabou.com/uploads/communities/uuid.jpg",
"banner_url": "https://co.garabou.com/uploads/banners/uuid.jpg",
"type": "public|private|invite_only",
"visibility": "visible|hidden",
"members_count": 524,
"rules": [
"Pas de spam",
"Respectez les autres",
"Pas de contenu NSFW",
"Aide et entraide bienvenues"
],
"created_by": "user_id_123",
"owner_id": "user_id_123",
"moderators": ["user_id_456", "user_id_789"],
"created_at": "2025-11-03T10:00:00Z",
"updated_at": "2025-11-03T15:30:00Z",
"metadata": {
"default_channel": "general",
"require_email_verification": false,
"auto_approve_members": true
}
}
2.2 - Types de Communautés
| Type | Description | Qui peut voir ? | Qui peut rejoindre ? |
|---|---|---|---|
| Public | Visible partout | Tout le monde | Demande directe |
| Private | Pas visible | Seulement membres | Invitation du propriétaire |
| Invite-only | Cachée | Seulement membres | Invitation obligatoire |
2.3 - Rôles dans Communauté
1. PROPRIÉTAIRE (Owner)
- Créer/Supprimer communauté
- Toutes les permissions
- Transférer propriété
- Voir analytics
2. MODÉRATEUR (Moderator)
- Supprimer messages
- Bannir/Mute utilisateurs
- Créer canaux
- Voir logs modération
3. MEMBRE (Member)
- Poster messages
- Réagir aux messages
- Rejoindre canaux
- Envoyer DM
4. INVITÉ (Guest - pour private)
- Lecture seule (si configuré)
- Attend approbation
2.4 - Actions Communauté
- Créer une communauté (propriétaire)
- Rejoindre (public) / Demander accès (private)
- Inviter amis (propriétaire/modérateur)
- Quitter communauté
- Supprimer communauté (propriétaire)
- Épingler un message important
- Créer enquête/vote
- Archiver (Phase 2)
3. CANAUX / DISCUSSIONS
3.1 - Structure Canal
{
"id": "uuid_channel",
"community_id": "uuid_community",
"name": "general",
"slug": "general",
"description": "Discussions générales sur le sujet",
"icon": "💬",
"type": "text|voice|announcement",
"visibility": "public|private",
"is_nsfw": false,
"position": 0,
"created_at": "2025-11-03T10:00:00Z",
"topic": "Discuter librement de Linux",
"slow_mode": 0,
"permissions": {
"user_role": ["read", "write", "react"],
"moderator_role": ["read", "write", "react", "delete", "manage"]
}
}
3.2 - Types de Canaux
1. TEXTE (#general, #tech, #off-topic)
- Discussion textuelle
- Support images/fichiers
- Système de réactions
2. ANNONCES (#annonces)
- Lecture seule (sauf modérateurs)
- Pin messages importants
- Notifications push
3. VOICE (Optionnel Phase 2+)
- Chat audio temps réel
- Screen sharing
- Enregistrement (optionnel)
4. THREADS (Phase 2)
- Sous-discussions d'un message
- Garder les conversations organisées
3.3 - Catégories de Canaux
Possible d'organiser les canaux en catégories :
┌─ 📋 INFORMATIONS
│ ├─ #annonces
│ └─ #bienvenue
├─ 💬 DISCUSSIONS
│ ├─ #general
│ ├─ #tech
│ └─ #off-topic
└─ 🎮 ÉVÉNEMENTS
├─ #game-night
└─ #soirée-live
4. MESSAGES
4.1 - Structure Message
{
"id": "uuid_message",
"channel_id": "uuid_channel",
"author_id": "user_id_123",
"author": {
"username": "garabou",
"avatar_url": "...",
"role": "member|moderator|owner"
},
"content": "Salut tout le monde !",
"embeds": [],
"attachments": [
{
"id": "uuid",
"filename": "image.jpg",
"url": "https://co.garabou.com/uploads/files/uuid.jpg",
"size": 524288,
"type": "image|file|video"
}
],
"reactions": {
"😂": ["user_id_456", "user_id_789"],
"❤️": ["user_id_111", "user_id_222", "user_id_333"],
"👍": ["user_id_444"]
},
"replies_count": 3,
"is_pinned": false,
"is_edited": false,
"created_at": "2025-11-03T15:30:00Z",
"updated_at": "2025-11-03T15:35:00Z"
}
4.2 - Fonctionnalités Messages
- Envoyer message texte
- Uploader images (max 10 MB)
- Uploader fichiers (max 50 MB)
- Mentions (@username) - notification
- Émojis unicode + émojis custom (futur)
- Réactions avec émojis
- Éditer message (5 min après envoi, alors "edited")
- Supprimer message (propriétaire du message / modérateur)
- Répondre à un message (reply/thread - Phase 2)
- Pin/Unpin message (modérateur)
- Partager message (lien direct)
4.3 - Format Texte
- Markdown basique autorisé :
*italique*
**gras**
__souligné__
~~barré~~
`code inline`
```code block```
> citation
- @mentions
- #hashtags (optionnel)
- URLs automatiquement cliquables
5. MESSAGES DIRECTS (DM)
5.1 - Structure DM
{
"id": "uuid_conversation",
"participants": ["user_id_123", "user_id_456"],
"last_message": {
"id": "uuid_message",
"content": "À plus tard !",
"sender_id": "user_id_123",
"created_at": "2025-11-03T15:30:00Z"
},
"unread_count": {
"user_id_123": 0,
"user_id_456": 3
},
"created_at": "2025-11-03T10:00:00Z",
"updated_at": "2025-11-03T15:30:00Z"
}
5.2 - Fonctionnalités DM
- Conversation 1-to-1 (Phase 1)
- Groupes DM jusqu'à 10 personnes (Phase 2)
- Historique persistant (illimité)
- Marquage comme lu/non-lu
- Typing indicator ("xyz est en train d'écrire...")
- État online/offline en temps réel
- Supprimer conversation (supprime côté utilisateur seulement)
- Transférer fichiers (images, fichiers)
- Rappels de messages (Phase 2)
- Épingler messages importants (Phase 2)
5.3 - Blocage
Si Utilisateur A bloque Utilisateur B :
- B ne peut pas lui envoyer de messages
- B ne peut pas le chercher
- A ne voit pas les messages de B
- A ne voit pas quand B se connecte
6. SYSTÈME D'AMIS
6.1 - Demande d'Ami
{
"id": "uuid_request",
"from_user": "user_id_123",
"to_user": "user_id_456",
"status": "pending|accepted|rejected",
"message": "Salut, je suis un ami de X !",
"created_at": "2025-11-03T15:30:00Z"
}
6.2 - Actions Amis
- Envoyer demande d'ami (avec message optionnel)
- Accepter demande
- Refuser demande
- Retirer ami (supprimer de liste)
- Lister ses amis
- Voir profil ami
- Recevoir notification quand ami online
- Favoriser certains amis (Top amis)
6.3 - Statuts Ami
PENDING : Demande envoyée, en attente
ACCEPTED : Amis
REJECTED : Demande refusée (peut renvoyer après 30j)
BLOCKED : Bloqué (il ne peut rien faire)
7. NOTIFICATIONS
7.1 - Types Notifications
1. MESSAGES
- Message mention (@user)
- Réponse à ton message
- DM reçu
2. AMIS
- Nouvelle demande d'ami
- Ami accepté la demande
- Ami se connecte (optionnel)
3. COMMUNAUTÉS
- Invitation communauté
- Tu as été nommé modérateur
- Un événement démarre
4. MODÉRATION
- Tu as été averti
- Tu as été mute/banni
- Message supprimé
5. SYSTÈME
- Nouvelle feature
- Maintenance serveur
7.2 - Canaux Notification
- In-app bell (🔔)
- Email (paramétrable)
- Push notification (futur)
- SMS (futur, premium)
7.3 - Structure Notification
{
"id": "uuid_notif",
"user_id": "user_id_123",
"type": "message_mention|friend_request|community_invite",
"title": "Nouvelle mention de garabou",
"content": "garabou t'a mentionné dans #general",
"link": "/communities/uuid/channels/general",
"icon": "https://...",
"read": false,
"created_at": "2025-11-03T15:30:00Z"
}
8. ÉVÉNEMENTS & CALENDRIER
8.1 - Structure Événement
{
"id": "uuid_event",
"community_id": "uuid_community",
"title": "Soirée Jeu de Rôle Cyberpunk",
"description": "Partie RPG en direct avec maître du jeu IA",
"start_date": "2025-11-15T20:00:00Z",
"end_date": "2025-11-15T23:00:00Z",
"location": "Discord #voice-événement",
"channel_id": "uuid_channel",
"created_by": "user_id_123",
"cover_image": "https://...",
"status": "scheduled|ongoing|cancelled|completed",
"capacity": 50,
"attendees": {
"going": ["user_id_123", "user_id_456"],
"maybe": ["user_id_789"],
"not_going": []
},
"created_at": "2025-11-03T10:00:00Z"
}
8.2 - Fonctionnalités Événements
- Créer événement (communauté)
- Afficher calendrier (vue mois/semaine/jour)
- RSVP (Oui/Peut-être/Non)
- Rappel (24h avant, 1h avant)
- Partager événement
- Modifier événement
- Annuler événement
- Archiver après fin
- Invitation automatique aux membres (optionnel)
9. MODÉRATION
9.1 - Actions Modération
1. SUPPRIMER MESSAGE
- Supprimer immédiatement
- Message retiré, raison affichée
- Modérateur enregistré
2. AVERTIR (Warning)
- Avertissement privé
- Compteur d'avertissements
- À 3 avertissements = mute temporaire
3. MUTE (Silencieux)
- 1h / 24h / 7j / permanent
- Utilisateur ne peut pas parler
- Peut lire
4. BAN
- Bannissement temporaire (1j à 30j)
- Bannissement permanent
- Utilisateur expulsé, ne peut pas rejoindre
5. KICK
- Expulsion immédiate
- Peut rejoindre après
9.2 - Logs Modération
{
"id": "uuid_log",
"community_id": "uuid_community",
"moderator_id": "user_id_456",
"action": "ban|mute|warn|delete_message|kick",
"target_user": "user_id_123",
"reason": "Spam excessif",
"duration": "7d",
"created_at": "2025-11-03T15:30:00Z"
}
9.3 - Permissions Modération
MODÉRATEUR peut :
- Supprimer messages
- Avertir utilisateurs
- Mute/Ban/Kick
- Créer canaux
- Épingler messages
- Voir les logs
MODÉRATEUR NE PEUT PAS :
- Supprimer la communauté
- Promouvoir en modérateur
- Voir identité réelle des users
10. SYSTÈME DE RÉPUTATION (Optionnel Phase 2)
10.1 - Points Réputation
+1 point : Message reçoit réaction
+5 points : Message reçoit 5+ réactions
+10 points : Aidé quelqu'un (utilisateur +1 pts)
-5 points : Message supprimé par modérateur
-10 points : Avertissement
-50 points : Bannissement
10.2 - Niveaux & Badges
NIVEAUX :
- Niveau 1 : 0-100 points (Novice)
- Niveau 2 : 101-500 points (Actif)
- Niveau 3 : 501-1000 points (Contributeur)
- Niveau 4 : 1001+ points (Expert)
BADGES :
🎖️ Helpful : +50 points
😂 Funny : Messages avec 10+ réactions
🚀 Expert : +1000 points
📅 Founder : Créateur de communauté
🛡️ Moderator : Modérateur
11. RECHERCHE
11.1 - Critères Recherche
- Utilisateurs (par username, bio)
- Communautés (par nom, description)
- Messages (par contenu, dans canal/communauté)
- Événements (par titre, date)
- Hashtags (Phase 2)
Filtres :
- Date (derniers 7j, 30j, custom)
- Type (utilisateur, communauté, message)
- Communauté spécifique
- Tri (pertinence, récent, populaire)
🎨 INTERFACE FRONTEND (DÉTAILLÉE)
Design Général
| Aspect | Spécification |
|---|---|
| Thème principal | Sombre (Dark mode par défaut) |
| Couleur fond | #1a1a1a (très sombre) |
| Couleur texte | #f0f0f0 (blanc cassé) |
| Accents primaires | Bleu #0066ff |
| Accents secondaires | Violet #8B00FF, Rose #FF006E |
| Statuts en ligne | Vert #00cc00 (online), Gris #666 (offline), Orange #ffaa00 (away) |
| Erreurs | Rouge #ff3333 |
| Succès | Vert #00cc00 |
| Polices | Inter / Poppins / Roboto (sans-serif moderne) |
| Responsive breakpoints | Desktop (1200px+), Tablet (768-1199px), Mobile (< 768px) |
| Animations | Smooth transitions (0.3s), Fade in/out |
PAGE 1 - ACCUEIL (Non authentifié)
┌─────────────────────────────────────────────┐
│ HEADER │
│ Logo "Community" [Se connecter] [S'inscrire]
├─────────────────────────────────────────────┤
│ │
│ Bienvenue sur Community │
│ La plateforme de communauté moderne │
│ │
│ [Bouton CTA "Rejoindre maintenant"] │
│ │
│ Features : │
│ ✓ Communautés thématiques │
│ ✓ Chat temps réel │
│ ✓ Événements & Calendrier │
│ ✓ Messages directs │
│ │
├─────────────────────────────────────────────┤
│ FOOTER │
│ Copyright © 2025 | Contact | Conditions │
└─────────────────────────────────────────────┘
PAGE 2 - DASHBOARD (Après authentification)
┌────────┬──────────────────────────┬──────────────┐
│ │ │ │
│ SIDEBAR│ ZONE CENTRALE │ NOTIFICATIONS│
│ │ │ │
│ [Avatar] ├──────────────────────────┤ │
│ garabou │ Feed communautés │ [Bell] (3) │
│ │ (derniers messages) │ │
│ ─────── │ │ Utilisateurs │
│ │ Message 1 de user123 │ en ligne │
│ Communautés │ Message 2 de user456 │ │
│ ⭐ Linux │ Message 3 de user789 │ user123 🟢 │
│ 💻 Réseau│ Message 4 de user111 │ user456 🟢 │
│ 🎮 Gaming│ │ user789 🔘 │
│ + Créer │ [Input pour écrire] │ │
│ │ │ Événements │
│ ─────── │ │ │
│ Amis │ │ 🎮 Soirée... │
│ • friend1 │ 📅 15 nov │
│ • friend2 │ │
│ + Ajouter │ │
│ │ │ │
└────────┴──────────────────────────┴──────────────┘
PAGE 3 - VUE COMMUNAUTÉ
┌─────────────────────────────────────────────┐
│ [BANNER IMAGE] │
├─────────────────────────────────────────────┤
│ [Icon] Linux Enthusiasts │
│ Description : Communauté Linux moderne │
│ │
│ 524 membres | [Rejoindre] [Invitation] │
├─────────────────────────────────────────────┤
│ │
│ Canaux: │ Messages: │
│ ────────────── ├─────────────────────────── │
│ 📍 INFOS │ [User123] Salut ! │
│ ├─ #annonces │ il y a 5 min │
│ ├─ #bienvenue │ │
│ │ [User456] Ça va ? │
│ 💬 DISCUS │ il y a 2 min │
│ ├─ #general │ │
│ ├─ #tech │ [Input texte] │
│ └─ #off-topic │ [Envoyer] │
│ │ │
│ 🎮 ÉVÉNEMENT │ │
│ ├─ game-night │ │
│ └─ live │ │
│ │ │
└─────────────────────────────────────────────┘
PAGE 4 - PROFIL UTILISATEUR
┌─────────────────────────────────────┐
│ [Avatar 100x100] │
│ garabou │
│ @garabou_xyz │
│ 🟢 En ligne │
│ │
│ Étudiant Bachelor Réseau │
│ Passionné par Linux et l'infra │
│ │
│ [Ajouter ami] [Bloquer] [DM] │
├─────────────────────────────────────┤
│ Amis (42) │ Communautés (8) │
│ │ │
│ • friend1 │ • Linux Fans │
│ • friend2 │ • Réseau Pro │
│ • friend3 │ • Gaming │
│ +39 autres │ +5 autres │
├─────────────────────────────────────┤
│ Messages récents │
│ "Salut, ça va ?" │
│ "Besoin d'aide pour..." │
└─────────────────────────────────────┘
PAGE 5 - MESSAGES DIRECTS
┌────────────────────┬──────────────────────┐
│ Conversations │ Chat avec User123 │
│ │ │
│ [User123] 🟢 │ User123 (en ligne) │
│ "À bientôt !" │ │
│ ├──────────────────────┤
│ [User456] 🔘 │ │
│ "Ok, merci !" │ [15:30] You: │
│ │ Salut, ça va ? │
│ [User789] 🟢 │ │
│ "D'accord" │ [15:35] User123: │
│ │ Très bien, et toi ? │
│ + Nouveau chat │ │
│ │ [15:36] User123: │
│ │ xyz est en train │
│ │ d'écrire... │
│ │ │
│ ├──────────────────────┤
│ │ [Message...] [Send] │
└────────────────────┴──────────────────────┘
PAGE 6 - CALENDRIER ÉVÉNEMENTS
┌─────────────────────────────────────┐
│ Novembre 2025 │
│ ◄ ► Mode: Mois / Semaine / Jour │
├─────────────────────────────────────┤
│ Lu | Ma | Me | Je | Ve | Sa | Di │
│ -- | -- | -- | -- | -- | -- | 1 │
│ 2 | 3 | 4 | 5 | 6 | 7 | 8 │
│ 9 | 10 | 11 | 12 | 13 | 14 |15 🎮 │
│ 16 | 17 | 18 | 19 | 20 | 21 |22 📅 │
│ ... | ... | ... │
├─────────────────────────────────────┤
│ Événements prochains │
│ │
│ 🎮 Soirée RPG - 15 nov 20:00 │
│ Linux Enthusiasts │
│ 12 personnes intéressées │
│ │
│ 📅 Meetup Réseau - 22 nov 18:00 │
│ Réseau Pro │
│ 8 personnes inscrites │
└─────────────────────────────────────┘
💻 ARCHITECTURE BACKEND (DÉTAILLÉE)
Structure de Projet Node.js + Express
project-community/
│
├── .env ← Variables d'environnement (secrets)
├── .env.example ← Template .env
├── .gitignore ← Fichiers à ignorer git
├── package.json ← Dépendances npm
├── package-lock.json
│
├── server.js ← Point d'entrée principal
│
├── config/
│ ├── database.js ← Configuration PostgreSQL
│ ├── constants.js ← Constantes globales
│ ├── env.js ← Validation variables env
│ └── socket.js ← Configuration Socket.io
│
├── models/ ← Modèles de données
│ ├── User.js
│ ├── Community.js
│ ├── Channel.js
│ ├── Message.js
│ ├── DirectMessage.js
│ ├── Friendship.js
│ ├── Event.js
│ ├── Notification.js
│ └── ModerationLog.js
│
├── routes/ ← Routes API
│ ├── auth.js ← POST /api/auth/register, login
│ ├── users.js ← GET/PUT /api/users/:id
│ ├── communities.js ← Gestion communautés
│ ├── channels.js ← Gestion canaux
│ ├── messages.js ← Gestion messages
│ ├── direct-messages.js ← Gestion DM
│ ├── friends.js ← Gestion amis
│ ├── events.js ← Gestion événements
│ ├── notifications.js ← Gestion notifications
│ └── search.js ← Recherche globale
│
├── middleware/
│ ├── auth.js ← Vérification JWT
│ ├── validation.js ← Validation inputs
│ ├── error-handler.js ← Gestion erreurs
│ └── rate-limit.js ← Rate limiting
│
├── controllers/ ← Logique métier
│ ├── authController.js
│ ├── userController.js
│ ├── communityController.js
│ ├── messageController.js
│ ├── friendController.js
│ └── ... (autres)
│
├── websocket/
│ ├── handlers/
│ │ ├── messageHandler.js ← Événements messages
│ │ ├── notificationHandler.js
│ │ ├── typingHandler.js
│ │ └── userStatusHandler.js
│ │
│ ├── namespaces.js ← Socket.io namespaces
│ └── events.js ← Liste des événements
│
├── services/
│ ├── email.js ← Envoi emails (Nodemailer)
│ ├── jwt.js ← Token JWT
│ ├── hash.js ← Bcrypt passwords
│ ├── notifications.js ← Logique notifications
│ ├── moderation.js ← Logique modération
│ └── upload.js ← Upload fichiers
│
├── utils/
│ ├── logger.js ← Logging
│ ├── helpers.js ← Fonctions utilitaires
│ ├── validators.js ← Validations customs
│ └── formatters.js ← Formatage données
│
├── database/
│ ├── migrations/ ← Migrations DB
│ │ ├── 001_create_users.sql
│ │ ├── 002_create_communities.sql
│ │ └── ...
│ │
│ └── seeds/ ← Données test
│ └── seed.sql
│
├── public/ ← Fichiers statiques
│ ├── uploads/
│ │ ├── avatars/ ← Avatars utilisateurs
│ │ ├── banners/ ← Bannières communautés
│ │ └── files/ ← Fichiers partagés
│ │
│ └── index.html ← Accueil
│
├── frontend/ ← Frontend React (optionnel)
│ ├── src/
│ │ ├── components/
│ │ ├── pages/
│ │ ├── services/
│ │ ├── store/
│ │ └── App.jsx
│ │
│ └── package.json
│
├── tests/ ← Tests unitaires
│ ├── auth.test.js
│ ├── communities.test.js
│ └── ...
│
└── docs/ ← Documentation
├── API.md ← Documentation API
├── WEBSOCKET.md ← Documentation WebSocket
└── SETUP.md ← Guide d'installation
Dépendances NPM Requises
{
"dependencies": {
"express": "^4.18.0",
"socket.io": "^4.5.0",
"pg": "^8.8.0",
"sequelize": "^6.35.0",
"jsonwebtoken": "^9.0.0",
"bcrypt": "^5.1.0",
"dotenv": "^16.0.0",
"cors": "^2.8.5",
"helmet": "^7.0.0",
"express-rate-limit": "^6.7.0",
"multer": "^1.4.5",
"sharp": "^0.32.0",
"nodemailer": "^6.9.0",
"redis": "^4.6.0",
"express-validator": "^7.0.0",
"morgan": "^1.10.0",
"winston": "^3.8.0"
},
"devDependencies": {
"jest": "^29.5.0",
"supertest": "^6.3.0",
"nodemon": "^2.0.0"
}
}
📡 API REST ENDPOINTS (COMPLETS)
Authentification
POST /api/auth/register
Body: { username, email, password, password_confirm }
Response: { token, refresh_token, user }
POST /api/auth/login
Body: { email, password }
Response: { token, refresh_token, user }
POST /api/auth/logout
Auth: JWT token
Response: { success: true }
POST /api/auth/refresh
Body: { refresh_token }
Response: { token, refresh_token }
POST /api/auth/forgot-password
Body: { email }
Response: { message: "Email sent" }
POST /api/auth/reset-password/:token
Body: { password }
Response: { success: true }
Utilisateurs
GET /api/users/:id
Response: { user object }
GET /api/users/me
Auth: JWT token
Response: { user object (current) }
PUT /api/users/:id
Auth: JWT token
Body: { username?, bio?, avatar?, email? }
Response: { updated user }
DELETE /api/users/:id
Auth: JWT token
Response: { success: true }
GET /api/users/search?q=term
Query: q (search term)
Response: { users: [{ id, username, avatar }] }
GET /api/users/:id/profile
Response: { profile with stats }
Communautés
GET /api/communities
Query: limit, offset, sort
Response: { communities: [], total }
POST /api/communities
Auth: JWT token
Body: { name, description, icon, banner, type }
Response: { community }
GET /api/communities/:id
Response: { community with full details }
PUT /api/communities/:id
Auth: JWT token (owner/moderator)
Body: { name?, description?, rules? }
Response: { updated community }
DELETE /api/communities/:id
Auth: JWT token (owner)
Response: { success: true }
POST /api/communities/:id/join
Auth: JWT token
Response: { success: true }
POST /api/communities/:id/leave
Auth: JWT token
Response: { success: true }
GET /api/communities/:id/members
Response: { members: [] }
POST /api/communities/:id/invite
Auth: JWT token (owner/moderator)
Body: { user_id }
Response: { success: true }
POST /api/communities/:id/settings
Auth: JWT token (owner)
Body: { auto_approve?, require_email? }
Response: { updated settings }
Canaux
GET /api/communities/:id/channels
Response: { channels: [] }
POST /api/communities/:id/channels
Auth: JWT token (owner/moderator)
Body: { name, description, type }
Response: { channel }
PUT /api/channels/:id
Auth: JWT token (owner/moderator)
Body: { name?, description? }
Response: { updated channel }
DELETE /api/channels/:id
Auth: JWT token (owner/moderator)
Response: { success: true }
Messages
GET /api/channels/:id/messages
Query: limit=50, offset=0
Response: { messages: [], total }
POST /api/channels/:id/messages
Auth: JWT token
Body: { content, attachments? }
Response: { message }
PUT /api/messages/:id
Auth: JWT token (author)
Body: { content }
Response: { updated message }
DELETE /api/messages/:id
Auth: JWT token (author/moderator)
Response: { success: true }
POST /api/messages/:id/reactions
Auth: JWT token
Body: { emoji }
Response: { success: true }
DELETE /api/messages/:id/reactions/:emoji
Auth: JWT token
Response: { success: true }
POST /api/messages/:id/pin
Auth: JWT token (moderator)
Response: { success: true }
Messages Directs
GET /api/dm
Auth: JWT token
Response: { conversations: [] }
POST /api/dm
Auth: JWT token
Body: { user_id }
Response: { conversation }
GET /api/dm/:conversation_id/messages
Auth: JWT token
Query: limit=50, offset=0
Response: { messages: [] }
POST /api/dm/:conversation_id/messages
Auth: JWT token
Body: { content, attachments? }
Response: { message }
DELETE /api/dm/:conversation_id
Auth: JWT token
Response: { success: true }
Amis
GET /api/friends
Auth: JWT token
Response: { friends: [] }
POST /api/friends/request
Auth: JWT token
Body: { user_id, message? }
Response: { success: true }
GET /api/friends/requests
Auth: JWT token
Response: { requests: [] }
POST /api/friends/request/:id/accept
Auth: JWT token
Response: { success: true }
POST /api/friends/request/:id/reject
Auth: JWT token
Response: { success: true }
DELETE /api/friends/:user_id
Auth: JWT token
Response: { success: true }
POST /api/users/:user_id/block
Auth: JWT token
Response: { success: true }
DELETE /api/users/:user_id/unblock
Auth: JWT token
Response: { success: true }
Notifications
GET /api/notifications
Auth: JWT token
Query: limit=20, unread_only?
Response: { notifications: [] }
PUT /api/notifications/:id/read
Auth: JWT token
Response: { success: true }
PUT /api/notifications/read-all
Auth: JWT token
Response: { success: true }
DELETE /api/notifications/:id
Auth: JWT token
Response: { success: true }
Événements
GET /api/communities/:id/events
Query: upcoming_only?
Response: { events: [] }
POST /api/communities/:id/events
Auth: JWT token (owner/moderator)
Body: { title, description, start_date, end_date }
Response: { event }
PUT /api/events/:id
Auth: JWT token (creator)
Body: { title?, description?, start_date? }
Response: { updated event }
DELETE /api/events/:id
Auth: JWT token (creator)
Response: { success: true }
POST /api/events/:id/attend
Auth: JWT token
Body: { status: "going|maybe|not_going" }
Response: { success: true }
GET /api/events/:id/attendees
Response: { attendees: [] }
Modération
POST /api/communities/:id/moderation/warn
Auth: JWT token (moderator)
Body: { user_id, reason }
Response: { success: true }
POST /api/communities/:id/moderation/mute
Auth: JWT token (moderator)
Body: { user_id, duration }
Response: { success: true }
POST /api/communities/:id/moderation/ban
Auth: JWT token (moderator)
Body: { user_id, duration?, reason? }
Response: { success: true }
POST /api/communities/:id/moderation/kick
Auth: JWT token (moderator)
Body: { user_id }
Response: { success: true }
GET /api/communities/:id/moderation/logs
Auth: JWT token (moderator)
Response: { logs: [] }
Recherche
GET /api/search?q=term&type=users|communities|messages
Query: q, type, limit, offset
Response: { results: [] }
🔌 WEBSOCKET EVENTS (SOCKET.IO)
Connexion
// Client connects
socket.on('connect', () => {
console.log('Connected', socket.id);
});
socket.on('disconnect', () => {
console.log('Disconnected');
});
// User joins channel
socket.emit('channel:join', { channel_id: 'uuid' });
socket.on('channel:joined', { users_count: 10 });
// User leaves channel
socket.emit('channel:leave', { channel_id: 'uuid' });
Messages
// Envoyer message
socket.emit('message:send', {
channel_id: 'uuid',
content: 'Salut !',
attachments: []
});
socket.on('message:received', {
id: 'msg_uuid',
author: { username, avatar },
content: 'Salut !',
created_at: '...'
});
// Éditer message
socket.emit('message:edit', {
message_id: 'uuid',
content: 'Salut modifié !'
});
socket.on('message:edited', {
message_id: 'uuid',
content: 'Salut modifié !',
updated_at: '...'
});
// Supprimer message
socket.emit('message:delete', { message_id: 'uuid' });
socket.on('message:deleted', { message_id: 'uuid' });
// Ajouter réaction
socket.emit('message:reaction:add', {
message_id: 'uuid',
emoji: '😂'
});
socket.on('message:reaction:added', {
message_id: 'uuid',
emoji: '😂',
count: 5
});
Typing Indicator
socket.emit('typing:start', { channel_id: 'uuid' });
socket.on('typing:started', {
username: 'user123',
channel_id: 'uuid'
});
socket.emit('typing:stop', { channel_id: 'uuid' });
socket.on('typing:stopped', { username: 'user123' });
État Utilisateur
socket.emit('user:status:update', { status: 'online|away|dnd' });
socket.on('user:status:changed', {
user_id: 'uuid',
status: 'online',
username: 'user123'
});
socket.on('user:joined', {
user_id: 'uuid',
username: 'user123',
channel_id: 'uuid'
});
socket.on('user:left', {
user_id: 'uuid',
channel_id: 'uuid'
});
Messages Directs
socket.emit('dm:message:send', {
recipient_id: 'uuid',
content: 'Salut !'
});
socket.on('dm:message:received', {
sender_id: 'uuid',
sender_username: 'user123',
content: 'Salut !',
created_at: '...'
});
socket.emit('dm:typing:start', { user_id: 'uuid' });
socket.on('dm:typing:started', { username: 'user123' });
Notifications
socket.on('notification:received', {
type: 'mention|friend_request|etc',
title: 'Titre',
content: 'Contenu',
link: '/path'
});
socket.emit('notification:read', { notification_id: 'uuid' });
Événements Communauté
socket.on('community:user:joined', {
user_id: 'uuid',
username: 'user123',
community_id: 'uuid'
});
socket.on('community:user:left', {
user_id: 'uuid',
community_id: 'uuid'
});
socket.on('community:event:created', {
event_id: 'uuid',
title: 'Soirée...',
start_date: '...'
});
📝 BASE DE DONNÉES POSTGRESQL (COMPLET)
Schéma Complet SQL
-- ============================================
-- CRÉATION DE LA BASE DE DONNÉES
-- ============================================
CREATE DATABASE community_platform;
\c community_platform;
-- ============================================
-- TABLE UTILISATEURS
-- ============================================
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
username VARCHAR(255) UNIQUE NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
avatar_url TEXT,
bio TEXT,
status VARCHAR(20) DEFAULT 'offline', -- online, offline, away, dnd
last_seen TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL,
is_verified BOOLEAN DEFAULT FALSE
);
CREATE INDEX idx_users_username ON users(username);
CREATE INDEX idx_users_email ON users(email);
-- ============================================
-- TABLE COMMUNAUTÉS
-- ============================================
CREATE TABLE communities (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(255) UNIQUE NOT NULL,
slug VARCHAR(255) UNIQUE NOT NULL,
description TEXT,
icon_url TEXT,
banner_url TEXT,
type VARCHAR(20) DEFAULT 'public', -- public, private, invite_only
visibility VARCHAR(20) DEFAULT 'visible', -- visible, hidden
created_by UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
members_count INTEGER DEFAULT 1,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL
);
CREATE INDEX idx_communities_name ON communities(name);
CREATE INDEX idx_communities_slug ON communities(slug);
CREATE INDEX idx_communities_created_by ON communities(created_by);
-- ============================================
-- TABLE MEMBRES COMMUNAUTÉ
-- ============================================
CREATE TABLE community_members (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
community_id UUID NOT NULL REFERENCES communities(id) ON DELETE CASCADE,
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
role VARCHAR(20) DEFAULT 'member', -- owner, moderator, member
joined_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(community_id, user_id)
);
CREATE INDEX idx_community_members_community ON community_members(community_id);
CREATE INDEX idx_community_members_user ON community_members(user_id);
-- ============================================
-- TABLE CANAUX
-- ============================================
CREATE TABLE channels (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
community_id UUID NOT NULL REFERENCES communities(id) ON DELETE CASCADE,
name VARCHAR(255) NOT NULL,
slug VARCHAR(255),
description TEXT,
icon VARCHAR(50),
type VARCHAR(20) DEFAULT 'text', -- text, voice, announcement
visibility VARCHAR(20) DEFAULT 'public', -- public, private
is_nsfw BOOLEAN DEFAULT FALSE,
position INTEGER DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(community_id, name)
);
CREATE INDEX idx_channels_community ON channels(community_id);
-- ============================================
-- TABLE MESSAGES
-- ============================================
CREATE TABLE messages (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
channel_id UUID NOT NULL REFERENCES channels(id) ON DELETE CASCADE,
author_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
content TEXT NOT NULL,
is_edited BOOLEAN DEFAULT FALSE,
is_pinned BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL
);
CREATE INDEX idx_messages_channel ON messages(channel_id);
CREATE INDEX idx_messages_author ON messages(author_id);
CREATE INDEX idx_messages_created ON messages(created_at DESC);
-- ============================================
-- TABLE FICHIERS ATTACHÉS
-- ============================================
CREATE TABLE attachments (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
message_id UUID NOT NULL REFERENCES messages(id) ON DELETE CASCADE,
filename VARCHAR(255) NOT NULL,
url TEXT NOT NULL,
size INTEGER,
type VARCHAR(20), -- image, file, video
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_attachments_message ON attachments(message_id);
-- ============================================
-- TABLE RÉACTIONS AUX MESSAGES
-- ============================================
CREATE TABLE reactions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
message_id UUID NOT NULL REFERENCES messages(id) ON DELETE CASCADE,
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
emoji VARCHAR(10) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(message_id, user_id, emoji)
);
CREATE INDEX idx_reactions_message ON reactions(message_id);
CREATE INDEX idx_reactions_user ON reactions(user_id);
-- ============================================
-- TABLE MESSAGES DIRECTS
-- ============================================
CREATE TABLE direct_messages (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
sender_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
recipient_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
content TEXT NOT NULL,
is_read BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL
);
CREATE INDEX idx_dm_sender ON direct_messages(sender_id);
CREATE INDEX idx_dm_recipient ON direct_messages(recipient_id);
CREATE INDEX idx_dm_created ON direct_messages(created_at DESC);
-- ============================================
-- TABLE AMIS
-- ============================================
CREATE TABLE friendships (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id_1 UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
user_id_2 UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
status VARCHAR(20) DEFAULT 'pending', -- pending, accepted, rejected
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CHECK (user_id_1 < user_id_2)
);
CREATE INDEX idx_friendships_user1 ON friendships(user_id_1);
CREATE INDEX idx_friendships_user2 ON friendships(user_id_2);
-- ============================================
-- TABLE UTILISATEURS BLOQUÉS
-- ============================================
CREATE TABLE blocked_users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
blocker_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
blocked_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(blocker_id, blocked_id)
);
CREATE INDEX idx_blocked_blocker ON blocked_users(blocker_id);
-- ============================================
-- TABLE ÉVÉNEMENTS
-- ============================================
CREATE TABLE events (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
community_id UUID NOT NULL REFERENCES communities(id) ON DELETE CASCADE,
title VARCHAR(255) NOT NULL,
description TEXT,
start_date TIMESTAMP NOT NULL,
end_date TIMESTAMP,
location VARCHAR(255),
channel_id UUID REFERENCES channels(id) ON DELETE SET NULL,
created_by UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
cover_image_url TEXT,
status VARCHAR(20) DEFAULT 'scheduled', -- scheduled, ongoing, cancelled, completed
capacity INTEGER,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_events_community ON events(community_id);
CREATE INDEX idx_events_start_date ON events(start_date);
-- ============================================
-- TABLE ATTENDANCES ÉVÉNEMENTS
-- ============================================
CREATE TABLE event_attendances (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
event_id UUID NOT NULL REFERENCES events(id) ON DELETE CASCADE,
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
status VARCHAR(20) DEFAULT 'maybe', -- going, maybe, not_going
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(event_id, user_id)
);
CREATE INDEX idx_attendance_event ON event_attendances(event_id);
CREATE INDEX idx_attendance_user ON event_attendances(user_id);
-- ============================================
-- TABLE NOTIFICATIONS
-- ============================================
CREATE TABLE notifications (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
type VARCHAR(50) NOT NULL, -- message_mention, friend_request, etc
title VARCHAR(255),
content TEXT,
link VARCHAR(255),
icon_url TEXT,
is_read BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_notifications_user ON notifications(user_id);
CREATE INDEX idx_notifications_read ON notifications(user_id, is_read);
-- ============================================
-- TABLE LOGS MODÉRATION
-- ============================================
CREATE TABLE moderation_logs (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
community_id UUID NOT NULL REFERENCES communities(id) ON DELETE CASCADE,
moderator_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
action VARCHAR(50) NOT NULL, -- ban, mute, warn, delete_message, kick
target_user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
reason TEXT,
duration VARCHAR(20),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_modlogs_community ON moderation_logs(community_id);
CREATE INDEX idx_modlogs_moderator ON moderation_logs(moderator_id);
CREATE INDEX idx_modlogs_target ON moderation_logs(target_user_id);
-- ============================================
-- TABLE RÉPUTATION (Optionnel)
-- ============================================
CREATE TABLE reputation (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID UNIQUE NOT NULL REFERENCES users(id) ON DELETE CASCADE,
points INTEGER DEFAULT 0,
level VARCHAR(20) DEFAULT 'novice', -- novice, active, contributor, expert
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_reputation_user ON reputation(user_id);
-- ============================================
-- TABLE SESSIONS
-- ============================================
CREATE TABLE sessions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
token_hash VARCHAR(255) NOT NULL,
ip_address VARCHAR(45),
user_agent TEXT,
expires_at TIMESTAMP NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_sessions_user ON sessions(user_id);
CREATE INDEX idx_sessions_expires ON sessions(expires_at);
-- ============================================
-- TRIGGERS & UPDATES
-- ============================================
-- Auto-update updated_at
CREATE OR REPLACE FUNCTION update_timestamp()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = CURRENT_TIMESTAMP;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER update_users_timestamp
BEFORE UPDATE ON users
FOR EACH ROW
EXECUTE FUNCTION update_timestamp();
CREATE TRIGGER update_communities_timestamp
BEFORE UPDATE ON communities
FOR EACH ROW
EXECUTE FUNCTION update_timestamp();
CREATE TRIGGER update_messages_timestamp
BEFORE UPDATE ON messages
FOR EACH ROW
EXECUTE FUNCTION update_timestamp();
CREATE TRIGGER update_notifications_timestamp
BEFORE UPDATE ON notifications
FOR EACH ROW
EXECUTE FUNCTION update_timestamp();
-- ============================================
-- FIN DU SCHÉMA
-- ============================================
🔐 SÉCURITÉ (CHECKLIST)
| Aspect | Implémentation |
|---|---|
| Authentification | JWT tokens (7j expiration, refresh token 30j) |
| Hashage Password | Bcrypt (10+ rounds) |
| Validation Input | Sanitisation (SQL injection, XSS) |
| CORS | Configuré strictement (liste blanche domaines) |
| Rate Limiting | 100 req/min par IP pour auth, 1000 req/min pour API |
| HTTPS | Certificat SSL/TLS (Let's Encrypt) |
| Secrets | Variables d'environnement (.env) |
| SQL Injection | Prepared statements (ORM) |
| XSS | Escape HTML, Content Security Policy |
| CSRF | Tokens CSRF sur formulaires |
| DDoS | CloudFlare ou WAF |
| Logs | Audit trail complet |
| Backup | Automatisé quotidien (PostgreSQL) |
🚀 PHASES DE DÉVELOPPEMENT
Phase 1 - MVP (2-3 semaines)
Objectif : Plateforme fonctionnelle et utilisable
- ✅ Authentification (register/login)
- ✅ Profils utilisateur
- ✅ Créer/Rejoindre communautés
- ✅ Canaux texte
- ✅ Chat temps réel (WebSockets)
- ✅ Messages persistants (DB)
- ✅ Notifications basiques
- ✅ Design responsive
- ✅ Déploiement
Durée : 2-3 semaines
Phase 2 - Fonctionnalités Sociales (1-2 semaines)
- 🔲 Messages directs (DM)
- 🔲 Système d'amis (demandes, listes)
- 🔲 Réactions aux messages
- 🔲 Édition/Suppression messages
- 🔲 Recherche (utilisateurs, communautés, messages)
- 🔲 Blocage utilisateurs
- 🔲 Modération basique (delete, warn, mute)
Durée : 1-2 semaines
Phase 3 - Événements & Calendrier (1-2 semaines)
- 🔲 Création événements
- 🔲 Calendrier communauté
- 🔲 RSVP événements
- 🔲 Rappels événements
- 🔲 Système de réputation
- 🔲 Badges utilisateurs
- 🔲 Amélioration modération (ban, logs complets)
Durée : 1-2 semaines
Phase 4 - Premium & Scaling (Futur)
- 🔲 Système d'abonnement
- 🔲 Voix/Vidéo
- 🔲 Bots (API publique)
- 🔲 Plugins/Marketplace
- 🔲 Analytics détaillées
- 🔲 Mobile app (React Native)
- 🔲 Fédération (multiserver)
📋 CHECKLIST DE DÉMARRAGE
Avant de commencer le développement :
Infrastructure
- [ ] VM créée et prête (4 CPU, 8 GB RAM min)
- [ ] Linux installé (Debian/Ubuntu)
- [ ] Domaine réservé (ex: co.garabou.com)
- [ ] Email d'envoi configuré
Outils Développement
- [ ] Node.js 18+ installé
- [ ] npm/yarn installé
- [ ] PostgreSQL installé localement
- [ ] Git configuré
- [ ] IDE (VS Code recommandé)
Dépendances Initiales
- [ ] Créer package.json : npm init -y
- [ ] Installer Express : npm install express
- [ ] Installer Socket.io : npm install socket.io
- [ ] Installer PostgreSQL client : npm install pg
- [ ] Installer JWT : npm install jsonwebtoken
- [ ] Installer Bcrypt : npm install bcrypt
- [ ] Installer CORS : npm install cors
- [ ] Installer .env : npm install dotenv
Database
- [ ] PostgreSQL service running
- [ ] Database créée
- [ ] Schéma SQL exécuté
- [ ] Migrations prêtes
Configuration
- [ ] .env créé avec variables (DB, JWT_SECRET, etc.)
- [ ] .env.example créé (sans secrets)
- [ ] .gitignore configuré
Documentation
- [ ] README.md créé
- [ ] API.md documenté (endpoints)
- [ ] SETUP.md créé (guide installation)
- [ ] WebSocket.md créé (événements)
🎓 VALEUR PÉDAGOGIQUE
Tu vas apprendre:
- ✅ Backend moderne : Node.js, Express, REST API
- ✅ Communication temps réel : WebSockets, Socket.io
- ✅ Base de données : PostgreSQL, relations complexes, migrations
- ✅ Frontend moderne : React, gestion d'état
- ✅ Authentification : JWT, sessions, sécurité
- ✅ Scalabilité : Gérer 1000+ utilisateurs
- ✅ DevOps : Déploiement, HTTPS, monitoring, logs
- ✅ Programmation collaborative : Git, équipe
💰 MONÉTISATION (Futur)
📊 EXEMPLE COMPLET D'UTILISATION
1. Alice s'inscrit → Crée profil (avatar, bio)
2. Alice crée communauté "Linux Fans" (public)
3. Alice crée canaux : #general, #tech, #off-topic
4. Bob découvre la communauté → Clique "Rejoindre"
5. Bob envoie message dans #general : "Salut tout le monde !"
6. Alice répond en temps réel (WebSocket)
7. Charlie voit la convération, réagit (😂)
8. Alice add Charlie en ami (demande)
9. Charlie accepte amitié
10. Alice organise événement "Soirée Linux" (22 nov 20:00)
11. Notifications envoyées aux membres
12. Bob + Charlie confirment présence (RSVP: going)
13. Alice envoie DM à Charlie : "À samedi !"
14. Charlie voit Alice online, répond direct
15. Événement se lance, chat en direct dans #voice-événement
🎯 RÉSUMÉ FINAL
| Aspect | Détail |
|---|---|
| Type | Plateforme communautaire complète (Discord-like) |
| Complexité | Moyenne-Élevée (projet ambitieux mais réaliste) |
| Durée estimée (Phase 1) | 2-3 semaines temps plein |
| Équipe recommandée | 1-2 développeurs (tu peux le faire seul) |
| Scalabilité | 100-1000+ utilisateurs simultanés |
| Stack recommandé | Node.js + Express + React + PostgreSQL + Socket.io |
| Portfolio value | ⭐⭐⭐⭐⭐ (très impressionnant) |
| Potentiel monétaire | Haut (abonnements + API) |
PRÊT À COMMENCER ? 🚀
Quand tu seras prêt(e) à coder ce projet :
- Copie ce cahier des charges entièrement
- Envoie-le moi sur cette conversation
- Je vais directement comprendre de quoi tu parles
- On lance Claude Code et on code ensemble
- Je t'explique chaque étape en détail
Bonne chance avec le portfolio en ce moment ! 💪