📩 Boxanet - Documentation Technique

🎯 Projet: Boxanet - Plateforme de gestion de self-stockage
🏱 Entreprise: GeoCodeTout pour la SAS Boxarium Toulouse Nord
đŸ‘šâ€đŸ’» DĂ©veloppeur: GeoCodeTout - FrĂ©dĂ©ric Nauleau
🚀 Version: 2.7.0 (2026-02-02)

Vue d'ensemble

Boxanet est la solution numérique complÚte développée par GeoCodeTout pour gérer les activités quotidiennes des centres de self-stockage Boxarium. La plateforme centralise tous les aspects de l'exploitation :

  • Gestion des espaces : Suivi en temps rĂ©el de l'occupation des boxes, plans interactifs, zonage et tarification
  • Relation client : De la premiĂšre demande jusqu'au contrat de location, en passant par les visites et devis
  • Assistant virtuel BoxAI : RĂ©ponses automatiques 24h/24 aux prospects via WhatsApp et le site web
  • ContrĂŽle d'accĂšs intelligent : Ouverture des portails Ă  distance pour les clients et gestion des permissions
  • OpĂ©rateur Boxanet : Serveur d'automatisation qui publie vos annonces 24h/24 sur les sites cibles (Jestocke, OuiStock, Costockage) sans intervention manuelle
  • Administration multi-sites : Tableau de bord unifiĂ© pour piloter plusieurs centres depuis une seule interface

Stack Technique

đŸ–„ïž Backend

  • PHP 8.2+ (strict types)
  • MySQL 8.0
  • Pattern MVC custom
  • PDO (prepared statements)

🎹 Frontend

  • HTML5 / CSS3
  • JavaScript vanilla
  • AJAX dynamique
  • Responsive design

đŸ€– IA & Services

  • Mammouth.AI (OpenAI-compatible)
  • Twilio (SMS/WhatsApp)
  • EMQX (broker MQTT)
  • PHPMailer

🚀 Automation

  • Node.js 20 (Operator)
  • Puppeteer + Chromium
  • Express.js
  • Rocky Linux 8

Architecture Globale

Internet
    │
    ├──▶ www.boxanet.com (OVH MutualisĂ©)
    │    ├─ Dashboard utilisateurs
    │    ├─ API REST (JSON)
    │    ├─ Widget chatbot BoxAI
    │    └─ Webhooks Twilio
    │
    ├──▶ operator.boxanet.com (Rocky Linux VPS)
    │    ├─ Node.js 20 + Puppeteer
    │    ├─ Publication sur sites cibles (Jestocke, OuiStock, Costockage)
    │    └─ Synology reverse proxy (HTTPS)
    │
    └──▶ dev.boxanet.com (Rocky Linux VPS)
         ├─ Documentation technique
         ├─ Apache 2.4
         └─ Synology reverse proxy (HTTPS)

Ressources Externes

đŸ’» Commandes utiles

Retrouvez ici toutes les commandes fréquemment utilisées pour administrer l'écosystÚme Boxanet.

🚀 DĂ©ploiement

Site principal (www.boxanet.com)

# Déployer le site vers OVH (production)
./deploy.sh

# Le script fait :
# 1. Synchronise les fichiers via LFTP
# 2. Exclut .git, node_modules, tests, logs
# 3. Préserve le dossier uploads/ (photos)

Opérateur (operator.boxanet.com)

⚠ DĂ©ploiement en 2 Ă©tapes (nĂ©cessite connexion SSH)

Étape 1 : Depuis votre Mac (local)

# Exécuter le script de déploiement
./deploy-operator.sh

# Ce que fait le script :
# 1. rsync local → staging sur Rocky Linux (~nauleaufrederic/boxanet-operator-staging/)
# 2. Affiche les commandes à exécuter manuellement (étape 2)

Étape 2 : Se connecter en SSH sur Rocky Linux

# Se connecter au serveur
ssh nauleaufrederic@192.168.21.250

# Une fois connecté, passer en root
su -

# Copier staging → production
rsync -a --delete /home/nauleaufrederic/boxanet-operator-staging/ /opt/boxanet-operator/

# Ajuster les permissions
chown -R nginx:nginx /opt/boxanet-operator

# Redémarrer le service
systemctl restart boxanet-operator

# Vérifier que le service est actif
systemctl status boxanet-operator

# Quitter la session root puis SSH
exit
exit
Pourquoi 2 étapes ?
Le script ne peut pas copier directement vers /opt/boxanet-operator car ce dossier nécessite les droits root. Il copie d'abord en staging (accessible sans root), puis vous devez vous connecter en SSH pour finaliser le déploiement avec sudo.

Documentation (dev.boxanet.com)

⚠ DĂ©ploiement en 2 Ă©tapes (nĂ©cessite connexion SSH)

Étape 1 : Depuis votre Mac (local)

# Exécuter le script de déploiement
./dev/deploy-to-rocky.sh

# Ce que fait le script :
# 1. rsync local → staging sur Rocky Linux (~nauleaufrederic/dev-staging/)
# 2. Affiche les commandes à exécuter manuellement (étape 2)

Étape 2 : Se connecter en SSH sur Rocky Linux

# Se connecter au serveur
ssh nauleaufrederic@192.168.21.250

# Une fois connecté, passer en root
su -

# Copier staging → production
rsync -a --delete /home/nauleaufrederic/dev-staging/ /var/www/dev.boxanet.com/public_html/

# Ajuster les permissions
chown -R apache:apache /var/www/dev.boxanet.com/public_html

# Recharger Apache (sans coupure)
systemctl reload httpd

# Vérifier qu'Apache est actif
systemctl status httpd

