Passer au contenu principal

💬 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

InformationDétail
CréateurGarabou (Étudiant Bachelor Réseau Informatique)
EntrepriseNicomatic (alternance)
Type de plateformeCommunauté généraliste multi-thèmes
Utilisateurs ciblesN'importe qui (amis, communautés d'intérêts, groupes)
Modèle économiqueGratuit de base → Abonnement premium (Phase futur)
Valeur pédagogiqueBackend moderne, WebSockets, BD complexe, scalabilité

🏗️ ARCHITECTURE TECHNIQUE COMPLÈTE

INFRASTRUCTURE D'HÉBERGEMENT

ÉlémentDétail
Type VMÀ définir (nouvelle VM OU VM 105 Nextcloud)
Système d'exploitationLinux (Debian/Ubuntu/Arch)
Ressources recommandéesMin 4 CPU, 8 GB RAM, 100 GB disque
Adresse IPÀ définir (ex: 192.168.0.xxx)
Domaine futurco.garabou.com OU community.garabou.com
Port en développement3000 (Node.js recommandé) ou 8000
Port en production80 (HTTP) / 443 (HTTPS avec reverse proxy)
Reverse proxyNginx (pour gérer HTTPS, routing)

STACK TECHNIQUE RECOMMANDÉE

Backend

ComposantOption A (Recommandé)Option B (Alternative)
LangageNode.js 18+Python 3.10+
FrameworkExpress.jsFastAPI ou Django
AvantagesMeilleur pour WebSockets, plus rapidePlus simple à maintenir long terme
WebSocketsSocket.io (facile)FastAPI WebSockets (native)
Performance⭐⭐⭐⭐⭐

Choix final recommandé : Node.js + Express + Socket.io

Frontend

ÉlémentRecommandé
FrameworkReact 18+ OU Vue.js 3+
Alternative simpleHTML5 + CSS3 + JavaScript Vanilla
Gestion d'étatRedux (React) OU Vuex (Vue)
HTTP ClientAxios OU Fetch API
ResponsiveMobile-first design
CSS FrameworkTailwind CSS OU Bootstrap OU custom

Base de Données

AspectDétail
Système principalPostgreSQL 14+ (robuste, scalable)
AlternativeMongoDB (plus flexible mais moins relationnel)
Connexionpg (Node.js) OU Sequelize (ORM)
MigrationsFlyway OU Alembic
BackupAutomatisé (pg_dump, logs WAL)

Communication Temps Réel

ÉlémentDétail
WebSocketsSocket.io (Node.js + Express)
AlternativeNative WebSockets avec fallback polling
NamespaceSéparation par communauté, DM, notifications
Événementsmessage:send, typing:start, user:status, etc.
Scaling futurRedis pour partager état entre serveurs

Stockage Fichiers

TypeDétail
Avatars/ImagesDossier /uploads/ local OU S3-compatible
Fichiers partagésLimiter à 10-50 MB par fichier
OptimisationCompresser images, générer thumbnails

Sécurité

AspectImplémentation
AuthentificationJWT (JSON Web Tokens)
Mot de passeBcrypt (hash) + salt
HTTPSCertificat Let's Encrypt (gratuit)
CORSConfiguré strictement
Rate limiting100 req/min par IP
Validation inputSanitisation (SQL injection, XSS)
SecretsVariables 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

TypeDescriptionQui peut voir ?Qui peut rejoindre ?
PublicVisible partoutTout le mondeDemande directe
PrivatePas visibleSeulement membresInvitation du propriétaire
Invite-onlyCachéeSeulement membresInvitation 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

AspectSpécification
Thème principalSombre (Dark mode par défaut)
Couleur fond#1a1a1a (très sombre)
Couleur texte#f0f0f0 (blanc cassé)
Accents primairesBleu #0066ff
Accents secondairesViolet #8B00FF, Rose #FF006E
Statuts en ligneVert #00cc00 (online), Gris #666 (offline), Orange #ffaa00 (away)
ErreursRouge #ff3333
SuccèsVert #00cc00
PolicesInter / Poppins / Roboto (sans-serif moderne)
Responsive breakpointsDesktop (1200px+), Tablet (768-1199px), Mobile (< 768px)
AnimationsSmooth 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)

AspectImplémentation
AuthentificationJWT tokens (7j expiration, refresh token 30j)
Hashage PasswordBcrypt (10+ rounds)
Validation InputSanitisation (SQL injection, XSS)
CORSConfiguré strictement (liste blanche domaines)
Rate Limiting100 req/min par IP pour auth, 1000 req/min pour API
HTTPSCertificat SSL/TLS (Let's Encrypt)
SecretsVariables d'environnement (.env)
SQL InjectionPrepared statements (ORM)
XSSEscape HTML, Content Security Policy
CSRFTokens CSRF sur formulaires
DDoSCloudFlare ou WAF
LogsAudit trail complet
BackupAutomatisé 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)

  • 🔲 Premium membership : 5-10€/mois pour features
  • 🔲 Communautés premium : Modérateurs payent pour features
  • 🔲 Sponsorship : Marques sur communautés
  • 🔲 API payante : Bots/Intégrations
  • 🔲 Publicités ciblées (optionnel)

📊 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

AspectDétail
TypePlateforme 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ée1-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étaireHaut (abonnements + API)

PRÊT À COMMENCER ? 🚀

Quand tu seras prêt(e) à coder ce projet :

  1. Copie ce cahier des charges entièrement
  2. Envoie-le moi sur cette conversation
  3. Je vais directement comprendre de quoi tu parles
  4. On lance Claude Code et on code ensemble
  5. Je t'explique chaque étape en détail

Bonne chance avec le portfolio en ce moment ! 💪