Vue d'ensemble
Backend API Django REST pour la plateforme média panafricaine GAM
User Stories Implémentées
| US | Description | Statut |
|---|---|---|
US-01 | Gestion des taxonomies (Auteurs & Catégories) | Fait |
US-02 | Rédaction d'article riche (blocs dynamiques StreamField) | Fait |
US-03 | Gestion des vidéos Web TV (YouTube) | Fait |
US-04 | Workflow de publication (Draft → Published) | Fait |
US-05 | Page d'accueil dynamique | Fait |
US-06 | Lecture d'article (vues, articles liés) | Fait |
US-07 | Consultation Web TV | Fait |
US-08 | Recherche de contenu | Fait |
US-10 | Inscription à la newsletter | Fait |
US-11 | SEO (meta title, meta description) | Fait |
Architecture
Organisation modulaire avec séparation claire Core / Métier
Apps Core
- core — Modèles de base (TimeStamped, Slugged, Publishable, SEO, Ordered), permissions, utilitaires, validators, throttles, storage Supabase
- users — Modèle User custom (email-based), rôles (Admin, Chef Rédacteur, Rédacteur, Lecteur), JWT + Session auth
Apps Métier
- editorial — Articles avec StreamField, Vidéos YouTube, Catégories hiérarchiques, Auteurs
- engagement — Newsletter (Brevo/Mailchimp), Messages de contact, Notifications
- search — Recherche globale, Suggestions, Tags populaires
- kpi — KPI plateforme (articles, vidéos, lecteurs, pays couverts)
- advertising — Publicités (placement, planification, tracking impressions/clics, CTR)
Modèles de données
Schéma complet des modèles Django avec leurs champs et relations
Modèles Abstraits (Core)
TimeStampedModel
abstractSluggedModel
abstractPublishableModel
abstractSEOModel
abstractOrderedModel
abstractUsers
User
AbstractUser + TimeStampedEditorial
Article
TimeStamped + Slugged + Publishable + SEOArticleBlock
TimeStampedVideo
TimeStamped + Slugged + Publishable + SEOCategory
TimeStamped + Slugged + OrderedAuthor
TimeStamped + SluggedEngagement
NewsletterSubscription
TimeStampedContactMessage
TimeStampedArticleNotification
TimeStampedKPI & Advertising
PlatformKPI
singletonAdvertisement
TimeStampedCore — Réseaux Sociaux
SocialNetwork
TimeStampedEndpoints API
Tous les endpoints REST sous /api/v1/
Auth — /api/v1/auth/
/api/v1/auth/login/Connexion — retourne JWT + infos user/api/v1/auth/refresh/Rafraîchir le access token/api/v1/auth/register/Inscription nouvel utilisateur/api/v1/auth/logout/Déconnexion (blacklist token)/api/v1/auth/profile/Profil utilisateur connecté/api/v1/auth/profile/Modifier son profil/api/v1/auth/password/change/Changer son mot de passe/api/v1/auth/admin/users/Liste utilisateurs (admin)/api/v1/auth/admin/users/{id}/activate/Activer un utilisateur/api/v1/auth/admin/users/{id}/deactivate/Désactiver un utilisateur/api/v1/auth/admin/users/{id}/change_role/Changer le rôle Editorial — /api/v1/editorial/
/api/v1/editorial/articles/Liste paginée des articles/api/v1/editorial/articles/{slug}/Détail article (incrémente vues)/api/v1/editorial/articles/Créer un article/api/v1/editorial/articles/featured/Articles à la Une (US-05)/api/v1/editorial/articles/trending/Articles tendance/api/v1/editorial/articles/recent/Articles récents/api/v1/editorial/articles/{slug}/publish/Publier (US-04, permission CanPublish)/api/v1/editorial/articles/{slug}/unpublish/Dépublier/api/v1/editorial/videos/Liste paginée des vidéos/api/v1/editorial/videos/{slug}/Détail vidéo/api/v1/editorial/videos/featured/Vidéos en vedette/api/v1/editorial/videos/live/Vidéos en direct/api/v1/editorial/videos/by_type/?type=Vidéos par type (US-07)/api/v1/editorial/categories/Liste catégories (racines, cache 10min)/api/v1/editorial/categories/{slug}/Détail catégorie + enfants/api/v1/editorial/categories/{slug}/articles/Articles d'une catégorie/api/v1/editorial/categories/{slug}/videos/Vidéos d'une catégorie/api/v1/editorial/categories/featured/Catégories en vedette/api/v1/editorial/authors/Liste auteurs actifs/api/v1/editorial/authors/{slug}/Détail auteur/api/v1/editorial/authors/{slug}/articles/Articles d'un auteur/api/v1/editorial/homepage/Données page d'accueil (cache 5min) Search — /api/v1/search/
/api/v1/search/?q=queryRecherche articles + vidéos/api/v1/search/global/?q=queryRecherche globale paginée/api/v1/search/suggestions/?q=querySuggestions auto-complete/api/v1/search/trending-tags/Tags populaires Engagement — /api/v1/engagement/
/api/v1/engagement/newsletter/subscribe/Inscription newsletter/api/v1/engagement/newsletter/unsubscribe/Désabonnement newsletter/api/v1/engagement/contact/Envoyer message de contact/api/v1/engagement/admin/newsletter/Admin — Liste abonnés/api/v1/engagement/admin/contacts/Admin — Messages de contact KPI — /api/v1/kpi/
/api/v1/kpi/platform/KPIs plateforme (articles, vidéos, pays...) Advertising — /api/v1/advertising/
/api/v1/advertising/active/Publicités actives (par position)/api/v1/advertising/track/Tracker impression/clic/api/v1/advertising/admin/Admin — CRUD publicités (staff only) Core — /api/v1/core/
/api/v1/core/social-networks/Réseaux sociaux du siteDocumentation API
/api/schema/Schéma OpenAPI (JSON)/api/docs/Swagger UI interactif/api/redoc/ReDoc documentationAuthentification & Rôles
JWT + Session hybride avec système de rôles hiérarchique
JWT (API)
POST /api/v1/auth/login/
{
"email": "user@example.com",
"password": "***"
}
→ Response:
{
"access": "eyJ...", // 60 min
"refresh": "eyJ...", // 7 jours
"user": { ... }
}
// Utilisation
Authorization: Bearer <access_token>
Session (Wagtail CMS)
// Login JWT crée aussi une session Django // → Accès automatique au CMS Wagtail POST /api/v1/auth/session/login/ → Redirige vers /cms/ GET /api/v1/auth/session/logout/ → Détruit la session
Hiérarchie des rôles
Permissions custom
| Permission | Description | Rôles |
|---|---|---|
IsEditorOrReadOnly | Écriture réservée aux rédacteurs+ | Editor, Chief Editor, Admin |
CanPublish | Publier / dépublier du contenu | Chief Editor, Admin |
IsAdminUser | Gestion des utilisateurs | Admin uniquement |
Rate Limiting
| Scope | Limite | Type |
|---|---|---|
| Anonyme | 2 000 / heure | Lecture (GET safe) — écriture limitée par IP |
| Authentifié | 5 000 / heure | Toutes requêtes |
| Newsletter | 10 / heure | Inscription newsletter |
| Contact | 5 / heure | Messages de contact |
Stack Technique
Technologies et dépendances du backend
Django 5.x
Framework web Python
Django REST Framework
API REST avec ViewSets, Serializers, Filters
Wagtail CMS
CMS headless avec StreamField pour les articles
SimpleJWT
Authentification JWT + blacklist + session hybride
PostgreSQL
Base de données relationnelle
Supabase Storage
Stockage média S3-compatible
Brevo / Mailchimp
Fournisseur newsletter
Cloudflare Tunnel
Exposition sécurisée via Workers
drf-spectacular
Documentation OpenAPI / Swagger / ReDoc
django-filter
Filtres avancés sur les endpoints
Docker
Conteneurisation avec Dockerfile + entrypoint
WhiteNoise
Serveur de fichiers statiques
Configuration clé
Settings
LANGUAGE_CODE = 'fr-fr' TIME_ZONE = 'Africa/Douala' PAGE_SIZE = 12 # JWT ACCESS_TOKEN_LIFETIME = 60 min REFRESH_TOKEN_LIFETIME = 7 jours ROTATE_REFRESH_TOKENS = True # Cache Homepage = 5 min Categories = 10 min # Lecture READING_SPEED = 200 mots/min
Middleware Stack
1. SecurityMiddleware 2. WhiteNoiseMiddleware 3. CorsMiddleware 4. SessionMiddleware 5. CommonMiddleware 6. CsrfViewMiddleware 7. AuthenticationMiddleware 8. MessageMiddleware 9. XFrameOptionsMiddleware 10. Wagtail RedirectMiddleware
Structure du Projet
Organisation des fichiers et dossiers
GAM-backend/ ├── config/ │ ├── settings/ │ │ ├── base.py # Settings communs (JWT, DRF, Wagtail, CORS...) │ │ ├── development.py # Debug, SQLite fallback │ │ └── production.py # Sécurité, Supabase, Gunicorn │ ├── urls.py # Routes principales + Swagger │ ├── wsgi.py │ └── asgi.py ├── apps/ │ ├── core/ # Modèles abstraits, permissions, utilitaires │ │ ├── models.py # TimeStamped, Slugged, Publishable, SEO, Ordered, SocialNetwork │ │ ├── permissions.py # IsEditorOrReadOnly, CanPublish │ │ ├── validators.py # validate_youtube_url, validate_hex_color │ │ ├── utils.py # extract_youtube_id, get_youtube_embed_url │ │ ├── throttles.py # ReadSafeAnonRateThrottle │ │ ├── storage.py # GAMBaseStorage (Supabase S3) │ │ ├── mixins.py # MultiSerializerViewSetMixin │ │ └── constants.py # AFRICAN_COUNTRIES │ ├── users/ # Authentification & Utilisateurs │ │ ├── models.py # User (email-based, 4 rôles) │ │ ├── views.py # Login, Register, Logout, Profile, Admin │ │ ├── serializers.py # JWT, User CRUD, Admin │ │ └── urls.py │ ├── editorial/ # Contenu éditorial │ │ ├── models/ │ │ │ ├── article.py # Article + ArticleBlock (StreamField) │ │ │ ├── video.py # Video (YouTube) │ │ │ ├── category.py # Category (hiérarchique, couleur) │ │ │ └── author.py # Author (bio, réseaux sociaux) │ │ ├── views.py # 4 ViewSets + HomepageView │ │ ├── serializers.py # List/Detail/Create/Admin serializers │ │ ├── filters.py # ArticleFilter, VideoFilter │ │ ├── blocks.py # ArticleStreamBlock (Wagtail) │ │ └── signals.py # Auto-calcul reading_time │ ├── engagement/ # Newsletter & Contact │ │ ├── models.py # Newsletter, ContactMessage, Notifications │ │ ├── services.py # Brevo/Mailchimp integration │ │ ├── views.py │ │ └── urls.py │ ├── search/ # Recherche │ │ ├── services.py # Logique de recherche │ │ ├── views.py # Search, Suggestions, Trending │ │ └── urls.py │ ├── kpi/ # Indicateurs de performance │ │ ├── models.py # PlatformKPI (singleton) │ │ └── views.py │ └── advertising/ # Publicités │ ├── models.py # Advertisement (6 types, 8 positions) │ ├── views.py # Active ads, Track, Admin CRUD │ └── urls.py ├── requirements/ │ ├── base.txt │ ├── development.txt │ └── production.txt ├── scripts/ # Scripts utilitaires ├── Dockerfile ├── docker-entrypoint.sh └── manage.py