# Quitter la session root puis SSH
exit
exit
Pourquoi 2 étapes ?
Le script ne peut pas copier directement vers /var/www/dev.boxanet.com/ car ce dossier nécessite les droits root. Il copie d'abord en staging (accessible sans root), puis vous devez vous connecter en SSH pour finaliser le déploiement avec sudo.

📊 Logs en temps rĂ©el

Opérateur (systemd)

# Suivre les logs en temps réel
journalctl -u boxanet-operator -f

# Afficher les 100 derniĂšres lignes
journalctl -u boxanet-operator -n 100

# Logs depuis une date
journalctl -u boxanet-operator --since "2026-02-05 10:00:00"

# Logs avec priorité (erreurs uniquement)
journalctl -u boxanet-operator -p err

Site principal (www.boxanet.com)

Les logs sont accessibles via l'interface web OVH, pas en SSH.

Accéder aux logs via OVH

  1. Se connecter sur Manager OVH
  2. Aller dans Web Cloud → HĂ©bergements
  3. Sélectionner l'hébergement boxanet.com
  4. Onglet Plus → Statistiques et logs
  5. Consulter les logs en temps quasi-réel (rafraßchis toutes les 5 minutes)
💡 Types de logs disponibles :
‱ error.log : Erreurs PHP, Apache, timeouts
‱ access.log : Toutes les requĂȘtes HTTP (IP, URL, code statut)
‱ out.log : Sorties standards (echo, print)

⚙ Gestion des services

Opérateur (systemd)

# Statut du service
systemctl status boxanet-operator

# Démarrer
systemctl start boxanet-operator

# ArrĂȘter
systemctl stop boxanet-operator

# Redémarrer
systemctl restart boxanet-operator

# Activer au boot
systemctl enable boxanet-operator

# Désactiver au boot
systemctl disable boxanet-operator

# Recharger la config systemd aprĂšs modification du .service
systemctl daemon-reload

Apache (dev.boxanet.com)

# Statut
systemctl status httpd

# Redémarrer
systemctl restart httpd

# Recharger la config (sans coupure)
systemctl reload httpd

# Tester la syntaxe de la config
apachectl configtest
httpd -t

🔍 Tests & VĂ©rifications

Health checks

# OpĂ©rateur (depuis n'importe oĂč)
curl https://operator.boxanet.com/health

# Opérateur (depuis Rocky Linux - réseau local)
curl http://192.168.21.250:3000/health

# Site principal
curl -I https://www.boxanet.com

# Documentation
curl -I https://dev.boxanet.com

Tests unitaires (site)

# Exécuter tous les tests
./vendor/bin/phpunit

# Tests unitaires uniquement
./vendor/bin/phpunit --testsuite Unit

# Tests d'un modÚle spécifique
./vendor/bin/phpunit --filter User

# Avec couverture de code (génÚre coverage/)
./vendor/bin/phpunit --coverage-html coverage/

Vérifications sécurité

# Permissions .env (doit ĂȘtre 600)
ls -la .env
ls -la /opt/boxanet-operator/.env

# Firewall (zones et ports)
firewall-cmd --list-all
firewall-cmd --zone=local-network --list-all

# SELinux (si problĂšmes de permissions)
getenforce  # Doit retourner "Enforcing"
audit2why -a  # Analyser les denials SELinux

đŸ’Ÿ Base de donnĂ©es

MySQL production (OVH)

L'accÚs direct à la base de données MySQL est limité. Utilisez phpMyAdmin via l'interface OVH :

Accéder à phpMyAdmin

  1. Se connecter sur Manager OVH
  2. Aller dans Web Cloud → HĂ©bergements
  3. Sélectionner l'hébergement boxanet.com
  4. Onglet Bases de données
  5. Cliquer sur Accéder à phpMyAdmin
💡 OpĂ©rations disponibles :
‱ Export : Sauvegarder la base (SQL, CSV, JSON)
‱ Import : Restaurer un backup ou exĂ©cuter une migration SQL
‱ RequĂȘtes SQL : Onglet "SQL" pour exĂ©cuter des commandes
‱ Structure : Visualiser les tables et colonnes
# Exemple de migration à exécuter via phpMyAdmin
# Copier le contenu du fichier SQL dans l'onglet "SQL"
# Ou utiliser "Importer" pour un fichier .sql complet

-- Exemple de requĂȘte
SELECT COUNT(*) FROM boxes WHERE status = 'available';
UPDATE storage_sites SET is_active = 1 WHERE id = 4;

🔧 Maintenance

Nettoyage logs

# Rotation manuelle des logs systemd (libérer espace)
journalctl --vacuum-time=7d  # Garder 7 jours
journalctl --vacuum-size=500M  # Limiter Ă  500MB

# Vérifier l'espace disque
df -h
du -sh /var/log/
du -sh /opt/boxanet-operator/logs/

Mise à jour dépendances

# PHP (Composer)
composer update
composer audit  # Vérifier vulnérabilités

# Node.js (Opérateur)
cd /opt/boxanet-operator
npm outdated
npm update
npm audit fix
systemctl restart boxanet-operator

Certificats SSL

# Vérifier expiration (via Synology DSM)
# Panneau de configuration → SĂ©curitĂ© → Certificat

# Renouveler manuellement (si nécessaire)
# Let's Encrypt renouvelle automatiquement 30 jours avant expiration

# Vérifier via commande (depuis l'extérieur)
openssl s_client -connect operator.boxanet.com:443 -servername operator.boxanet.com < /dev/null 2>/dev/null | openssl x509 -noout -dates

🐛 DĂ©bogage

Opérateur ne démarre pas

# Vérifier les logs détaillés
journalctl -u boxanet-operator -xe

# Tester manuellement (arrĂȘter le service d'abord)
systemctl stop boxanet-operator
cd /opt/boxanet-operator
node server.js  # Observer les erreurs directement

