Website_Template/README.md
Louis Mazin 663268bbe9 nice
2026-10-15 14:52:54 +02:00

211 lines
9.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Template Django + React + MySQL
Un squelette réutilisable inspiré de l'organisation de GoodDrive, **sans ses fonctionnalités** :
Django REST Framework, React/Vite, Tailwind 4, composants shadcn/ui, Oxlint, MySQL 8 et Docker Compose.
## Démarrage rapide
1. Compléter les secrets du `.env` (ou les générer avec `python scripts/init_env.py`).
2. Modifier si nécessaire `FRONTEND_PORT`, `BACKEND_PORT`, `ALLOWED_HOSTS` et les origines autorisées.
3. Démarrer avec le script principal :
```sh
chmod +x start.sh
./start.sh
```
`start.sh` initialise le `.env`, puis détecte Docker Compose. Si Docker est disponible,
il construit et démarre les trois services. Sinon, il lance **Django et React dans le même
environnement** (mode Pterodactyl, avec une base MySQL externe déjà accessible).
Tu peux choisir explicitement :
```sh
./start.sh --compose # Docker Compose
./start.sh --standalone # Un seul environnement, sans Docker
```
En mode standalone, Python 3, Node.js/npm et les bibliothèques nécessaires à `mysqlclient`
doivent être disponibles. Le script installe les dépendances Python manquantes, installe
les dépendances React et compile le frontend avant de lancer les deux serveurs.
La variable `MYSQL_HOST=db` du modèle fonctionne **uniquement en mode Compose** :
en mode standalone, indique l'adresse réelle de ton serveur MySQL dans `.env`.
Le mode standalone utilise `vite preview` pour servir le build et le proxy API ; pour
un site public à forte charge, préfère le mode Docker Compose avec Nginx.
Le script ne télécharge ni n'écrase automatiquement le dépôt Git.
- **Frontend** : http://localhost:1028 (ou `FRONTEND_PORT`)
- **Backend** : http://localhost:1029/api/health/ (ou `BACKEND_PORT`)
- **Administration React (shadcn/ui)** : http://localhost:1028/admin/
- **Admin Django technique** : http://localhost:1028/django-admin/
Au premier lancement, `ensure_admin` crée le compte à partir de `ADMIN_*`. Si le compte existe déjà, il **ne change pas son mot de passe** à chaque redémarrage.
**Attention :** ne versionne jamais `.env`, et remplace les noms/mots de passe par des valeurs propres à chaque projet. `DEBUG=True` ne doit pas être utilisé en production.
## Structure
```text
.
├── .env # paramètres locaux, non versionné
├── .env.example # modèle sans secrets
├── docker-compose.yml
├── start.sh # Démarrage Compose ou standalone / Pterodactyl
├── scripts/
│ └── init_env.py
├── backend/
│ ├── Dockerfile
│ ├── entrypoint.sh
│ ├── requirements.txt
│ ├── manage.py
│ ├── core/
│ │ ├── settings.py
│ │ ├── origins.py
│ │ └── urls.py
│ └── common/
│ ├── urls.py
│ ├── views.py
│ ├── admin_api.py # API sécurisée pour le tableau de bord React
│ └── management/commands/ensure_admin.py
└── frontend/
├── Dockerfile
├── nginx.conf
├── package.json
├── .oxlintrc.json # Oxlint : JS/JSX, React et accessibilité
├── components.json
├── vite.config.js
└── src/
├── App.jsx # sélection des pages
├── index.css
├── pages/ # HomePage, AdminPage
├── hooks/ # logique React et états réutilisables
├── services/ # appels HTTP centralisés, AUCUN fetch dans JSX
│ ├── apiClient.js
│ ├── healthService.js
│ ├── authService.js
│ └── adminService.js
└── components/
├── admin/ # widgets de la page d'administration
├── layout/ # composants partagés
└── ui/ # composants shadcn/ui
```
## Origines CORS/CSRF et ports automatiques
`backend/core/settings.py` transforme les origines du `.env` automatiquement.
```ini
FRONTEND_PORT=1028
BACKEND_PORT=1029
CORS_ALLOWED_ORIGINS=http://localhost,http://127.0.0.1
CSRF_TRUSTED_ORIGINS=http://localhost,http://127.0.0.1
```
Valeurs effectives :
```python
CORS_ALLOWED_ORIGINS = ["http://localhost:1028", "http://127.0.0.1:1028"]
CSRF_TRUSTED_ORIGINS = [
"http://localhost:1029", "http://127.0.0.1:1029", # backend
"http://localhost:1028", "http://127.0.0.1:1028", # frontend
]
```
Les origines comportant **déjà un port explicite** sont conservées telles quelles :
`http://localhost:3000` reste `http://localhost:3000`.
Pour un reverse proxy HTTPS avec ports standards 443, mets `AUTO_PORT_CORS=False` et
`AUTO_PORT_CSRF=False`, puis indique tes origines complètes dans les deux variables.
Cela évite d'ajouter `:1028` à `https://mon-domaine.fr`.
**Pourquoi le frontend figure également dans CSRF ?** Django en a besoin pour
les formulaires avec cookie/session provenant de l'interface. Cela complète
la règle demandée « port backend pour CSRF, port frontend pour CORS ».
Dans ce template, le frontend utilise `/api/` sur le **même domaine** grâce au proxy Nginx :
CORS n'est normalement pas nécessaire pour la communication interne, mais reste
configuré si une autre application appelle directement l'API exposée sur le port backend.
## Architecture Docker
- `db` : MySQL 8.4 avec volume `db_data` (non exposé sur le réseau hôte).
- `backend` : Django + Gunicorn sur le port interne 8000, publié sur `BACKEND_PORT`.
- `frontend` : React compilé puis servi par Nginx sur le port interne 80, publié sur `FRONTEND_PORT`.
- Nginx relaie `/api/`, `/django-admin/` et `/static/` vers Django. `/admin/` est une page React.
Le port `MYSQL_PORT` est **le port de MySQL dans le réseau des conteneurs** (3306 avec le service `db`). Pour une base distante, adapte `MYSQL_HOST` et `MYSQL_PORT`. Le service `db` reste créé par Compose dans cette version du template.
## Ajouter tes fonctionnalités
- Django : nouvelle application via `python manage.py startapp monapp` ; l'ajouter dans `INSTALLED_APPS` et ses URL dans `core/urls.py`.
- React : nouvelles pages dans `frontend/src/pages/`, hooks dans `hooks/` et appels à l’API dans `services/`. Ne pas appeler `fetch` dans les composants JSX.
- shadcn/ui : le fichier `components.json` est présent. Ajouter les composants via la CLI shadcn (`npx shadcn@latest add dialog`, par exemple). Le template inclut Button, Card, Input, Label, Table, Badge, Dialog, Separator et Alert.
- Variables supplémentaires : les ajouter au `.env.example` et les lire via `decouple.config` côté Django.
## Qualité du code avec Oxlint
Oxlint est inclus dans les dépendances de développement du frontend. Il contrôle le JavaScript/JSX, les règles React, les erreurs fréquentes et certaines règles d’accessibilité. Il ne remplace pas un formateur de code.
```sh
cd frontend
npm install
npm run lint # Contrôle sans modifier les fichiers
npm run lint:fix # Applique les corrections automatiques sûres disponibles
```
La configuration se trouve dans `frontend/.oxlintrc.json`. Les dossiers `dist` et `coverage` sont ignorés. Oxlint est volontairement **indépendant du démarrage** : `start.sh` ne bloque pas le lancement du site sur un avertissement de lint.
## Vérifier et exploiter
```sh
# Logs
docker compose logs -f backend
docker compose logs -f frontend
# Voir les origines effectives (ne pas afficher le SECRET_KEY)
docker compose exec backend python manage.py shell -c "from django.conf import settings; print(settings.CORS_ALLOWED_ORIGINS, settings.CSRF_TRUSTED_ORIGINS)"
# Tests unitaires des origines (sans Django)
cd backend && python -m unittest discover -s tests
# Avec une base Django de test :
python manage.py test common
# Stopper sans détruire MySQL
docker compose down
```
**Ne pas utiliser `docker compose down -v`** : cela supprime le volume de la base.
## Notes de sécurité
- `SECRET_KEY`, `MYSQL_PASSWORD`, `MYSQL_ROOT_PASSWORD` et `ADMIN_PASSWORD` sont générés localement par le script, sans être publiés dans le ZIP.
- Les identifiants MySQL ne sont pas intégrés dans les images Docker.
- La route de diagnostic `/api/health/` est volontairement publique ; les futures routes API sont protégées par défaut dans DRF.
- Sur Internet, configure HTTPS, `ALLOWED_HOSTS`, origines, cookies sécurisés et reverse proxy avant mise en ligne.
- En production, évite d'exposer directement le port backend si les appels passent seulement par Nginx.
## Tableau de bord administrateur (shadcn/ui)
- `/admin/` : interface React avec connexion par session Django, thème clair/sombre,
statistiques, recherche, création de comptes et activation/désactivation.
- `/django-admin/` : administration Django native conservée pour la gestion avancée.
- Seuls les comptes `is_staff` accèdent au tableau de bord. Pour **créer ou désactiver**
des comptes, il faut en plus être **superutilisateur**. Le compte connecté et les
autres superutilisateurs sont protégés contre la désactivation.
- L'API se trouve dans `backend/common/admin_api.py`. La session Django et les jetons
CSRF protègent les actions, **les secrets ne sont jamais stockés dans le frontend**.
- Le frontend parle au backend par un chemin relatif `/api/`, proxifié en Compose
comme en standalone. `frontend/src/services/apiClient.js` centralise les erreurs,
cookies et en-têtes CSRF.
- L'interface ne remplace pas les permissions fines de Django Admin pour les modèles
que tu ajouteras : la page React sert de base claire et extensible.
## Validation
Le template inclut les tests `backend/common/tests.py` pour l'authentification,
les autorisations administrateur et la CSRF. Pour les lancer, une base Django de test
accessible est requise : `python manage.py test common`.