#81 — site-recensement
EN PRODUCTION
Priorité: 🟡 EN PRODUCTION · Type: TYPE H · Conteneur: recensement/ (déployé séparément)
Dépendances: Aucune
URL Production : https://registre-rgz.duckdns.org
Description
Premier outil du projet RGZ, le seul actuellement en production. Site web de recensement permettant aux ~500 revendeurs WiFi Zone illégaux du Bénin de s'inscrire en vue de leur légalisation sous la marque ACCESS ("Powered by RGZ").
Développé en Python Flask avec une interface simple et efficace. Les revendeurs remplissent un formulaire en ligne (nom, localisation, nombre d'abonnés, équipements), l'équipe RGZ valide les candidatures via un panel admin, et peut exporter les données en CSV pour traitement.
Déployé sur registre-rgz.duckdns.org avec HTTPS Let's Encrypt, indépendamment de la stack principale RGZ (son propre docker-compose.yml).
Architecture Interne
Revendeur → https://registre-rgz.duckdns.org (HTTPS)
↓
nginx (reverse proxy) → Flask app (port 5000)
↓
Formulaire HTML → Validation → SQLite DB
↓
Admin panel (/admin) → Liste candidats → Validation/Rejet
↓
Export /admin/export.csv → Traitement équipe RGZStack
- Backend : Python Flask 3.x
- DB : SQLite (simple, pas de dépendance externe)
- Frontend : HTML/CSS Bootstrap 5 (léger, mobile-friendly)
- Reverse proxy : nginx
- HTTPS : Let's Encrypt via certbot
- Déploiement : Docker Compose indépendant (
recensement/docker-compose.yml)
Structure fichiers
recensement/
├── docker-compose.yml # Stack indépendante
├── app/
│ ├── app.py # Application Flask principale
│ ├── models.py # SQLAlchemy models (Revendeur)
│ ├── templates/
│ │ ├── index.html # Formulaire public
│ │ └── admin.html # Panel administration
│ └── static/ # CSS, images, logo ACCESS
└── nginx/
└── nginx.conf # Reverse proxy + HTTPSModèle Revendeur (DB)
class Revendeur(db.Model):
id = Column(Integer, primary_key=True)
nom = Column(String, nullable=False)
prenom = Column(String, nullable=False)
telephone = Column(String, nullable=False)
ville = Column(String, nullable=False)
quartier = Column(String)
nb_abonnes = Column(Integer) # Estimation abonnés actuels
equipements = Column(String) # Type CPE, routeurs...
statut = Column(String, default='candidat') # candidat|validé|rejeté
created_at = Column(DateTime, default=datetime.utcnow)
notes_admin = Column(Text)Configuration
# recensement/.env
FLASK_SECRET_KEY=changeme_production_key
ADMIN_PASSWORD=admin_password_securise
FLASK_ENV=production
DATABASE_URI=sqlite:///recensement.dbEndpoints
| Méthode | Route | Description | Auth |
|---|---|---|---|
| GET | / | Formulaire public inscription | Non |
| POST | /submit | Soumettre candidature | Non |
| GET | /admin | Liste candidats + stats | Admin |
| POST | /admin/validate/{id} | Valider candidature | Admin |
| POST | /admin/reject/{id} | Rejeter candidature | Admin |
| GET | /admin/export.csv | Export CSV complet | Admin |
| GET | /health | Health check nginx | Non |
Commandes de Gestion
# Status de la stack
cd /home/claude-dev/RGZ/recensement
docker compose ps
# Logs
docker compose logs -f
# Démarrage
docker compose up -d
# Arrêt
docker compose down
# Backup DB SQLite
docker exec recensement-app cp /app/recensement.db /backups/recensement_$(date +%Y%m%d).db
# Voir les candidats récents
docker exec recensement-app sqlite3 /app/recensement.db \
"SELECT id, nom, ville, nb_abonnes, statut, created_at
FROM revendeur ORDER BY created_at DESC LIMIT 20;"
# Compter par statut
docker exec recensement-app sqlite3 /app/recensement.db \
"SELECT statut, COUNT(*) FROM revendeur GROUP BY statut;"
# Exporter CSV manuellement
curl -u admin:$ADMIN_PASSWORD \
https://registre-rgz.duckdns.org/admin/export.csv \
-o revendeurs_$(date +%Y%m%d).csv
# Renouveler le certificat SSL
docker exec recensement-certbot certbot renew --quietURLs et Accès
| Service | URL | Credentials |
|---|---|---|
| Formulaire public | https://registre-rgz.duckdns.org | — |
| Panel admin | https://registre-rgz.duckdns.org/admin | Variable ADMIN_PASSWORD |
| Health check | https://registre-rgz.duckdns.org/health | — |
Migration vers Stack Principale (future)
Lors du déploiement complet de la stack RGZ, les données du site recensement seront migrées :
# Migration: SQLite recensement → PostgreSQL rgz-db
# Script: scripts/ops/migrate_recensement.py
# Mapping champs:
# revendeur.nom + prenom → resellers.contact_name
# revendeur.telephone → resellers.phone
# revendeur.ville → resellers.city
# revendeur.statut='validé' → resellers.status='candidate' (début onboarding #56)Sécurité
| Aspect | Implémentation |
|---|---|
| HTTPS | Let's Encrypt auto-renew |
| Admin auth | Mot de passe ADMIN_PASSWORD (basique, usage interne uniquement) |
| SQLite | Fichier protégé dans container (pas d'accès externe) |
| Données | Pas de données bancaires stockées |
| Backup | Manuel via scripts/ops/backup.sh |
Dernière mise à jour: 2026-02-21