# Vérifier les permissions
ls -la /opt/boxanet-operator
ls -la /opt/boxanet-operator/.env

Chromium ne se lance pas

# Tester Chromium manuellement
chromium-browser --headless --no-sandbox --dump-dom https://www.google.com | head -20

# Vérifier dépendances manquantes
ldd /usr/bin/chromium-browser | grep "not found"

# Réinstaller dépendances
dnf reinstall chromium pango libXcomposite gtk3 nss -y

ProblĂšmes de connexion MQTT

# Tester connexion EMQX depuis le serveur
telnet o101170f.ala.eu-central-1.emqxsl.com 8883

# Vérifier certificats SSL EMQX
openssl s_client -connect o101170f.ala.eu-central-1.emqxsl.com:8883 -servername o101170f.ala.eu-central-1.emqxsl.com

# Logs MQTT dans Boxanet
grep "MQTT" ~/logs/error.log
💡 Astuce pro : CrĂ©ez des alias dans votre ~/.bashrc ou ~/.zshrc :
# Alias utiles Boxanet
alias logs-op="journalctl -u boxanet-operator -f"
alias status-op="systemctl status boxanet-operator"
alias restart-op="sudo systemctl restart boxanet-operator"
alias deploy-site="cd ~/Boxanet && ./deploy.sh"
alias deploy-op="cd ~/Boxanet && ./deploy-operator.sh"

🌐 Installation - Site www.boxanet.com

📍 HĂ©bergement: OVH MutualisĂ© Performance
🔗 Production: https://www.boxanet.com
🚀 DĂ©ploiement: Automatique via FTP/LFTP

Prérequis

  • PHP 8.2 ou supĂ©rieur
  • MySQL 8.0 ou supĂ©rieur
  • Composer (pour PHPUnit et dĂ©pendances)
  • Git
  • LFTP pour le dĂ©ploiement

1. Cloner le repository

# Cloner le projet
git clone https://github.com/GeoCodeTout/Boxanet.git
cd Boxanet

# Installer dépendances PHP
composer install

2. Configuration locale

# Copier le fichier de configuration
cp .env.example .env

# Éditer les paramùtres
nano .env
.env - Configuration complĂšte
# =========================================================================
# Base de données
# =========================================================================
DB_HOST=localhost                # Production: zxxnwuxboxarium.mysql.db
DB_USER=root                     # Production: zxxnwuxboxarium
DB_PASS=votre_mot_de_passe       # Production: [mot de passe sécurisé]
DB_NAME=boxanet_dev              # Production: zxxnwuxboxarium
DB_PORT=3306

# =========================================================================
# Application
# =========================================================================
APPROOT=
BASE_URL=http://localhost:8000   # Production: https://www.boxanet.com
SITENAME=Boxanet
ADMIN_PHONE=+33686443984

# Sécurité HTTPS
FORCE_HTTPS=false                # Production: true
ENVIRONMENT=development          # Production: production

# =========================================================================
# IA - Mammouth.AI (API compatible OpenAI)
# =========================================================================
MAMMOUTH_API_KEY=                # Production: sk-djVHFTc5j1ndEo9DglB5EA

# =========================================================================
# Chiffrement et JWT
# =========================================================================
ENCRYPTION_KEY=                  # Générer: openssl rand -base64 32
JWT_SECRET=                      # Générer: openssl rand -base64 32

# =========================================================================
# EMQX Cloud - MQTT (IoT)
# =========================================================================
EMQX_HOST=o101170f.ala.eu-central-1.emqxsl.com
EMQX_PORT=8883
EMQX_API_ENDPOINT=https://o101170f.ala.eu-central-1.emqxsl.com:8443/api/v5
EMQX_APP_ID=                     # Production: k7ea1188
EMQX_APP_SECRET=                 # Production: [secret sécurisé]
MQTT_WEBHOOK_TOKEN=              # Production: [token sécurisé]

# =========================================================================
# Twilio - WhatsApp Business API
# =========================================================================
TWILIO_ACCOUNT_SID=              # Production: ACecf32eb01011e5a291f72d2de4825a72
TWILIO_AUTH_TOKEN=               # Production: [token sécurisé]
TWILIO_WHATSAPP_NUMBER=          # Production: +33745058890

# =========================================================================
# Google Analytics 4 (optionnel)
# =========================================================================
GA_MEASUREMENT_ID=               # Production: G-12T85GR6JR

# =========================================================================
# Operator Server - Headless Automation
# =========================================================================
OPERATOR_API_URL=https://operator.boxanet.com/api
OPERATOR_API_KEY=                # Générer avec: openssl rand -hex 32
⚠ SĂ©curitĂ©:
‱ GĂ©nĂ©rer des clĂ©s uniques pour ENCRYPTION_KEY et JWT_SECRET avec openssl rand -base64 32
‱ Ne JAMAIS commiter le .env dans Git
‱ Les clĂ©s API de production doivent ĂȘtre diffĂ©rentes du dĂ©veloppement

3. Base de données

# Créer la base de données
mysql -u root -p -e "CREATE DATABASE boxanet_dev CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"

# Importer le schéma
mysql -u root -p boxanet_dev < database/zxxnwuxboxarium.sql

4. Créer un utilisateur admin

# Script de création d'admin
php scripts/create-admin.php

# Renseigner: email, mot de passe
# L'utilisateur aura le rĂŽle super-admin

5. Démarrer en local

# Serveur PHP intégré
./start-dev-server.sh

# Ou manuellement
php -S localhost:8000 -t public/
✅ Accùs local: http://localhost:8000

6. Configuration production (OVH)

Créer deploy.conf à la racine :

deploy.conf
FTP_HOST=ftp.cluster028.hosting.ovh.net
FTP_USER=boxanetcom
FTP_PASS=votre_mot_de_passe
REMOTE_PATH=/www

