Skip to content

#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 RGZ

Stack

  • 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 + HTTPS

Modèle Revendeur (DB)

python
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

env
# recensement/.env
FLASK_SECRET_KEY=changeme_production_key
ADMIN_PASSWORD=admin_password_securise
FLASK_ENV=production
DATABASE_URI=sqlite:///recensement.db

Endpoints

MéthodeRouteDescriptionAuth
GET/Formulaire public inscriptionNon
POST/submitSoumettre candidatureNon
GET/adminListe candidats + statsAdmin
POST/admin/validate/{id}Valider candidatureAdmin
POST/admin/reject/{id}Rejeter candidatureAdmin
GET/admin/export.csvExport CSV completAdmin
GET/healthHealth check nginxNon

Commandes de Gestion

bash
# 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 --quiet

URLs et Accès

ServiceURLCredentials
Formulaire publichttps://registre-rgz.duckdns.org
Panel adminhttps://registre-rgz.duckdns.org/adminVariable ADMIN_PASSWORD
Health checkhttps://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 :

python
# 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é

AspectImplémentation
HTTPSLet's Encrypt auto-renew
Admin authMot de passe ADMIN_PASSWORD (basique, usage interne uniquement)
SQLiteFichier protégé dans container (pas d'accès externe)
DonnéesPas de données bancaires stockées
BackupManuel via scripts/ops/backup.sh

Dernière mise à jour: 2026-02-21

PROJET MOSAÏQUE — 81 outils, 22 conteneurs, 500+ revendeurs WiFi Zone