7. Déployer en production

# Déploiement automatique
./deploy.sh

# Le script effectue :
# 1. Vérifie les exclusions (node_modules, tests, etc.)
# 2. Synchronise via LFTP
# 3. Exclut dev/, operator-server/, .git/
# 4. Préserve uploads/
⚠ Important:
‱ Ne JAMAIS dĂ©ployer config/config.php local
‱ Le fichier de config production existe dĂ©jĂ  sur OVH
‱ Le dossier uploads/ est exclu (photos stockĂ©es en prod)

8. Tests unitaires

# Exécuter tous les tests
./tests.sh

# Tests unitaires uniquement
./vendor/bin/phpunit --testsuite Unit

# Avec couverture de code
./vendor/bin/phpunit --coverage-html coverage/

⚙ Installation - OpĂ©rateur

🎯 Service: operator.boxanet.com
đŸ–„ïž Serveur: Rocky Linux 8 (VPS)
📩 Stack: Node.js 20 + Puppeteer + Chromium
🔒 Reverse Proxy: Synology DSM (HTTPS/SSL)

Sites cibles disponibles

Qu'est-ce que l'Opérateur Boxanet ?

L'Opérateur Boxanet est un serveur d'automatisation intelligent qui fonctionne 24h/24 pour publier automatiquement vos annonces de boxes disponibles sur les principales plateformes de distribution du self-stockage en France.

🎯 RĂŽle et bĂ©nĂ©fices

Sans l'Opérateur (processus manuel) :

  • CrĂ©er manuellement chaque annonce sur chaque site cible
  • Remplir 15-20 champs par plateforme (titre, description, dimensions, prix, photos...)
  • Mettre Ă  jour les annonces Ă  chaque changement de tarif
  • Supprimer les annonces quand les boxes sont louĂ©es
  • Temps requis : 15-30 minutes par box et par plateforme

Avec l'Opérateur (automatisé) :

  • ✅ Un clic dans Boxanet : "Publier sur [site cible]"
  • ✅ L'OpĂ©rateur remplit automatiquement tous les champs
  • ✅ TĂ©lĂ©charge et positionne les photos
  • ✅ Valide et soumet l'annonce
  • ✅ Retourne le lien de l'annonce publiĂ©e
  • Temps requis : 30 secondes, sans intervention

🔧 Principe de fonctionnement

L'Opérateur utilise Puppeteer, une bibliothÚque qui pilote un navigateur Chrome en mode "headless" (sans interface graphique). Il simule les actions d'un utilisateur humain :

  1. Connexion : Se connecte au site cible avec vos identifiants (stockés de maniÚre sécurisée)
  2. Navigation : AccÚde au formulaire de dépÎt d'annonce
  3. Remplissage : ComplĂšte automatiquement tous les champs (type de box, dimensions, prix, adresse...)
  4. Photos : Télécharge les photos depuis Boxanet et les ajoute à l'annonce
  5. Validation : Soumet le formulaire et attend la confirmation
  6. Retour : Renvoie l'ID et l'URL de l'annonce créée à Boxanet
💡 Avantage clĂ© : L'OpĂ©rateur s'adapte automatiquement aux changements d'interface des plateformes. MĂȘme si un site cible modifie son formulaire, l'OpĂ©rateur continue de fonctionner grĂące Ă  sa logique de navigation intelligente.

đŸ—ïž Architecture technique

L'Opérateur est un service Node.js indépendant hébergé sur un serveur dédié (pas sur l'hébergement mutualisé OVH). Cette séparation garantit :

  • Performances : Chromium nĂ©cessite des ressources importantes (CPU, RAM)
  • StabilitĂ© : Les publications n'impactent pas les performances de www.boxanet.com
  • SĂ©curitĂ© : Les identifiants des plateformes sont isolĂ©s du serveur web principal
  • ÉvolutivitĂ© : Facile d'ajouter de nouvelles plateformes

Architecture

Internet
    ↓
operator.boxanet.com (DNS)
    ↓
Synology DSM (HTTPS)
    ├─ SSL/TLS (Let's Encrypt)
    └─ Port 443 → HTTP 192.168.21.250:3000
        ↓
Rocky Linux 8 - Node.js Operator
    ├─ Express API
    ├─ Puppeteer + Chromium
    └─ Publication sur sites cibles

1. Prérequis serveur

Spécifications minimales:

  • OS: Rocky Linux 8
  • RAM: 2 GB minimum
  • CPU: 2 vCPUs
  • Stockage: 20 GB
  • IP fixe + DNS configurĂ©

2. Installation Node.js 20

# Reset module
dnf module reset nodejs

# Installer Node.js 20
dnf module install nodejs:20 -y

# Vérifier
node -v   # v20.19.5
npm -v    # 10.8.2

3. Installer Chromium

# Activer EPEL
dnf install epel-release -y

# Installer Chromium
dnf install chromium -y

# Dépendances graphiques headless
dnf install pango libXcomposite libXcursor libXdamage libXext \\
            libXi libXtst cups-libs libXScrnSaver libXrandr \\
            alsa-lib atk gtk3 nss libdrm libgbm mesa-libgbm -y

# Vérifier (teste les deux commandes possibles)
chromium-browser --version || chromium --version

# Tester le mode headless
chromium-browser --headless --no-sandbox --dump-dom https://www.google.com | head -20

4. Créer projet Operator

# Créer structure
mkdir -p /opt/boxanet-operator/{services,middleware,logs}
cd /opt/boxanet-operator

# Initialiser npm
npm init -y

# Installer dépendances (production uniquement)
npm install --production express puppeteer dotenv helmet express-rate-limit cors morgan

# Permissions
chown -R nginx:nginx /opt/boxanet-operator
chmod 755 /opt/boxanet-operator

# Créer .env (sera configuré à l'étape suivante)
touch /opt/boxanet-operator/.env
chmod 600 /opt/boxanet-operator/.env
chown nginx:nginx /opt/boxanet-operator/.env
💡 Note: Si vous avez un package.json complet avec les dĂ©pendances dĂ©jĂ  listĂ©es, utilisez simplement : npm install --production

5. Configuration

Générer une clé API sécurisée :

# Générer une clé aléatoire de 32 bytes (64 caractÚres hex)
openssl rand -hex 32

Créer /opt/boxanet-operator/.env avec la clé générée :

# Exemple avec la clé générée
API_KEY=a3f8c9d2e1b4567890abcdef1234567890abcdef1234567890abcdef12345678
PORT=3000
NODE_ENV=production

Sécuriser le fichier :

# Permissions restrictives (lecture seule par le propriétaire)
chmod 600 /opt/boxanet-operator/.env
chown nginx:nginx /opt/boxanet-operator/.env
⚠ Important: Conserver cette clĂ© API en lieu sĂ»r. Elle sera nĂ©cessaire dans config/config.php sur le serveur Boxanet pour appeler l'Operator.

6. Service systemd

Le service systemd permet de gérer l'Opérateur comme un service systÚme :

  • DĂ©marrage automatique : LancĂ© au dĂ©marrage du serveur (grĂące Ă  WantedBy=multi-user.target)
  • RedĂ©marrage automatique : Se relĂšve en cas de crash (Restart=on-failure)
  • Gestion centralisĂ©e : ContrĂŽlĂ© via systemctl start/stop/restart/status
  • Logs unifiĂ©s : Accessibles via journalctl -u boxanet-operator

Créer /etc/systemd/system/boxanet-operator.service :

nano /etc/systemd/system/boxanet-operator.service

Coller cette configuration :

/etc/systemd/system/boxanet-operator.service
[Unit]
Description=Boxanet Operator - Headless Automation Service
Documentation=https://dev.boxanet.com
After=network.target

[Service]
Type=simple
User=nginx
Group=nginx
WorkingDirectory=/opt/boxanet-operator
Environment=NODE_ENV=production
Environment=HOME=/var/lib/nginx

ExecStart=/usr/bin/node server.js

Restart=on-failure
RestartSec=10

StandardOutput=journal
StandardError=journal
SyslogIdentifier=boxanet-operator

NoNewPrivileges=true
PrivateTmp=true

[Install]
WantedBy=multi-user.target

7. Firewall

Restreindre l'accĂšs au port 3000 uniquement au rĂ©seau local (192.168.x.x) pour empĂȘcher les connexions depuis Internet :

# Créer une zone firewall pour le réseau local
firewall-cmd --permanent --new-zone=local-network
firewall-cmd --permanent --zone=local-network --add-source=192.168.0.0/16
firewall-cmd --permanent --zone=local-network --add-port=3000/tcp
firewall-cmd --reload

# Vérifier la configuration
firewall-cmd --zone=local-network --list-all
⚠ SĂ©curitĂ© critique :
‱ Le port 3000 doit ĂȘtre accessible UNIQUEMENT depuis le rĂ©seau local (Synology reverse proxy)
‱ ❌ Ne JAMAIS utiliser --add-port=3000/tcp sans zone spĂ©cifique (ouvre Ă  Internet !)
‱ ✅ Toujours restreindre avec une zone dĂ©diĂ©e ou rich rule

Vérification de sécurité :

# Tester depuis le réseau local (doit fonctionner)
curl http://192.168.21.250:3000/health

# Tester depuis Internet (doit échouer / timeout)
# Depuis un autre réseau, tenter d'accéder à l'IP publique:3000

8. Reverse Proxy Synology

Panneau de configuration → SĂ©curitĂ© → Certificat:

  1. Ajouter → Let's Encrypt
  2. Domaine: operator.boxanet.com
  3. Email: frederic@boxanet.com

Portail d'application → Reverse Proxy:

  • Source: HTTPS, operator.boxanet.com, port 443
  • Destination: HTTP, 192.168.21.250, port 3000
  • Activer HSTS et HTTP/2

9. Démarrer le service

# Recharger systemd
systemctl daemon-reload

# Activer au boot
systemctl enable boxanet-operator

# Démarrer
systemctl start boxanet-operator

# Vérifier
systemctl status boxanet-operator

10. Tests

# Health check local
curl http://localhost:3000/health

# Health check depuis Internet
curl https://operator.boxanet.com/health

# Vérifier SSL
curl -v https://operator.boxanet.com/health
✅ Service opĂ©rationnel!
Consulter les logs: journalctl -u boxanet-operator -f

Déploiement des mises à jour

# Depuis votre Mac
./deploy-operator.sh

# Le script effectue:
# 1. rsync vers staging (user)
# 2. Affiche commandes sudo pour prod
# 3. sudo rsync vers /opt/boxanet-operator
# 4. Redémarrage service

đŸ› ïž Installation - Serveur Dev

🎯 Service: dev.boxanet.com
đŸ–„ïž Serveur: Rocky Linux 8 (VPS)
📩 Stack: Apache 2.4
🔒 Reverse Proxy: Synology DSM (HTTPS/SSL)

Qu'est-ce que dev.boxanet.com ?

dev.boxanet.com est le serveur de documentation technique de Boxanet. Il hĂ©berge cette documentation que vous ĂȘtes en train de lire, accessible 24h/24 pour l'Ă©quipe de dĂ©veloppement.

🎯 Rîle et avantages

  • Documentation centralisĂ©e : Une seule source de vĂ©ritĂ© pour toute l'Ă©quipe
  • Toujours Ă  jour : DĂ©ployĂ©e automatiquement avec les derniĂšres modifications
  • Accessible partout : HTTPS sĂ©curisĂ©, disponible de n'importe oĂč
  • VersionnĂ© : SynchronisĂ© avec le repository Git principal
  • ThĂšme adaptatif : Mode sombre/clair, recherche intĂ©grĂ©e

đŸ—ïž Architecture simplifiĂ©e

Le serveur de documentation utilise une architecture statique simple :

  • HTML/CSS/JS statiques : Pas de backend PHP ou base de donnĂ©es
  • Apache comme serveur web : LĂ©ger et performant pour du contenu statique
  • SSL gĂ©rĂ© par Synology : Pas besoin de configurer Let's Encrypt sur Rocky Linux
  • DĂ©ploiement par rsync : Copie directe des fichiers HTML
💡 Avantage clĂ© : SĂ©paration totale entre documentation (dev.boxanet.com) et application (www.boxanet.com). Si un serveur a un problĂšme, l'autre reste accessible.

Architecture

Internet
    ↓
dev.boxanet.com (DNS)
    ↓
Synology DSM (HTTPS)
    ├─ SSL/TLS (Let's Encrypt)
    └─ Port 443 → HTTP 192.168.21.250:80
        ↓
Rocky Linux 8 - Apache
    └─ Documentation technique
📌 SSL Termination: Le Synology gĂšre le SSL. Apache Ă©coute en HTTP sur le rĂ©seau local uniquement. Plus simple et aussi sĂ©curisĂ© sur rĂ©seau privĂ©.

1. Installer Apache

# Connexion SSH
ssh nauleaufrederic@192.168.21.250
su -

# Mise Ă  jour systĂšme
dnf update -y

# Installer Apache
dnf install httpd -y

# Vérifier
httpd -v   # Apache/2.4.37 (rocky)

2. Structure répertoires

# Créer structure
mkdir -p /var/www/dev.boxanet.com/{public_html,logs}

# Permissions
chown -R apache:apache /var/www/dev.boxanet.com
chmod -R 755 /var/www/dev.boxanet.com

3. Virtual Host

Créer /etc/httpd/conf.d/dev.boxanet.com.conf :

/etc/httpd/conf.d/dev.boxanet.com.conf
<VirtualHost *:80>
    ServerName dev.boxanet.com
    ServerAdmin frederic@boxanet.com
    
    DocumentRoot /var/www/dev.boxanet.com/public_html
    
    ErrorLog /var/www/dev.boxanet.com/logs/error.log
    CustomLog /var/www/dev.boxanet.com/logs/access.log combined
    
    <Directory /var/www/dev.boxanet.com/public_html>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
        DirectoryIndex index.html index.md README.md
    </Directory>
</VirtualHost>
⚠ Port 80, pas 443! Le Synology gĂšre le SSL et forward en HTTP vers Apache.

4. SELinux

# Créer fichiers logs
touch /var/www/dev.boxanet.com/logs/{error,access}.log

# Permissions
chown -R apache:apache /var/www/dev.boxanet.com/logs
chmod -R 755 /var/www/dev.boxanet.com/logs

# Contexte SELinux pour logs (CRUCIAL)
semanage fcontext -a -t httpd_log_t "/var/www/dev.boxanet.com/logs(/.*)?"
restorecon -R /var/www/dev.boxanet.com/logs

# Contexte pour contenu
chcon -R -t httpd_sys_content_t /var/www/dev.boxanet.com/public_html

# Vérifier
ls -Z /var/www/dev.boxanet.com/logs/

5. Firewall (réseau local uniquement)

# Créer zone locale
firewall-cmd --permanent --new-zone=boxanet-local
firewall-cmd --permanent --zone=boxanet-local --add-source=192.168.0.0/16
firewall-cmd --permanent --zone=boxanet-local --add-port=80/tcp

# Recharger
firewall-cmd --reload

# Vérifier
firewall-cmd --zone=boxanet-local --list-all

6. Démarrer Apache

# Tester config
httpd -t   # Syntax OK

# Démarrer
systemctl start httpd
systemctl enable httpd

# Vérifier
systemctl status httpd

7. Reverse Proxy Synology

Panneau de configuration → SĂ©curitĂ© → Certificat:

  1. Ajouter → Let's Encrypt
  2. Domaine: dev.boxanet.com
  3. Email: frederic@boxanet.com

Portail d'application → Reverse Proxy:

  • Source: HTTPS, dev.boxanet.com, port 443
  • Destination: HTTP, 192.168.21.250, port 80
  • Activer HSTS et HTTP/2

8. Tests

# Depuis le serveur Rocky
curl http://localhost

# Depuis le Synology
curl http://192.168.21.250

# Depuis Internet
curl https://dev.boxanet.com

# Vérifier SSL
curl -v https://dev.boxanet.com

9. Déploiement contenu

Script deploy-to-rocky.sh dans le dossier dev/ :

# Depuis votre Mac (racine du projet)
./dev/deploy-to-rocky.sh

# Le script effectue:
# 1. rsync dev/ vers staging
# 2. Demande confirmation
# 3. sudo rsync vers /var/www/dev.boxanet.com/public_html
# 4. chown apache:apache
# 5. systemctl reload httpd
✅ Site opĂ©rationnel!
AccĂšs: https://dev.boxanet.com

Dépannage

Apache ne démarre pas (Permission denied logs):

# Vérifier contexte SELinux
ls -Z /var/www/dev.boxanet.com/logs/

# Doit afficher httpd_log_t
# Si incorrect, réappliquer:
semanage fcontext -a -t httpd_log_t "/var/www/dev.boxanet.com/logs(/.*)?"
restorecon -R /var/www/dev.boxanet.com/logs

Page ne s'affiche pas:

# Vérifier firewall
firewall-cmd --zone=boxanet-local --list-all

# Logs Apache
tail -50 /var/log/httpd/error_log
tail -50 /var/www/dev.boxanet.com/logs/error.log

đŸ—ïž Architecture - Vue Globale

Pattern MVC

Couche Emplacement Responsabilité
ContrÎleurs app/controllers/ Routing, orchestration, validation entrée
ModÚles app/models/ AccÚs BDD, logique métier
Vues app/views/ Affichage HTML uniquement
Helpers app/helpers/ Fonctions utilitaires (statiques)
⚠ RĂšgles strictes:
‱ Jamais de requĂȘtes SQL dans contrĂŽleurs ou vues
‱ ContrĂŽleurs hĂ©ritent de BaseController
‱ ModĂšles hĂ©ritent de BaseModel
‱ PDO singleton partagĂ© par tous les modĂšles

Mutualisation Dashboard/Admin

DASHBOARD UTILISATEUR ─────┐
(managers, employĂ©s)       │
                           ├──▶ CONTRÔLEURS DOMAINE
ADMIN BOXANET ─────────────┘    ├─ BoxController        (boxes + JSON)
(super-admin)                   ├─ UserController       (users + JSON)
                                ├─ CustomerController   (customers + JSON)
                                ├─ StoragesiteController(sites + geocode)
                                ├─ PlanController       (plans + positions)
                                └─ CompanyController    (entreprises)
                                          │
                                          ▌
                                AdminController (fonctions super-admin only)
                                ├─ deviceStatusJson()
                                ├─ userAccess*Json()
                                ├─ impersonation
                                └─ gestion globale

Endpoints API JSON

Chaque contrÎleur de domaine gÚre ses propres endpoints. Ne pas créer de contrÎleur API centralisé.

Endpoint ContrÎleur Méthode
/api/users UserController listJson()
/api/boxes BoxController listJson()
/api/sites StoragesiteController listJson()
/api/customers CustomerController listJson()
/api/geocode StoragesiteController geocodeJson()
/api/saveBoxPosition PlanController saveBoxPositionJson()
/api/deviceStatus AdminController deviceStatusJson()
/access/action AccessController action()

Chargement des modĂšles

✅ CORRECT - Pattern recommandĂ© (typage strict)
require_once __DIR__ . '/../models/Zone.php';
require_once __DIR__ . '/../models/Box.php';

class ZoneController extends BaseController
{
    /** @var Zone Instance du modĂšle Zone */
    private Zone $zoneModel;
    
    /** @var Box Instance du modĂšle Box */
    private Box $boxModel;

    public function __construct()
    {
        parent::__construct();
        $this->zoneModel = new Zone();
        $this->boxModel = new Box();
    }
}
❌ DÉPRÉCIÉ - Éviter loadModel() (perte du typage strict)
protected ?object $Box = null;
$this->loadModel('Box');

⚙ Configuration - Site www.boxanet.com

Le site Boxanet utilise un fichier .env pour centraliser toutes les variables de configuration. Ce fichier doit ĂȘtre créé Ă  partir de .env.example et ne doit jamais ĂȘtre committĂ© dans Git.

⚠ SĂ©curitĂ©:
‱ Ne jamais exposer le .env publiquement
‱ Utiliser des valeurs diffĂ©rentes entre dev/staging/production
‱ GĂ©nĂ©rer des clĂ©s alĂ©atoires pour ENCRYPTION_KEY et JWT_SECRET

📊 Base de donnĂ©es

ParamĂštre Description Exemple Dev Exemple Production
DB_HOST HĂŽte du serveur MySQL localhost zxxnwuxboxarium.mysql.db
DB_USER Nom d'utilisateur MySQL root zxxnwuxboxarium
DB_PASS Mot de passe MySQL votre_mdp [mot de passe sécurisé]
DB_NAME Nom de la base de données boxanet_dev zxxnwuxboxarium
DB_PORT Port MySQL 3306 3306

🌐 Application

ParamĂštre Description Valeurs possibles
APPROOT Chemin racine de l'application (optionnel) Laisser vide sauf si sous-dossier
BASE_URL URL complĂšte du site http://localhost:8000
https://www.boxanet.com
SITENAME Nom du site (utilisé dans emails, titres) Boxanet
ADMIN_PHONE Téléphone de l'administrateur principal +33686443984
FORCE_HTTPS Forcer la redirection HTTPS false (dev)
true (production)
ENVIRONMENT Environnement d'exécution development, staging, production

đŸ€– Intelligence Artificielle

ParamĂštre Description Usage
MAMMOUTH_API_KEY Clé API Mammouth.AI (compatible OpenAI) Assistant virtuel BoxAI, génération de textes, conversations WhatsApp
💡 Mammouth.AI: API française compatible avec l'API OpenAI. UtilisĂ©e pour gĂ©nĂ©rer les rĂ©ponses de l'assistant BoxAI et automatiser les conversations WhatsApp.

🔐 SĂ©curitĂ© & Chiffrement

ParamÚtre Description Génération
ENCRYPTION_KEY Clé de chiffrement AES-256 pour données sensibles openssl rand -base64 32
JWT_SECRET Secret pour signer les tokens JWT openssl rand -base64 32
⚠ Critique: Ces clĂ©s doivent ĂȘtre uniques par environnement et jamais partagĂ©es. Si compromises, rĂ©gĂ©nĂ©rez-les immĂ©diatement.

📡 EMQX Cloud - MQTT (IoT)

ParamĂštre Description Usage
EMQX_HOST HĂŽte du broker MQTT EMQX Connexion au broker pour contrĂŽle des appareils IoT
EMQX_PORT Port MQTT sécurisé (TLS) 8883 (MQTT over SSL/TLS)
EMQX_API_ENDPOINT Endpoint API REST EMQX Gestion des clients, topics, ACL via API
EMQX_APP_ID Identifiant application EMQX Authentification API
EMQX_APP_SECRET Secret application EMQX Authentification API (à protéger)
MQTT_WEBHOOK_TOKEN Token de validation des webhooks EMQX Vérifier l'authenticité des callbacks EMQX
💡 EMQX Cloud: Broker MQTT cloud utilisĂ© pour contrĂŽler les appareils IoT (ouverture de portails, accĂšs boxes). Les webhooks notifient Boxanet lors d'Ă©vĂ©nements (connexion/dĂ©connexion devices, messages).

💬 Twilio - WhatsApp Business

ParamĂštre Description Usage
TWILIO_ACCOUNT_SID Identifiant de compte Twilio Authentification API Twilio
TWILIO_AUTH_TOKEN Token d'authentification Twilio Signature des requĂȘtes API (Ă  protĂ©ger)
TWILIO_WHATSAPP_NUMBER Numéro WhatsApp Business +33745058890 - Numéro d'envoi des messages
💡 Twilio WhatsApp: API utilisĂ©e pour l'assistant virtuel BoxAI. Les clients peuvent converser par WhatsApp pour poser des questions, demander des devis, ou recevoir des notifications.

📊 Google Analytics 4

ParamĂštre Description Usage
GA_MEASUREMENT_ID ID de mesure Google Analytics 4 Tracking global (peut ĂȘtre surchargĂ© par site)
💡 Configuration multi-sites: Ce GA_MEASUREMENT_ID est la valeur par dĂ©faut. Chaque site peut avoir son propre ID configurĂ© dans la base de donnĂ©es (table storage_sites).

đŸ€– Operator Server

ParamĂštre Description Usage
OPERATOR_API_URL URL de l'API Operator https://operator.boxanet.com/api
OPERATOR_API_KEY Clé API pour authentifier les appels Générer avec: openssl rand -hex 32
⚠ Synchronisation: La clĂ© OPERATOR_API_KEY doit ĂȘtre identique dans le .env du site Boxanet ET dans le .env du serveur Operator.

⚙ Configuration - OpĂ©rateur

Le serveur Operator utilise également un fichier .env pour sa configuration. Ce fichier se trouve dans /opt/boxanet-operator/.env sur le serveur Rocky Linux.

📍 Emplacement: /opt/boxanet-operator/.env
🔒 Permissions: chmod 600 et chown nginx:nginx

🌐 Configuration serveur

ParamÚtre Description Valeur recommandée
API_KEY ClĂ© API pour authentifier les requĂȘtes de Boxanet Identique Ă  OPERATOR_API_KEY du site
PORT Port d'écoute du serveur Express 3000
NODE_ENV Environnement Node.js production

🔐 GĂ©nĂ©ration de la clĂ© API

# Générer une clé aléatoire de 32 bytes (64 caractÚres hex)
openssl rand -hex 32

# Exemple de résultat:
# 3cc4eaf8333c24351512aaf9a38103c36f41f8666e23ad15c88318a598482200
Exemple .env complet
API_KEY=3cc4eaf8333c24351512aaf9a38103c36f41f8666e23ad15c88318a598482200
PORT=3000
NODE_ENV=production

🔗 Synchronisation avec Boxanet

La clĂ© API doit ĂȘtre configurĂ©e aux deux endroits :

1ïžâƒŁ Sur le serveur Operator (/opt/boxanet-operator/.env)

API_KEY=3cc4eaf8333c24351512aaf9a38103c36f41f8666e23ad15c88318a598482200

2ïžâƒŁ Sur le site Boxanet (.env Ă  la racine)

OPERATOR_API_KEY=3cc4eaf8333c24351512aaf9a38103c36f41f8666e23ad15c88318a598482200
⚠ Important: Sans cette clĂ© API ou si elle ne correspond pas, le site Boxanet ne pourra pas publier d'annonces via l'Operator (erreur 401 Unauthorized).

🔧 Variables d'environnement systemd

Le service systemd (/etc/systemd/system/boxanet-operator.service) définit également des variables d'environnement :

Variable Valeur Raison
NODE_ENV production Mode production Node.js (optimisations)
HOME /var/lib/nginx Puppeteer nécessite un répertoire HOME pour le cache Chromium
💡 Pourquoi HOME ? Sans la variable HOME, Puppeteer Ă©choue au dĂ©marrage avec l'erreur "Cannot find browser". Cette variable pointe vers un rĂ©pertoire accessible par l'utilisateur nginx.

đŸ—„ïž Architecture - Base de donnĂ©es

Documentation en cours de rédaction...

Référence complÚte: database/zxxnwuxboxarium.sql

đŸ€– Architecture - BoxAI

Documentation en cours de rédaction...

⚙ Architecture - Serveur Operator

Documentation en cours de rédaction...

📝 Conventions de code

Documentation en cours de rédaction...

đŸ—ïž Pattern MVC

Documentation en cours de rédaction...

🔒 SĂ©curitĂ©

Documentation en cours de rédaction...

đŸ§Ș Tests unitaires

Documentation en cours de rédaction...

🔌 API - Endpoints

Documentation en cours de rédaction...

🔐 API - Authentification

Documentation en cours de rédaction...

đŸ€– API - BoxAI

Documentation en cours de rédaction...

📡 Service MQTT/EMQX

Documentation en cours de rédaction...

💬 Service WhatsApp

Documentation en cours de rédaction...

📧 Services Email/SMS

Documentation en cours de rédaction...

🚀 DĂ©ploiement Production (OVH)

Documentation en cours de rédaction...

⚙ DĂ©ploiement Operator

Documentation en cours de rédaction...

đŸ› ïž DĂ©ploiement Dev Server

Documentation en cours de rédaction...