Remove unnecessary deployment guides and scripts from the project

This commit removes obsolete deployment documentation, shell scripts, and backup files.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: dec54137-d5a2-4406-8ad4-5f2f9fb110bf
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/0715008c-7244-40f4-befc-26c014852236/ce49b69a-6c08-46b0-9012-fdaae8591d14.jpg
This commit is contained in:
michaelschal committed 2025-07-11 19:05:12 +00:00
1 parent 9d973c12e4
commit 9016a564ec
42 files changed
+378 -3125

No files matched your search

-115
View File
@@ -1,115 +0,0 @@
# Déploiement Docker de RegisFlow
## 1. Préparer le serveur
```bash
# Créer le répertoire de déploiement
mkdir -p /opt/regisflow
cd /opt/regisflow
# Télécharger les fichiers essentiels
wget https://raw.githubusercontent.com/votre-repo/regisflow/main/docker-compose.yml
wget https://raw.githubusercontent.com/votre-repo/regisflow/main/.env.example
cp .env.example .env
```
## 2. Configuration (.env)
Editez le fichier `.env` selon votre environnement :
```env
# Base de données PostgreSQL
DATABASE_URL=postgresql://regisflow:VotreMotDePasseSecurise@regisflow-db:5432/regisflow
POSTGRES_PASSWORD=VotreMotDePasseSecurise
# Application
NODE_ENV=production
PORT=5000
SESSION_SECRET=VotreCleSecreteTresLongueEtSecurisee
# Timezone
TZ=Europe/Paris
# Sauvegardes
BACKUP_RETENTION_DAYS=90
MAX_BACKUP_COUNT=20
DATA_RETENTION_MONTHS=19
# Production (optionnel)
SECURE_COOKIES=true
ALLOWED_DOMAIN=votre-domaine.com
```
## 3. Déploiement
```bash
# Construire et démarrer les services
docker-compose up -d --build
# Vérifier le statut
docker-compose ps
docker-compose logs -f regisflow
# Les tables sont créées automatiquement au premier démarrage
```
## 4. Vérification
```bash
# Tester l'application
curl http://localhost:5000/health
# Voir les logs en temps réel
docker-compose logs -f
# Vérifier la base de données
docker-compose exec regisflow-db psql -U regisflow -d regisflow -c "\dt"
```
## 5. Accès à l'application
- **URL** : http://votre-serveur:5000
- **Admin** : admin / admin123
- **PostgreSQL** : localhost:5433 (depuis l'hôte)
## 6. Maintenance
```bash
# Arrêter l'application
docker-compose down
# Mise à jour
docker-compose pull
docker-compose up -d --force-recreate
# Sauvegardes manuelles
docker-compose exec regisflow npm run backup
# Voir l'utilisation des ressources
docker stats
```
## 7. Production avec reverse proxy (Nginx)
```nginx
server {
listen 80;
server_name votre-domaine.com;
location / {
proxy_pass http://localhost:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
```
## 8. Sécurité
- Changez POSTGRES_PASSWORD
- Changez SESSION_SECRET
- Configurez un firewall
- Activez HTTPS avec Let's Encrypt
- Sauvegardez régulièrement le volume PostgreSQL
-74
View File
@@ -1,74 +0,0 @@
# Déploiement Docker pour RegisFlow
## Problème résolu : Image Docker manquante
### Le problème
Portainer essayait de télécharger une image `regisflow-regisflow:latest` qui n'existe pas sur Docker Hub.
### Solution
L'image doit être construite localement avant utilisation.
## Instructions de déploiement
### 1. Construction de l'image Docker
```bash
# Méthode 1: Utiliser le script automatique
./build-docker.sh
# Méthode 2: Construction manuelle
docker build -t regisflow:latest .
```
### 2. Démarrage avec Docker Compose
```bash
# Démarrer tous les services
docker-compose up -d
# Vérifier le statut
docker-compose ps
```
### 3. Configuration dans Portainer
1. Utiliser le nom d'image : `regisflow:latest`
2. Ou utiliser la configuration Docker Compose existante
3. L'image sera trouvée localement après construction
## Vérification du déploiement
### Vérifier que l'image existe
```bash
docker images | grep regisflow
```
### Vérifier les logs
```bash
docker-compose logs -f regisflow
```
### Tester la santé de l'application
```bash
curl http://localhost:5000/health
```
## Notes importantes
- L'image doit être construite sur le serveur de déploiement
- La base de données PostgreSQL est incluse dans la configuration
- Les volumes sont persistants pour les sauvegardes et données
- Le port 5000 est exposé pour l'application
- Le port 5433 est exposé pour PostgreSQL (pour éviter les conflits)
## Résolution des problèmes courants
### Si l'image n'est pas trouvée
1. Vérifier que l'image a été construite : `docker images`
2. Reconstruire si nécessaire : `docker build -t regisflow:latest .`
### Si le conteneur ne démarre pas
1. Vérifier les logs : `docker-compose logs regisflow`
2. Vérifier la connectivité réseau : `docker network ls`
3. Vérifier les variables d'environnement
### Si PostgreSQL ne se connecte pas
1. Vérifier que le conteneur DB est en cours d'exécution
2. Vérifier la variable DATABASE_URL
3. Attendre que le healthcheck PostgreSQL passe (30s)
-59
View File
@@ -1,59 +0,0 @@
# Solution Finale pour Portainer
## Problème résolu
Le docker-compose.yml a été modifié pour forcer la construction locale et empêcher complètement le téléchargement d'images depuis Docker Hub.
## Modifications apportées
### 1. Suppression de la ligne `image:`
- Plus de référence à une image Docker Hub
- Force Portainer à construire localement
### 2. Ajout de `pull_policy: never`
- Empêche tout téléchargement d'image
- Force l'utilisation de la construction locale
### 3. Configuration de build explicite
```yaml
build:
context: .
dockerfile: Dockerfile
target: production
args:
- NODE_ENV=production
```
## Instructions Portainer
### Dans Portainer:
1. **Supprimez l'ancienne stack** si elle existe
2. **Créez une nouvelle stack** avec le nom "regisflow"
3. **Copiez le contenu** du docker-compose.yml modifié
4. **Déployez la stack**
### Portainer construira automatiquement:
- ✅ L'image sera construite depuis le code source
- ✅ Aucun téléchargement depuis Docker Hub
- ✅ Utilisation du réseau nginx_default
- ✅ Volumes persistants conservés
## Vérification
Après déploiement, vérifiez:
```bash
# Statut des conteneurs
docker ps | grep regisflow
# Logs de l'application
docker logs regisflow-app
# Test de l'application
curl http://localhost:5000/health
```
## Accès
- **URL**: http://votre-serveur:5000
- **Login**: admin / admin123
- **PostgreSQL**: Port 5433
Cette configuration finale devrait résoudre définitivement le problème de téléchargement d'image dans Portainer.
-104
View File
@@ -1,104 +0,0 @@
# Guide de déploiement Portainer pour RegisFlow
## Problème résolu
L'erreur `regisflow-regisflow:latest` vient du fait que Portainer cherche une image sur Docker Hub qui n'existe pas.
## Solution complète
### Étape 1: Construire l'image sur votre serveur
```bash
# Connectez-vous à votre serveur et allez dans le dossier RegisFlow
cd /chemin/vers/regisflow
# Construisez l'image Docker
docker build -t regisflow:latest .
# Vérifiez que l'image est créée
docker images | grep regisflow
```
### Étape 2: Créer la Stack dans Portainer
1. **Ouvrez Portainer** dans votre navigateur
2. **Allez dans "Stacks"**
3. **Cliquez sur "Add stack"**
4. **Donnez un nom** : `regisflow`
5. **Copiez le contenu** du fichier `portainer-stack.yml`
6. **Cliquez sur "Deploy the stack"**
### Étape 3: Configuration alternative (Container unique)
Si vous préférez créer un conteneur unique :
1. **Allez dans "Containers"**
2. **Cliquez sur "Add container"**
3. **Nom** : `regisflow-app`
4. **Image** : `regisflow:latest`
5. **Port mapping** : `5000:5000`
6. **Variables d'environnement** :
```
NODE_ENV=production
PORT=5000
DATABASE_URL=postgresql://regisflow:RegisFlow2024!PostgreSQL@regisflow-db:5432/regisflow
SESSION_SECRET=RegisFlow2024SessionSecretKey1234567890ABCDEF
```
## Script automatique
Pour simplifier le processus :
```bash
# Exécutez le script de déploiement
./deploy-portainer.sh
```
## Vérification du déploiement
### Vérifier les conteneurs
```bash
docker ps | grep regisflow
```
### Vérifier les logs
```bash
docker logs regisflow-app
```
### Tester l'application
```bash
curl http://localhost:5000/health
```
## Résolution des problèmes
### Si l'image n'est pas trouvée
1. Vérifiez que vous êtes sur le bon serveur
2. Reconstruisez l'image : `docker build -t regisflow:latest .`
3. Vérifiez avec : `docker images | grep regisflow`
### Si Portainer ne trouve pas l'image
1. L'image doit être construite sur le même serveur que Portainer
2. Utilisez exactement le nom : `regisflow:latest`
3. Pas de préfixe `docker.io/library/`
### Si la base de données ne se connecte pas
1. Vérifiez que PostgreSQL est démarré
2. Vérifiez la variable `DATABASE_URL`
3. Attendez que le health check passe (30-60 secondes)
## Points importants
- ✅ L'image doit être construite localement
- ✅ Utilisez `regisflow:latest` (pas `regisflow-regisflow:latest`)
- ✅ PostgreSQL inclus dans la stack
- ✅ Volumes persistants pour les données
- ✅ Health checks configurés
- ✅ Ports : 5000 (app) et 5433 (PostgreSQL)
## Accès à l'application
Une fois déployé :
- **URL** : `http://votre-serveur:5000`
- **Connexion** : `admin` / `admin123`
- **Changez le mot de passe** après la première connexion
-153
View File
@@ -1,153 +0,0 @@
# Solution Portainer pour RegisFlow
## Problème identifié
Portainer ne peut pas télécharger l'image `regisflow` car elle n'existe pas sur Docker Hub. Il faut construire l'image depuis le code source.
## Solution 1: Stack avec build automatique (RECOMMANDÉE)
### Étapes dans Portainer:
1. **Allez dans "Stacks"**
2. **Cliquez sur "Add stack"**
3. **Nom de la stack**: `regisflow`
4. **Méthode de build**: Repository
5. **Repository URL**: Collez l'URL de votre dépôt Git ou utilisez "Upload"
6. **Compose file**: Copiez le contenu de `portainer-build-stack.yml`
7. **Cliquez sur "Deploy the stack"**
### Contenu à copier dans Portainer:
```yaml
version: '3.8'
services:
regisflow-db:
image: postgres:15-alpine
container_name: regisflow-db
environment:
POSTGRES_DB: regisflow
POSTGRES_USER: regisflow
POSTGRES_PASSWORD: RegisFlow2024!PostgreSQL
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5433:5432"
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U regisflow -d regisflow"]
interval: 30s
timeout: 10s
retries: 5
start_period: 30s
regisflow:
build:
context: .
dockerfile: Dockerfile
target: production
container_name: regisflow-app
depends_on:
regisflow-db:
condition: service_healthy
environment:
NODE_ENV: production
PORT: 5000
DATABASE_URL: postgresql://regisflow:RegisFlow2024!PostgreSQL@regisflow-db:5432/regisflow
SESSION_SECRET: RegisFlow2024SessionSecretKey1234567890ABCDEF
TZ: Europe/Paris
volumes:
- backup_data:/app/backups
- logs_data:/app/logs
ports:
- "5000:5000"
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:5000/health || exit 1"]
interval: 30s
timeout: 15s
retries: 3
start_period: 90s
volumes:
postgres_data:
backup_data:
logs_data:
```
## Solution 2: Construction manuelle puis image
Si la solution 1 ne fonctionne pas:
### Étape A: Sur votre serveur
```bash
# Téléchargez les fichiers RegisFlow sur votre serveur
# Puis construisez l'image:
docker build -t regisflow:latest .
# Vérifiez que l'image existe:
docker images | grep regisflow
```
### Étape B: Dans Portainer
Utilisez ensuite le fichier `portainer-stack.yml` original avec `image: regisflow:latest`
## Solution 3: Docker Hub personnel (avancée)
Si vous avez un compte Docker Hub:
```bash
# Taguez l'image avec votre nom d'utilisateur
docker tag regisflow:latest votre-username/regisflow:latest
# Poussez vers Docker Hub
docker push votre-username/regisflow:latest
```
Puis utilisez `votre-username/regisflow:latest` dans Portainer.
## Vérification du déploiement
### Dans Portainer:
1. Vérifiez que la stack est "Running"
2. Consultez les logs des conteneurs
3. Vérifiez les health checks
### Accès à l'application:
- URL: `http://votre-serveur:5000`
- Login: `admin`
- Mot de passe: `admin123`
### Tests de connectivité:
```bash
# Test de santé de l'application
curl http://localhost:5000/health
# Vérification PostgreSQL
docker exec regisflow-db pg_isready -U regisflow -d regisflow
```
## Résolution des problèmes courants
### Stack en échec de build:
1. Vérifiez que tous les fichiers sont présents
2. Consultez les logs de build dans Portainer
3. Vérifiez les droits d'accès au Dockerfile
### Conteneur qui ne démarre pas:
1. Vérifiez les logs du conteneur
2. Vérifiez les variables d'environnement
3. Attendez que PostgreSQL soit prêt (health check)
### Application inaccessible:
1. Vérifiez que le port 5000 est ouvert
2. Vérifiez les logs de l'application
3. Testez le health check: `/health`
## Points importants
✅ **Utilisez la Solution 1 avec build automatique**
✅ **Tous les fichiers sources doivent être disponibles pour Portainer**
✅ **PostgreSQL démarre en premier (health check)**
✅ **Volumes persistants pour les données**
✅ **Réseau dédié pour la communication inter-conteneurs**
✅ **Health checks configurés pour surveillance automatique**
-167
View File
@@ -1,167 +0,0 @@
# Guide de Mise en Production RegisFlow
## Configuration rapide pour production
### 1. Télécharger et préparer
```bash
# Créer le dossier de production
mkdir /opt/regisflow && cd /opt/regisflow
# Télécharger les fichiers nécessaires
curl -O https://raw.githubusercontent.com/votre-repo/regisflow/main/docker-compose.yml
curl -O https://raw.githubusercontent.com/votre-repo/regisflow/main/Dockerfile
curl -O https://raw.githubusercontent.com/votre-repo/regisflow/main/docker-entrypoint-simple.sh
```
### 2. Configuration environnement
Créer le fichier `.env` :
```env
# === OBLIGATOIRE - À MODIFIER ===
POSTGRES_PASSWORD=VotreMotDePasseSuperSecurise123!
SESSION_SECRET=VotreCleSessionTresLongueEtSecurisee456789ABCDEF
# === APPLICATION ===
NODE_ENV=production
PORT=5000
TZ=Europe/Paris
# === SÉCURITÉ ===
SECURE_COOKIES=true
DATA_RETENTION_MONTHS=19
# === SAUVEGARDES ===
BACKUP_RETENTION_DAYS=90
MAX_BACKUP_COUNT=20
```
### 3. Déploiement immédiat
```bash
# Option A: Démarrer avec Docker Compose
docker-compose up -d --build
# Option B: Utiliser le script automatisé
chmod +x deploy-production.sh
./deploy-production.sh
# Vérifier le fonctionnement
curl http://localhost:5000/health
# Voir les logs
docker-compose logs -f regisflow
```
### 3.1 Initialisation manuelle de la base (si nécessaire)
```bash
# Si les tables ne se créent pas automatiquement
chmod +x init-db.sh
./init-db.sh
# Ou avec une DATABASE_URL spécifique
./init-db.sh "postgresql://regisflow:password@localhost:5433/regisflow"
```
### 4. Accès initial
- **URL** : http://votre-serveur:5000
- **Compte admin** : `admin` / `admin123`
- **Base de données** : accessible sur port 5433
### 5. Nginx reverse proxy (recommandé)
Ajouter à votre configuration Nginx :
```nginx
server {
listen 80;
server_name votre-domaine.com;
client_max_body_size 10M; # Pour les photos
location / {
proxy_pass http://localhost:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}
```
### 6. Maintenance courante
```bash
# Voir l'état des services
docker-compose ps
# Redémarrer l'application
docker-compose restart regisflow
# Mise à jour
docker-compose down
docker-compose up -d --build --force-recreate
# Sauvegardes manuelles
docker-compose exec regisflow node -e "require('./dist/backup-scheduler.js').createAutomaticBackup()"
# Accès aux données
docker-compose exec regisflow-db psql -U regisflow -d regisflow
```
### 7. Monitoring et logs
```bash
# Logs en temps réel
docker-compose logs -f
# Utilisation des ressources
docker stats regisflow-app regisflow-db
# Espace disque des volumes
docker system df
```
## Fonctionnalités automatiques en production
✅ **Sauvegardes automatiques** : Toutes les 12h (00:00 et 12:00)
✅ **Purge des données** : Automatique après 19 mois (1er de chaque mois)
✅ **Health checks** : Surveillance continue des services
✅ **Gestion des sessions** : Sessions PostgreSQL sécurisées
✅ **Optimisation mémoire** : Configuration pour serveurs de production
## Sécurité production
- [ ] Modifier `POSTGRES_PASSWORD` et `SESSION_SECRET`
- [ ] Configurer firewall (ports 80, 443, 22 uniquement)
- [ ] Activer HTTPS avec certificats SSL
- [ ] Sauvegardes régulières vers stockage externe
- [ ] Monitoring des logs d'erreurs
- [ ] Changer le mot de passe admin par défaut
## Support et dépannage
**Problèmes courants :**
1. **Application inaccessible** : Vérifier `docker-compose ps` et les logs
2. **Erreur base de données** : Vérifier que PostgreSQL est démarré
3. **Photos ne se sauvegardent pas** : Vérifier les permissions du volume
4. **Performance lente** : Augmenter les limites mémoire Docker
**Commandes de diagnostic :**
```bash
# État complet du système
docker-compose ps && docker-compose logs --tail=50
docker system df && df -h
# Test complet de l'application
curl -v http://localhost:5000/health
curl -v http://localhost:5000/api/auth/default-credentials-status
```
@@ -1,42 +0,0 @@
📊 Backup stats: 1 users, 1 stores, 0 sales
1:10:47 AM [express] GET /api/auth/me 401 in 2ms :: {"error":"Authentication required"}
1:10:47 AM [express] GET /api/auth/me 401 in 1ms :: {"error":"Authentication required"}
1:10:47 AM [express] GET /api/auth/default-credentials-status 200 in 331ms :: {"showDefaultCredentia…
1:11:02 AM [express] POST /api/auth/login 200 in 513ms :: {"user":{"id":1,"username":"admin","email"…
1:11:03 AM [express] GET /api/auth/me 200 in 71ms :: {"id":1,"username":"admin","email":"admin@examp…
1:11:03 AM [express] GET /api/auth/me 304 in 9ms :: {"id":1,"username":"admin","email":"admin@exampl…
1:11:03 AM [express] GET /api/auth/me 304 in 7ms :: {"id":1,"username":"admin","email":"admin@exampl…
1:11:03 AM [express] GET /api/auth/me 304 in 12ms :: {"id":1,"username":"admin","email":"admin@examp…
1:11:03 AM [express] GET /api/admin/stores 200 in 30ms :: [{"id":1,"name":"Magasin Principal","addre…
1:11:11 AM [express] GET /api/admin/users 200 in 9ms :: [{"id":1,"username":"admin","email":"admin@e…
1:11:11 AM [express] GET /api/admin/backup/stats 200 in 5ms :: {"totalBackups":1,"backupDirectory":"…
1:11:11 AM [express] GET /api/admin/purge/stats 200 in 7ms :: {"totalSales":0,"oldSales":0,"cutoffDa…
1:11:36 AM [express] PUT /api/admin/users/1 200 in 410ms :: {"id":1,"username":"admin","email":"mich…
1:11:36 AM [express] GET /api/admin/users 403 in 4ms :: {"error":"Insufficient permissions"}
1:11:41 AM [express] GET /api/admin/purge/stats 403 in 5ms :: {"error":"Insufficient permissions"}
1:11:41 AM [express] GET /api/admin/backup/stats 403 in 20ms :: {"error":"Insufficient permissions"}
1:11:50 AM [express] PUT /api/admin/users/1 403 in 4ms :: {"error":"Insufficient permissions"}
1:12:08 AM [express] PUT /api/admin/users/1 403 in 38ms :: {"error":"Insufficient permissions"}
1:12:11 AM [express] GET /api/admin/purge/stats 403 in 6ms :: {"error":"Insufficient permissions"}
1:12:11 AM [express] GET /api/admin/backup/stats 403 in 6ms :: {"error":"Insufficient permissions"}
@@ -1,124 +0,0 @@
✅ Node.js 18 compatibility fix applied
file:///app/node_modules/@neondatabase/serverless/index.mjs:1345
o?t(o):n(u)},"cb"),s=new r(function(o,u){n=o,t=u}).catch(o=>{throw Error.captureStackTrace(
^
␍ErrorEvent {
[Symbol(kTarget)]: WebSocket {
_events: [Object: null prototype] {
error: [Function: onError] {
[Symbol(kIsForOnEventAttribute)]: false,
[Symbol(kListener)]: [Function (anonymous)]
},
message: [Function: onMessage] {
[Symbol(kIsForOnEventAttribute)]: false,
[Symbol(kListener)]: [Function (anonymous)]
},
close: [Function: onClose] {
[Symbol(kIsForOnEventAttribute)]: false,
[Symbol(kListener)]: [Function (anonymous)]
},
open: [Function: onOpen] {
[Symbol(kIsForOnEventAttribute)]: false,
[Symbol(kListener)]: [Function: handleWebSocketOpen]
}
},
_eventsCount: 4,
_maxListeners: undefined,
_binaryType: 'arraybuffer',
_closeCode: 1006,
_closeFrameReceived: false,
_closeFrameSent: false,
_closeMessage: Buffer(0) [Uint8Array] [],
_closeTimer: null,
_errorEmitted: true,
_extensions: {},
_paused: false,
_protocol: '',
_readyState: 3,
_receiver: null,
_sender: null,
_socket: null,
_bufferedAmount: 0,
_isServer: false,
_redirects: 0,
_autoPong: true,
_url: 'wss://regisflow-db/v2',
_req: null,
[Symbol(kCapture)]: false
},
[Symbol(kType)]: 'error',
[Symbol(kError)]: Error: connect ECONNREFUSED 172.22.0.2:443
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1555:16) {
errno: -111,
code: 'ECONNREFUSED',
syscall: 'connect',
address: '172.22.0.2',
port: 443
},
[Symbol(kMessage)]: 'connect ECONNREFUSED 172.22.0.2:443'
}
Node.js v18.20.8
@@ -1,91 +0,0 @@
at file:///app/dist/index.js:1081:5
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
Node.js v18.20.8
🚀 Démarrage de RegisFlow (mode simplifié)...
📡 Attente de la base de données...
✅ PostgreSQL prêt!
📦 Création des tables de la base de données...
Reading config file '/app/drizzle.config.ts'
Using 'pg' driver for database querying
[⣷] Pulling schema from database...
[⣯] Pulling schema from database...
[✓] Pulling schema from database...
[i] No changes detected
✅ Tables créées avec succès
✅ Base de données configurée
🎯 Démarrage de RegisFlow...
✅ Node.js 18 compatibility fix applied
file:///app/dist/index.js:1032
throw new Error(
^
Error: Could not find the build directory: /app/public, make sure to build the client first
at serveStatic (file:///app/dist/index.js:1032:11)
at file:///app/dist/index.js:1081:5
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
Node.js v18.20.8
🚀 Démarrage de RegisFlow (mode simplifié)...
📡 Attente de la base de données...
✅ PostgreSQL prêt!
📦 Création des tables de la base de données...
Reading config file '/app/drizzle.config.ts'
Using 'pg' driver for database querying
[⣷] Pulling schema from database...
[⣯] Pulling schema from database...
[✓] Pulling schema from database...
[i] No changes detected
✅ Tables créées avec succès
✅ Base de données configurée
🎯 Démarrage de RegisFlow...
✅ Node.js 18 compatibility fix applied
file:///app/dist/index.js:1032
throw new Error(
^
Error: Could not find the build directory: /app/public, make sure to build the client first
at serveStatic (file:///app/dist/index.js:1032:11)
at file:///app/dist/index.js:1081:5
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
Node.js v18.20.8
🚀 Démarrage de RegisFlow (mode simplifié)...
📡 Attente de la base de données...
✅ PostgreSQL prêt!
📦 Création des tables de la base de données...
Reading config file '/app/drizzle.config.ts'
Using 'pg' driver for database querying
[⣷] Pulling schema from database...
[⣯] Pulling schema from database...
[✓] Pulling schema from database...
[i] No changes detected
✅ Tables créées avec succès
✅ Base de données configurée
🎯 Démarrage de RegisFlow...
✅ Node.js 18 compatibility fix applied
file:///app/dist/index.js:1032
throw new Error(
^
Error: Could not find the build directory: /app/public, make sure to build the client first
at serveStatic (file:///app/dist/index.js:1032:11)
at file:///app/dist/index.js:1081:5
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
Node.js v18.20.8
🚀 Démarrage de RegisFlow (mode simplifié)...
📡 Attente de la base de données...
✅ PostgreSQL prêt!
📦 Création des tables de la base de données...
Reading config file '/app/drizzle.config.ts'
Using 'pg' driver for database querying
[⣷] Pulling schema from database...
[⣯] Pulling schema from database...
[✓] Pulling schema from database...
[i] No changes detected
✅ Tables créées avec succès
✅ Base de données configurée
🎯 Démarrage de RegisFlow...
✅ Node.js 18 compatibility fix applied
file:///app/dist/index.js:1032
throw new Error(
^
Error: Could not find the build directory: /app/public, make sure to build the client first
at serveStatic (file:///app/dist/index.js:1032:11)
at file:///app/dist/index.js:1081:5
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
Node.js v18.20.8
@@ -1,95 +0,0 @@
at async DatabaseStorage.getAllUsers (file:///app/dist/index.js:187:12)
at async DatabaseStorage.initializeDefaults (file:///app/dist/index.js:258:27)
at async registerRoutes (file:///app/dist/index.js:510:22)
at async file:///app/dist/index.js:1071:18 {
length: 105,
severity: 'ERROR',
code: '42P01',
detail: undefined,
hint: undefined,
position: '139',
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: undefined,
table: undefined,
column: undefined,
dataType: undefined,
constraint: undefined,
file: 'parse_relation.c',
line: '1392',
routine: 'parserOpenTable'
}
Node.js v18.20.8
🚀 Démarrage de RegisFlow (mode simplifié)...
📡 Attente de la base de données...
✅ PostgreSQL prêt!
✅ Base de données configurée
🎯 Démarrage de RegisFlow...
✅ Node.js 18 compatibility fix applied
/app/node_modules/pg-pool/index.js:45
Error.captureStackTrace(err)
^
error: relation "users" does not exist
at /app/node_modules/pg-pool/index.js:45:11
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async file:///app/node_modules/drizzle-orm/node-postgres/session.js:83:22
at async DatabaseStorage.getAllUsers (file:///app/dist/index.js:187:12)
at async DatabaseStorage.initializeDefaults (file:///app/dist/index.js:258:27)
at async registerRoutes (file:///app/dist/index.js:510:22)
at async file:///app/dist/index.js:1071:18 {
length: 105,
severity: 'ERROR',
code: '42P01',
detail: undefined,
hint: undefined,
position: '139',
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: undefined,
table: undefined,
column: undefined,
dataType: undefined,
constraint: undefined,
file: 'parse_relation.c',
line: '1392',
routine: 'parserOpenTable'
}
Node.js v18.20.8
🚀 Démarrage de RegisFlow (mode simplifié)...
📡 Attente de la base de données...
✅ PostgreSQL prêt!
✅ Base de données configurée
🎯 Démarrage de RegisFlow...
✅ Node.js 18 compatibility fix applied
/app/node_modules/pg-pool/index.js:45
Error.captureStackTrace(err)
^
error: relation "users" does not exist
at /app/node_modules/pg-pool/index.js:45:11
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async file:///app/node_modules/drizzle-orm/node-postgres/session.js:83:22
at async DatabaseStorage.getAllUsers (file:///app/dist/index.js:187:12)
at async DatabaseStorage.initializeDefaults (file:///app/dist/index.js:258:27)
at async registerRoutes (file:///app/dist/index.js:510:22)
at async file:///app/dist/index.js:1071:18 {
length: 105,
severity: 'ERROR',
code: '42P01',
detail: undefined,
hint: undefined,
position: '139',
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: undefined,
table: undefined,
column: undefined,
dataType: undefined,
constraint: undefined,
file: 'parse_relation.c',
line: '1392',
routine: 'parserOpenTable'
}
Node.js v18.20.8
Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

@@ -1,151 +0,0 @@
{
"timestamp": "2025-07-09T19:27:47.907Z",
"version": "1.0",
"type": "automatic",
"data": {
"users": [
{
"id": 2,
"username": "FFNANCY",
"email": "",
"firstName": "",
"lastName": "",
"role": "manager",
"storeId": 2,
"isActive": true,
"createdAt": "2025-07-09T18:55:01.413Z",
"updatedAt": "2025-07-09T18:55:01.413Z"
},
{
"id": 1,
"username": "admin",
"email": "admin@example.com",
"firstName": "Administrateur",
"lastName": "Principal",
"role": "admin",
"storeId": 1,
"isActive": true,
"createdAt": "2025-07-09T18:37:53.865Z",
"updatedAt": "2025-07-09T18:37:53.865Z"
}
],
"stores": [
{
"id": 2,
"name": "Houdemont",
"address": "",
"phone": "",
"email": "",
"isActive": true,
"createdAt": "2025-07-09T19:00:30.782Z",
"updatedAt": "2025-07-09T19:00:30.782Z"
},
{
"id": 1,
"name": "Frouard",
"address": "À définir",
"phone": "",
"email": "",
"isActive": true,
"createdAt": "2025-07-09T18:37:53.432Z",
"updatedAt": "2025-07-09T18:37:53.432Z"
}
],
"sales": [
{
"id": 5,
"storeId": 2,
"userId": 2,
"timestamp": "2025-07-09T19:16:46.797Z",
"vendeur": "Moi",
"dateVente": "2025-07-09",
"typeArticle": "Fusée",
"categorie": "F2",
"quantite": 10,
"gencode": "3660092323745",
"nom": " ASSOCIATION GRAND AIR",
"prenom": "Anne-Laure",
"dateNaissance": "2025-06-03",
"lieuNaissance": "Bar le duc",
"typeIdentite": "Passeport",
"numeroIdentite": "qsdfqsdgc23445",
"autoriteDelivrance": "Frouard",
"dateDelivrance": "2025-07-01",
"photoRecto": null,
"photoVerso": null
},
{
"id": 2,
"storeId": 2,
"userId": 1,
"timestamp": "2025-07-09T19:07:15.650Z",
"vendeur": "Moi",
"dateVente": "2025-07-09",
"typeArticle": "Pétard aérien",
"categorie": "F3",
"quantite": 1,
"gencode": "3660092323745",
"nom": "SCHAL",
"prenom": "Michaël",
"dateNaissance": "2025-07-02",
"lieuNaissance": "Bar le duc",
"typeIdentite": "CNI",
"numeroIdentite": "qsdfqsdgc23445",
"autoriteDelivrance": "Frouard",
"dateDelivrance": "2025-07-01",
"photoRecto": null,
"photoVerso": null
},
{
"id": 1,
"storeId": 2,
"userId": 1,
"timestamp": "2025-07-09T19:05:20.904Z",
"vendeur": "Moi",
"dateVente": "2025-07-09",
"typeArticle": "Pétard aérien",
"categorie": "F3",
"quantite": 1,
"gencode": "3660092323745",
"nom": "SCHAL",
"prenom": "Michaël",
"dateNaissance": "2025-07-02",
"lieuNaissance": "Bar le duc",
"typeIdentite": "CNI",
"numeroIdentite": "qsdfqsdgc23445",
"autoriteDelivrance": "Frouard",
"dateDelivrance": "2025-07-01",
"photoRecto": null,
"photoVerso": null
},
{
"id": 4,
"storeId": 1,
"userId": 1,
"timestamp": "2025-07-09T19:11:36.505Z",
"vendeur": "Moi",
"dateVente": "2025-07-09",
"typeArticle": "Batterie",
"categorie": "F3",
"quantite": 1,
"gencode": "3660092323745",
"nom": "SCHAL",
"prenom": "Michaël",
"dateNaissance": "2025-07-18",
"lieuNaissance": "Bar le duc",
"typeIdentite": "CNI",
"numeroIdentite": "qsdfqsdgc23445",
"autoriteDelivrance": "Frouard",
"dateDelivrance": "2025-07-01",
"photoRecto": null,
"photoVerso": null
}
]
},
"metadata": {
"totalUsers": 2,
"totalStores": 2,
"totalSales": 4,
"exportedBy": "system-auto-backup"
}
}
@@ -1,151 +0,0 @@
{
"timestamp": "2025-07-09T19:28:49.721Z",
"version": "1.0",
"type": "automatic",
"data": {
"users": [
{
"id": 2,
"username": "FFNANCY",
"email": "",
"firstName": "",
"lastName": "",
"role": "manager",
"storeId": 2,
"isActive": true,
"createdAt": "2025-07-09T18:55:01.413Z",
"updatedAt": "2025-07-09T18:55:01.413Z"
},
{
"id": 1,
"username": "admin",
"email": "admin@example.com",
"firstName": "Administrateur",
"lastName": "Principal",
"role": "admin",
"storeId": 1,
"isActive": true,
"createdAt": "2025-07-09T18:37:53.865Z",
"updatedAt": "2025-07-09T18:37:53.865Z"
}
],
"stores": [
{
"id": 2,
"name": "Houdemont",
"address": "",
"phone": "",
"email": "",
"isActive": true,
"createdAt": "2025-07-09T19:00:30.782Z",
"updatedAt": "2025-07-09T19:00:30.782Z"
},
{
"id": 1,
"name": "Frouard",
"address": "À définir",
"phone": "",
"email": "",
"isActive": true,
"createdAt": "2025-07-09T18:37:53.432Z",
"updatedAt": "2025-07-09T18:37:53.432Z"
}
],
"sales": [
{
"id": 5,
"storeId": 2,
"userId": 2,
"timestamp": "2025-07-09T19:16:46.797Z",
"vendeur": "Moi",
"dateVente": "2025-07-09",
"typeArticle": "Fusée",
"categorie": "F2",
"quantite": 10,
"gencode": "3660092323745",
"nom": " ASSOCIATION GRAND AIR",
"prenom": "Anne-Laure",
"dateNaissance": "2025-06-03",
"lieuNaissance": "Bar le duc",
"typeIdentite": "Passeport",
"numeroIdentite": "qsdfqsdgc23445",
"autoriteDelivrance": "Frouard",
"dateDelivrance": "2025-07-01",
"photoRecto": null,
"photoVerso": null
},
{
"id": 2,
"storeId": 2,
"userId": 1,
"timestamp": "2025-07-09T19:07:15.650Z",
"vendeur": "Moi",
"dateVente": "2025-07-09",
"typeArticle": "Pétard aérien",
"categorie": "F3",
"quantite": 1,
"gencode": "3660092323745",
"nom": "SCHAL",
"prenom": "Michaël",
"dateNaissance": "2025-07-02",
"lieuNaissance": "Bar le duc",
"typeIdentite": "CNI",
"numeroIdentite": "qsdfqsdgc23445",
"autoriteDelivrance": "Frouard",
"dateDelivrance": "2025-07-01",
"photoRecto": null,
"photoVerso": null
},
{
"id": 1,
"storeId": 2,
"userId": 1,
"timestamp": "2025-07-09T19:05:20.904Z",
"vendeur": "Moi",
"dateVente": "2025-07-09",
"typeArticle": "Pétard aérien",
"categorie": "F3",
"quantite": 1,
"gencode": "3660092323745",
"nom": "SCHAL",
"prenom": "Michaël",
"dateNaissance": "2025-07-02",
"lieuNaissance": "Bar le duc",
"typeIdentite": "CNI",
"numeroIdentite": "qsdfqsdgc23445",
"autoriteDelivrance": "Frouard",
"dateDelivrance": "2025-07-01",
"photoRecto": null,
"photoVerso": null
},
{
"id": 4,
"storeId": 1,
"userId": 1,
"timestamp": "2025-07-09T19:11:36.505Z",
"vendeur": "Moi",
"dateVente": "2025-07-09",
"typeArticle": "Batterie",
"categorie": "F3",
"quantite": 1,
"gencode": "3660092323745",
"nom": "SCHAL",
"prenom": "Michaël",
"dateNaissance": "2025-07-18",
"lieuNaissance": "Bar le duc",
"typeIdentite": "CNI",
"numeroIdentite": "qsdfqsdgc23445",
"autoriteDelivrance": "Frouard",
"dateDelivrance": "2025-07-01",
"photoRecto": null,
"photoVerso": null
}
]
},
"metadata": {
"totalUsers": 2,
"totalStores": 2,
"totalSales": 4,
"exportedBy": "system-auto-backup"
}
}
@@ -1,155 +0,0 @@
{
"timestamp": "2025-07-09T22:00:00.184Z",
"version": "1.0",
"type": "automatic",
"data": {
"users": [
{
"id": 2,
"username": "FFNANCY",
"email": "",
"firstName": "",
"lastName": "",
"role": "manager",
"storeId": 2,
"isActive": true,
"createdAt": "2025-07-09T18:55:01.413Z",
"updatedAt": "2025-07-09T18:55:01.413Z"
},
{
"id": 1,
"username": "admin",
"email": "admin@example.com",
"firstName": "Administrateur",
"lastName": "Principal",
"role": "admin",
"storeId": 1,
"isActive": true,
"createdAt": "2025-07-09T18:37:53.865Z",
"updatedAt": "2025-07-09T18:37:53.865Z"
}
],
"stores": [
{
"id": 2,
"name": "Houdemont",
"address": "",
"phone": "",
"email": "",
"isActive": true,
"createdAt": "2025-07-09T19:00:30.782Z",
"updatedAt": "2025-07-09T19:00:30.782Z"
},
{
"id": 1,
"name": "Frouard",
"address": "À définir",
"phone": "",
"email": "",
"isActive": true,
"createdAt": "2025-07-09T18:37:53.432Z",
"updatedAt": "2025-07-09T18:37:53.432Z"
}
],
"sales": [
{
"id": 5,
"storeId": 2,
"userId": 2,
"timestamp": "2025-07-09T19:16:46.797Z",
"vendeur": "Moi",
"dateVente": "2025-07-09",
"typeArticle": "Fusée",
"categorie": "F2",
"quantite": 10,
"gencode": "3660092323745",
"nom": " ASSOCIATION GRAND AIR",
"prenom": "Anne-Laure",
"dateNaissance": "2025-06-03",
"lieuNaissance": "Bar le duc",
"modePaiement": "Espèce",
"typeIdentite": "Passeport",
"numeroIdentite": "qsdfqsdgc23445",
"autoriteDelivrance": "Frouard",
"dateDelivrance": "2025-07-01",
"photoRecto": null,
"photoVerso": null
},
{
"id": 2,
"storeId": 2,
"userId": 1,
"timestamp": "2025-07-09T19:07:15.650Z",
"vendeur": "Moi",
"dateVente": "2025-07-09",
"typeArticle": "Pétard aérien",
"categorie": "F3",
"quantite": 1,
"gencode": "3660092323745",
"nom": "SCHAL",
"prenom": "Michaël",
"dateNaissance": "2025-07-02",
"lieuNaissance": "Bar le duc",
"modePaiement": "Espèce",
"typeIdentite": "CNI",
"numeroIdentite": "qsdfqsdgc23445",
"autoriteDelivrance": "Frouard",
"dateDelivrance": "2025-07-01",
"photoRecto": null,
"photoVerso": null
},
{
"id": 1,
"storeId": 2,
"userId": 1,
"timestamp": "2025-07-09T19:05:20.904Z",
"vendeur": "Moi",
"dateVente": "2025-07-09",
"typeArticle": "Pétard aérien",
"categorie": "F3",
"quantite": 1,
"gencode": "3660092323745",
"nom": "SCHAL",
"prenom": "Michaël",
"dateNaissance": "2025-07-02",
"lieuNaissance": "Bar le duc",
"modePaiement": "Espèce",
"typeIdentite": "CNI",
"numeroIdentite": "qsdfqsdgc23445",
"autoriteDelivrance": "Frouard",
"dateDelivrance": "2025-07-01",
"photoRecto": null,
"photoVerso": null
},
{
"id": 4,
"storeId": 1,
"userId": 1,
"timestamp": "2025-07-09T19:11:36.505Z",
"vendeur": "Moi",
"dateVente": "2025-07-09",
"typeArticle": "Batterie",
"categorie": "F3",
"quantite": 1,
"gencode": "3660092323745",
"nom": "SCHAL",
"prenom": "Michaël",
"dateNaissance": "2025-07-18",
"lieuNaissance": "Bar le duc",
"modePaiement": "Espèce",
"typeIdentite": "CNI",
"numeroIdentite": "qsdfqsdgc23445",
"autoriteDelivrance": "Frouard",
"dateDelivrance": "2025-07-01",
"photoRecto": null,
"photoVerso": null
}
]
},
"metadata": {
"totalUsers": 2,
"totalStores": 2,
"totalSales": 4,
"exportedBy": "system-auto-backup"
}
}
@@ -1,209 +0,0 @@
{
"timestamp": "2025-07-10T10:00:00.591Z",
"version": "1.0",
"type": "automatic",
"data": {
"users": [
{
"id": 5,
"username": "ff579",
"email": null,
"firstName": "",
"lastName": "",
"role": "employee",
"storeId": 2,
"isActive": true,
"createdAt": "2025-07-10T09:48:22.256Z",
"updatedAt": "2025-07-10T09:48:22.256Z"
},
{
"id": 4,
"username": "ff292",
"email": null,
"firstName": "",
"lastName": "",
"role": "employee",
"storeId": 1,
"isActive": true,
"createdAt": "2025-07-10T09:48:06.549Z",
"updatedAt": "2025-07-10T09:48:06.549Z"
},
{
"id": 3,
"username": "gael",
"email": null,
"firstName": "",
"lastName": "",
"role": "administrator",
"storeId": null,
"isActive": true,
"createdAt": "2025-07-10T08:47:04.063Z",
"updatedAt": "2025-07-10T08:47:04.063Z"
},
{
"id": 2,
"username": "FFNANCY",
"email": "michaelschal@gmail.com",
"firstName": "",
"lastName": "",
"role": "manager",
"storeId": 1,
"isActive": true,
"createdAt": "2025-07-09T18:55:01.413Z",
"updatedAt": "2025-07-09T18:55:01.413Z"
},
{
"id": 1,
"username": "admin",
"email": "michaelschal@ffest.fr",
"firstName": "Administrateur",
"lastName": "Principal",
"role": "admin",
"storeId": 1,
"isActive": true,
"createdAt": "2025-07-09T18:37:53.865Z",
"updatedAt": "2025-07-09T18:37:53.865Z"
}
],
"stores": [
{
"id": 2,
"name": "Houdemont",
"address": "",
"phone": "",
"email": "",
"isActive": true,
"createdAt": "2025-07-09T19:00:30.782Z",
"updatedAt": "2025-07-09T19:00:30.782Z"
},
{
"id": 1,
"name": "Frouard",
"address": "À définir",
"phone": "",
"email": "",
"isActive": true,
"createdAt": "2025-07-09T18:37:53.432Z",
"updatedAt": "2025-07-09T18:37:53.432Z"
}
],
"sales": [
{
"id": 5,
"storeId": 2,
"userId": 2,
"timestamp": "2025-07-09T19:16:46.797Z",
"vendeur": "Moi",
"typeArticle": "Fusée",
"categorie": "F2",
"quantite": 10,
"gencode": "3660092323745",
"nom": " ASSOCIATION GRAND AIR",
"prenom": "Anne-Laure",
"dateNaissance": "2025-06-03",
"lieuNaissance": "Bar le duc",
"modePaiement": "Espèce",
"typeIdentite": "Passeport",
"numeroIdentite": "qsdfqsdgc23445",
"autoriteDelivrance": "Frouard",
"dateDelivrance": "2025-07-01",
"photoRecto": null,
"photoVerso": null
},
{
"id": 2,
"storeId": 2,
"userId": 1,
"timestamp": "2025-07-09T19:07:15.650Z",
"vendeur": "Moi",
"typeArticle": "Pétard aérien",
"categorie": "F3",
"quantite": 1,
"gencode": "3660092323745",
"nom": "SCHAL",
"prenom": "Michaël",
"dateNaissance": "2025-07-02",
"lieuNaissance": "Bar le duc",
"modePaiement": "Espèce",
"typeIdentite": "CNI",
"numeroIdentite": "qsdfqsdgc23445",
"autoriteDelivrance": "Frouard",
"dateDelivrance": "2025-07-01",
"photoRecto": null,
"photoVerso": null
},
{
"id": 1,
"storeId": 2,
"userId": 1,
"timestamp": "2025-07-09T19:05:20.904Z",
"vendeur": "Moi",
"typeArticle": "Pétard aérien",
"categorie": "F3",
"quantite": 1,
"gencode": "3660092323745",
"nom": "SCHAL",
"prenom": "Michaël",
"dateNaissance": "2025-07-02",
"lieuNaissance": "Bar le duc",
"modePaiement": "Espèce",
"typeIdentite": "CNI",
"numeroIdentite": "qsdfqsdgc23445",
"autoriteDelivrance": "Frouard",
"dateDelivrance": "2025-07-01",
"photoRecto": null,
"photoVerso": null
},
{
"id": 6,
"storeId": 1,
"userId": 1,
"timestamp": "2025-07-10T00:08:19.097Z",
"vendeur": "Moi",
"typeArticle": "Chandelle romaine",
"categorie": "F2",
"quantite": 1,
"gencode": "3660092323745",
"nom": "SCHAL",
"prenom": "Anne-Laure",
"dateNaissance": "2018-02-10",
"lieuNaissance": "Bar le duc",
"modePaiement": "Espèce",
"typeIdentite": "Passeport",
"numeroIdentite": "qsdfqsdgc23445",
"autoriteDelivrance": "Frouard",
"dateDelivrance": "2025-07-01",
"photoRecto": null,
"photoVerso": null
},
{
"id": 4,
"storeId": 1,
"userId": 1,
"timestamp": "2025-07-09T19:11:36.505Z",
"vendeur": "Moi",
"typeArticle": "Batterie",
"categorie": "F3",
"quantite": 1,
"gencode": "3660092323745",
"nom": "SCHAL",
"prenom": "Michaël",
"dateNaissance": "2025-07-18",
"lieuNaissance": "Bar le duc",
"modePaiement": "Espèce",
"typeIdentite": "CNI",
"numeroIdentite": "qsdfqsdgc23445",
"autoriteDelivrance": "Frouard",
"dateDelivrance": "2025-07-01",
"photoRecto": null,
"photoVerso": null
}
]
},
"metadata": {
"totalUsers": 5,
"totalStores": 2,
"totalSales": 5,
"exportedBy": "system-auto-backup"
}
}
@@ -1,209 +0,0 @@
{
"timestamp": "2025-07-11T10:00:00.586Z",
"version": "1.0",
"type": "automatic",
"data": {
"users": [
{
"id": 5,
"username": "ff579",
"email": null,
"firstName": "",
"lastName": "",
"role": "employee",
"storeId": 2,
"isActive": true,
"createdAt": "2025-07-10T09:48:22.256Z",
"updatedAt": "2025-07-10T09:48:22.256Z"
},
{
"id": 4,
"username": "ff292",
"email": null,
"firstName": "",
"lastName": "",
"role": "employee",
"storeId": 1,
"isActive": true,
"createdAt": "2025-07-10T09:48:06.549Z",
"updatedAt": "2025-07-10T09:48:06.549Z"
},
{
"id": 3,
"username": "gael",
"email": null,
"firstName": "",
"lastName": "",
"role": "administrator",
"storeId": null,
"isActive": true,
"createdAt": "2025-07-10T08:47:04.063Z",
"updatedAt": "2025-07-10T08:47:04.063Z"
},
{
"id": 2,
"username": "FFNANCY",
"email": "michaelschal@gmail.com",
"firstName": "",
"lastName": "",
"role": "manager",
"storeId": 1,
"isActive": true,
"createdAt": "2025-07-09T18:55:01.413Z",
"updatedAt": "2025-07-09T18:55:01.413Z"
},
{
"id": 1,
"username": "admin",
"email": "michaelschal@ffest.fr",
"firstName": "Administrateur",
"lastName": "Principal",
"role": "admin",
"storeId": 1,
"isActive": true,
"createdAt": "2025-07-09T18:37:53.865Z",
"updatedAt": "2025-07-09T18:37:53.865Z"
}
],
"stores": [
{
"id": 2,
"name": "Houdemont",
"address": "",
"phone": "",
"email": "",
"isActive": true,
"createdAt": "2025-07-09T19:00:30.782Z",
"updatedAt": "2025-07-09T19:00:30.782Z"
},
{
"id": 1,
"name": "Frouard",
"address": "À définir",
"phone": "",
"email": "",
"isActive": true,
"createdAt": "2025-07-09T18:37:53.432Z",
"updatedAt": "2025-07-09T18:37:53.432Z"
}
],
"sales": [
{
"id": 5,
"storeId": 2,
"userId": 2,
"timestamp": "2025-07-09T19:16:46.797Z",
"vendeur": "Moi",
"typeArticle": "Fusée",
"categorie": "F2",
"quantite": 10,
"gencode": "3660092323745",
"nom": " ASSOCIATION GRAND AIR",
"prenom": "Anne-Laure",
"dateNaissance": "2025-06-03",
"lieuNaissance": "Bar le duc",
"modePaiement": "Espèce",
"typeIdentite": "Passeport",
"numeroIdentite": "qsdfqsdgc23445",
"autoriteDelivrance": "Frouard",
"dateDelivrance": "2025-07-01",
"photoRecto": null,
"photoVerso": null
},
{
"id": 2,
"storeId": 2,
"userId": 1,
"timestamp": "2025-07-09T19:07:15.650Z",
"vendeur": "Moi",
"typeArticle": "Pétard aérien",
"categorie": "F3",
"quantite": 1,
"gencode": "3660092323745",
"nom": "SCHAL",
"prenom": "Michaël",
"dateNaissance": "2025-07-02",
"lieuNaissance": "Bar le duc",
"modePaiement": "Espèce",
"typeIdentite": "CNI",
"numeroIdentite": "qsdfqsdgc23445",
"autoriteDelivrance": "Frouard",
"dateDelivrance": "2025-07-01",
"photoRecto": null,
"photoVerso": null
},
{
"id": 1,
"storeId": 2,
"userId": 1,
"timestamp": "2025-07-09T19:05:20.904Z",
"vendeur": "Moi",
"typeArticle": "Pétard aérien",
"categorie": "F3",
"quantite": 1,
"gencode": "3660092323745",
"nom": "SCHAL",
"prenom": "Michaël",
"dateNaissance": "2025-07-02",
"lieuNaissance": "Bar le duc",
"modePaiement": "Espèce",
"typeIdentite": "CNI",
"numeroIdentite": "qsdfqsdgc23445",
"autoriteDelivrance": "Frouard",
"dateDelivrance": "2025-07-01",
"photoRecto": null,
"photoVerso": null
},
{
"id": 6,
"storeId": 1,
"userId": 1,
"timestamp": "2025-07-10T00:08:19.097Z",
"vendeur": "Moi",
"typeArticle": "Chandelle romaine",
"categorie": "F2",
"quantite": 1,
"gencode": "3660092323745",
"nom": "SCHAL",
"prenom": "Anne-Laure",
"dateNaissance": "2018-02-10",
"lieuNaissance": "Bar le duc",
"modePaiement": "Espèce",
"typeIdentite": "Passeport",
"numeroIdentite": "qsdfqsdgc23445",
"autoriteDelivrance": "Frouard",
"dateDelivrance": "2025-07-01",
"photoRecto": null,
"photoVerso": null
},
{
"id": 4,
"storeId": 1,
"userId": 1,
"timestamp": "2025-07-09T19:11:36.505Z",
"vendeur": "Moi",
"typeArticle": "Batterie",
"categorie": "F3",
"quantite": 1,
"gencode": "3660092323745",
"nom": "SCHAL",
"prenom": "Michaël",
"dateNaissance": "2025-07-18",
"lieuNaissance": "Bar le duc",
"modePaiement": "Espèce",
"typeIdentite": "CNI",
"numeroIdentite": "qsdfqsdgc23445",
"autoriteDelivrance": "Frouard",
"dateDelivrance": "2025-07-01",
"photoRecto": null,
"photoVerso": null
}
]
},
"metadata": {
"totalUsers": 5,
"totalStores": 2,
"totalSales": 5,
"exportedBy": "system-auto-backup"
}
}
@@ -0,0 +1,375 @@
{
"timestamp": "2025-07-11T19:05:01.267Z",
"version": "1.0",
"type": "automatic",
"data": {
"users": [
{
"id": 5,
"username": "ff579",
"email": null,
"firstName": "",
"lastName": "",
"role": "employee",
"storeId": 2,
"isActive": true,
"createdAt": "2025-07-10T09:48:22.256Z",
"updatedAt": "2025-07-10T09:48:22.256Z"
},
{
"id": 4,
"username": "ff292",
"email": null,
"firstName": "",
"lastName": "",
"role": "employee",
"storeId": 1,
"isActive": true,
"createdAt": "2025-07-10T09:48:06.549Z",
"updatedAt": "2025-07-10T09:48:06.549Z"
},
{
"id": 3,
"username": "gael",
"email": null,
"firstName": "",
"lastName": "",
"role": "administrator",
"storeId": null,
"isActive": true,
"createdAt": "2025-07-10T08:47:04.063Z",
"updatedAt": "2025-07-10T08:47:04.063Z"
},
{
"id": 2,
"username": "FFNANCY",
"email": "michaelschal@gmail.com",
"firstName": "",
"lastName": "",
"role": "manager",
"storeId": 1,
"isActive": true,
"createdAt": "2025-07-09T18:55:01.413Z",
"updatedAt": "2025-07-09T18:55:01.413Z"
},
{
"id": 1,
"username": "admin",
"email": "michaelschal@ffest.fr",
"firstName": "Administrateur",
"lastName": "Principal",
"role": "admin",
"storeId": 1,
"isActive": true,
"createdAt": "2025-07-09T18:37:53.865Z",
"updatedAt": "2025-07-09T18:37:53.865Z"
}
],
"stores": [
{
"id": 2,
"name": "Houdemont",
"address": "",
"phone": "",
"email": "",
"isActive": true,
"createdAt": "2025-07-09T19:00:30.782Z",
"updatedAt": "2025-07-09T19:00:30.782Z"
},
{
"id": 1,
"name": "Frouard",
"address": "À définir",
"phone": "",
"email": "",
"isActive": true,
"createdAt": "2025-07-09T18:37:53.432Z",
"updatedAt": "2025-07-09T18:37:53.432Z"
}
],
"sales": [
{
"id": 8,
"storeId": 2,
"userId": 1,
"timestamp": "2025-07-11T18:27:55.231Z",
"vendeur": "Test Vendeur",
"typeArticle": "Batterie Test",
"categorie": "F2",
"quantite": 1,
"gencode": "1234567890123",
"nom": "DUPONT",
"prenom": "Jean",
"dateNaissance": "01/01/1980",
"lieuNaissance": "Paris",
"modePaiement": "Carte bancaire",
"typeIdentite": "Carte d'identité",
"numeroIdentite": "ABC123456",
"autoriteDelivrance": "Préfecture de Paris",
"dateDelivrance": "01/01/2020",
"photo_recto": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==",
"photo_verso": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==",
"photo_ticket": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=="
},
{
"id": 7,
"storeId": 2,
"userId": 1,
"timestamp": "2025-07-11T15:36:32.194Z",
"vendeur": "Moi",
"typeArticle": "Batterie",
"categorie": "F3",
"quantite": 1,
"gencode": "3660092323745",
"nom": "SCHAL",
"prenom": "Michaël",
"dateNaissance": "1998-02-05",
"lieuNaissance": "Bar le duc",
"modePaiement": "Espèce",
"typeIdentite": "CNI",
"numeroIdentite": "qsdfqsdgc23445",
"autoriteDelivrance": "Frouard",
"dateDelivrance": "2025-07-11",
"photo_recto": null,
"photo_verso": null,
"photo_ticket": null
},
{
"id": 5,
"storeId": 2,
"userId": 2,
"timestamp": "2025-07-09T19:16:46.797Z",
"vendeur": "Moi",
"typeArticle": "Fusée",
"categorie": "F2",
"quantite": 10,
"gencode": "3660092323745",
"nom": " ASSOCIATION GRAND AIR",
"prenom": "Anne-Laure",
"dateNaissance": "2025-06-03",
"lieuNaissance": "Bar le duc",
"modePaiement": "Espèce",
"typeIdentite": "Passeport",
"numeroIdentite": "qsdfqsdgc23445",
"autoriteDelivrance": "Frouard",
"dateDelivrance": "2025-07-01",
"photo_recto": null,
"photo_verso": null,
"photo_ticket": null
},
{
"id": 2,
"storeId": 2,
"userId": 1,
"timestamp": "2025-07-09T19:07:15.650Z",
"vendeur": "Moi",
"typeArticle": "Pétard aérien",
"categorie": "F3",
"quantite": 1,
"gencode": "3660092323745",
"nom": "SCHAL",
"prenom": "Michaël",
"dateNaissance": "2025-07-02",
"lieuNaissance": "Bar le duc",
"modePaiement": "Espèce",
"typeIdentite": "CNI",
"numeroIdentite": "qsdfqsdgc23445",
"autoriteDelivrance": "Frouard",
"dateDelivrance": "2025-07-01",
"photo_recto": null,
"photo_verso": null,
"photo_ticket": null
},
{
"id": 1,
"storeId": 2,
"userId": 1,
"timestamp": "2025-07-09T19:05:20.904Z",
"vendeur": "Moi",
"typeArticle": "Pétard aérien",
"categorie": "F3",
"quantite": 1,
"gencode": "3660092323745",
"nom": "SCHAL",
"prenom": "Michaël",
"dateNaissance": "2025-07-02",
"lieuNaissance": "Bar le duc",
"modePaiement": "Espèce",
"typeIdentite": "CNI",
"numeroIdentite": "qsdfqsdgc23445",
"autoriteDelivrance": "Frouard",
"dateDelivrance": "2025-07-01",
"photo_recto": null,
"photo_verso": null,
"photo_ticket": null
},
{
"id": 13,
"storeId": 1,
"userId": 1,
"timestamp": "2025-07-11T19:02:01.423Z",
"vendeur": "Production Test",
"typeArticle": "Chandelle",
"categorie": "F2",
"quantite": 1,
"gencode": "1234567890999",
"nom": "PROD",
"prenom": "Test",
"dateNaissance": "1990-01-01",
"lieuNaissance": "Test",
"modePaiement": "Espèce",
"typeIdentite": "Passeport",
"numeroIdentite": "123456789",
"autoriteDelivrance": "Test",
"dateDelivrance": "2025-01-01",
"photo_recto": null,
"photo_verso": null,
"photo_ticket": "data:image/jpeg;base64,PRODUCTION_TEST_TICKET"
},
{
"id": 12,
"storeId": 1,
"userId": 1,
"timestamp": "2025-07-11T18:48:31.159Z",
"vendeur": "Test Final",
"typeArticle": "Chandelle",
"categorie": "F2",
"quantite": 1,
"gencode": "1234567890999",
"nom": "FINAL",
"prenom": "Test",
"dateNaissance": "1990-01-01",
"lieuNaissance": "Test",
"modePaiement": "Espèce",
"typeIdentite": "Passeport",
"numeroIdentite": "123456789",
"autoriteDelivrance": "Test",
"dateDelivrance": "2025-01-01",
"photo_recto": null,
"photo_verso": null,
"photo_ticket": "data:image/jpeg;base64,TICKET_TEST_FINAL"
},
{
"id": 11,
"storeId": 1,
"userId": 1,
"timestamp": "2025-07-11T18:39:03.438Z",
"vendeur": "Test Debug",
"typeArticle": "Chandelle",
"categorie": "F2",
"quantite": 1,
"gencode": "1234567890125",
"nom": "DEBUG",
"prenom": "Test",
"dateNaissance": "1990-01-01",
"lieuNaissance": "Test",
"modePaiement": "Espèce",
"typeIdentite": "Passeport",
"numeroIdentite": "123456789",
"autoriteDelivrance": "Test",
"dateDelivrance": "2025-01-01",
"photo_recto": null,
"photo_verso": null,
"photo_ticket": "data:image/jpeg;base64,TEST_TICKET_DATA"
},
{
"id": 10,
"storeId": 1,
"userId": 1,
"timestamp": "2025-07-11T18:38:45.251Z",
"vendeur": "Test Vendeur 2",
"typeArticle": "Chandelle",
"categorie": "F2",
"quantite": 1,
"gencode": "1234567890124",
"nom": "TEST2",
"prenom": "Photo2",
"dateNaissance": "1990-01-01",
"lieuNaissance": "Test",
"modePaiement": "Espèce",
"typeIdentite": "Passeport",
"numeroIdentite": "123456789",
"autoriteDelivrance": "Test",
"dateDelivrance": "2025-01-01",
"photo_recto": null,
"photo_verso": null,
"photo_ticket": null
},
{
"id": 9,
"storeId": 1,
"userId": 1,
"timestamp": "2025-07-11T18:38:21.913Z",
"vendeur": "Test Vendeur",
"typeArticle": "Chandelle",
"categorie": "F2",
"quantite": 1,
"gencode": "1234567890123",
"nom": "TEST",
"prenom": "Photo",
"dateNaissance": "1990-01-01",
"lieuNaissance": "Test",
"modePaiement": "Espèce",
"typeIdentite": "Passeport",
"numeroIdentite": "123456789",
"autoriteDelivrance": "Test",
"dateDelivrance": "2025-01-01",
"photo_recto": null,
"photo_verso": null,
"photo_ticket": null
},
{
"id": 6,
"storeId": 1,
"userId": 1,
"timestamp": "2025-07-10T00:08:19.097Z",
"vendeur": "Moi",
"typeArticle": "Chandelle romaine",
"categorie": "F2",
"quantite": 1,
"gencode": "3660092323745",
"nom": "SCHAL",
"prenom": "Anne-Laure",
"dateNaissance": "2018-02-10",
"lieuNaissance": "Bar le duc",
"modePaiement": "Espèce",
"typeIdentite": "Passeport",
"numeroIdentite": "qsdfqsdgc23445",
"autoriteDelivrance": "Frouard",
"dateDelivrance": "2025-07-01",
"photo_recto": null,
"photo_verso": null,
"photo_ticket": null
},
{
"id": 4,
"storeId": 1,
"userId": 1,
"timestamp": "2025-07-09T19:11:36.505Z",
"vendeur": "Moi",
"typeArticle": "Batterie",
"categorie": "F3",
"quantite": 1,
"gencode": "3660092323745",
"nom": "SCHAL",
"prenom": "Michaël",
"dateNaissance": "2025-07-18",
"lieuNaissance": "Bar le duc",
"modePaiement": "Espèce",
"typeIdentite": "CNI",
"numeroIdentite": "qsdfqsdgc23445",
"autoriteDelivrance": "Frouard",
"dateDelivrance": "2025-07-01",
"photo_recto": null,
"photo_verso": null,
"photo_ticket": null
}
]
},
"metadata": {
"totalUsers": 5,
"totalStores": 2,
"totalSales": 12,
"exportedBy": "system-auto-backup"
}
}
-24
View File
@@ -1,24 +0,0 @@
#!/bin/bash
# Script de construction Docker pour RegisFlow
# Ce script construit l'image Docker localement
echo "🔧 Construction de l'image Docker RegisFlow..."
# Arrêter les conteneurs existants
echo "🛑 Arrêt des conteneurs existants..."
docker-compose down
# Construire l'image avec un nom spécifique
echo "🏗️ Construction de l'image..."
docker build -t regisflow:latest .
# Vérifier que l'image a été construite
echo "📋 Vérification de l'image construite..."
docker images | grep regisflow
echo "✅ Image construite avec succès !"
echo "🐳 Vous pouvez maintenant utiliser 'regisflow:latest' dans Portainer"
echo ""
echo "Pour démarrer l'application :"
echo " docker-compose up -d"
-58
View File
@@ -1,58 +0,0 @@
#!/bin/bash
# Script de déploiement simplifié pour Portainer
# Gère tout automatiquement sans configuration manuelle
echo "🚀 Déploiement RegisFlow pour Portainer (Automatique)"
echo "===================================================="
# Créer un répertoire de déploiement temporaire
DEPLOY_DIR="/tmp/regisflow-deploy"
CURRENT_DIR=$(pwd)
echo "📁 Préparation du déploiement..."
# Nettoyer le répertoire de déploiement s'il existe
rm -rf "$DEPLOY_DIR"
mkdir -p "$DEPLOY_DIR"
# Copier tous les fichiers nécessaires
echo "📋 Copie des fichiers..."
cp -r . "$DEPLOY_DIR/"
cd "$DEPLOY_DIR"
# Utiliser le Docker Compose spécifique à Portainer
mv docker-compose-portainer.yml docker-compose.yml
echo "🔧 Construction et démarrage..."
# Arrêter les conteneurs existants
docker-compose down 2>/dev/null || true
# Construire et démarrer
docker-compose up -d --build
if [ $? -eq 0 ]; then
echo "✅ Déploiement réussi!"
echo ""
echo "📊 État des conteneurs:"
docker-compose ps
echo ""
echo "🔗 Application accessible sur: http://localhost:5000"
echo "🔐 Connexion par défaut: admin/admin123"
echo "🗄️ PostgreSQL accessible sur le port: 5433"
echo ""
echo "📋 Commandes utiles:"
echo " - Voir les logs: docker-compose logs -f"
echo " - Arrêter: docker-compose down"
echo " - Redémarrer: docker-compose restart"
echo ""
echo "📁 Fichiers de déploiement dans: $DEPLOY_DIR"
else
echo "❌ Échec du déploiement"
echo "📋 Vérifiez les logs avec: docker-compose logs"
exit 1
fi
# Retourner au répertoire original
cd "$CURRENT_DIR"
-47
View File
@@ -1,47 +0,0 @@
#!/bin/bash
# Script de déploiement pour Portainer RegisFlow
# Ce script prépare et déploie RegisFlow via Portainer
echo "🚀 Déploiement RegisFlow pour Portainer"
echo "======================================"
# Étape 1: Construire l'image Docker
echo "🔧 Étape 1: Construction de l'image Docker..."
docker build -t regisflow:latest .
if [ $? -eq 0 ]; then
echo "✅ Image construite avec succès"
else
echo "❌ Échec de la construction de l'image"
exit 1
fi
# Étape 2: Vérifier que l'image existe
echo "🔍 Étape 2: Vérification de l'image..."
docker images | grep regisflow
# Étape 3: Arrêter les conteneurs existants si ils existent
echo "🛑 Étape 3: Nettoyage des conteneurs existants..."
docker stop regisflow-app regisflow-db 2>/dev/null || true
docker rm regisflow-app regisflow-db 2>/dev/null || true
# Étape 4: Informations pour Portainer
echo ""
echo "🐳 Instructions pour Portainer:"
echo "==============================="
echo "1. Dans Portainer, allez dans 'Stacks'"
echo "2. Cliquez sur 'Add stack'"
echo "3. Donnez un nom: 'regisflow'"
echo "4. Copiez le contenu du fichier 'portainer-stack.yml'"
echo "5. Cliquez sur 'Deploy the stack'"
echo ""
echo "📝 Nom de l'image à utiliser: regisflow:latest"
echo "🔗 URL d'accès: http://votre-serveur:5000"
echo "🔐 Connexion par défaut: admin/admin123"
echo ""
echo "📋 Ports exposés:"
echo " - Application: 5000"
echo " - PostgreSQL: 5433"
echo ""
echo "✅ Prêt pour le déploiement Portainer!"
-157
View File
@@ -1,157 +0,0 @@
#!/bin/bash
# Script de déploiement automatique RegisFlow Production
# Usage: ./deploy-production.sh
set -e
echo "🚀 Déploiement RegisFlow en production"
echo "======================================="
# Couleurs pour les messages
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Fonction pour afficher les messages
log_info() {
echo -e "${BLUE}ℹ️ $1${NC}"
}
log_success() {
echo -e "${GREEN}✅ $1${NC}"
}
log_warning() {
echo -e "${YELLOW}⚠️ $1${NC}"
}
log_error() {
echo -e "${RED}❌ $1${NC}"
}
# Vérifier que Docker est installé
if ! command -v docker &> /dev/null; then
log_error "Docker n'est pas installé. Veuillez l'installer d'abord."
exit 1
fi
if ! command -v docker-compose &> /dev/null; then
log_error "Docker Compose n'est pas installé. Veuillez l'installer d'abord."
exit 1
fi
# Créer le répertoire de déploiement
DEPLOY_DIR="/opt/regisflow"
log_info "Création du répertoire de déploiement : $DEPLOY_DIR"
if [ ! -d "$DEPLOY_DIR" ]; then
sudo mkdir -p "$DEPLOY_DIR"
sudo chown $USER:$USER "$DEPLOY_DIR"
log_success "Répertoire créé"
else
log_info "Répertoire existant"
fi
cd "$DEPLOY_DIR"
# Vérifier la configuration .env
if [ ! -f ".env" ]; then
log_warning "Fichier .env manquant"
if [ -f ".env.production" ]; then
log_info "Copie du template .env.production vers .env"
cp .env.production .env
else
log_info "Création d'un fichier .env de base"
cat > .env << EOF
# Configuration RegisFlow Production
POSTGRES_PASSWORD=RegisFlow2024!PostgreSQL_$(date +%s)
SESSION_SECRET=RegisFlow2024SessionSecret_$(openssl rand -hex 32)
NODE_ENV=production
PORT=5000
TZ=Europe/Paris
SECURE_COOKIES=true
DATA_RETENTION_MONTHS=19
BACKUP_RETENTION_DAYS=90
MAX_BACKUP_COUNT=20
EOF
fi
log_warning "IMPORTANT: Éditez le fichier .env avec vos propres mots de passe !"
log_warning "Fichier: $DEPLOY_DIR/.env"
read -p "Appuyez sur Entrée après avoir modifié le fichier .env..."
fi
# Vérifier les fichiers Docker requis
REQUIRED_FILES=("docker-compose.yml" "Dockerfile")
for file in "${REQUIRED_FILES[@]}"; do
if [ ! -f "$file" ]; then
log_error "Fichier manquant: $file"
log_info "Assurez-vous que tous les fichiers du projet sont présents dans $DEPLOY_DIR"
exit 1
fi
done
# Arrêter les anciens conteneurs si ils existent
log_info "Arrêt des anciens conteneurs..."
docker-compose down --remove-orphans 2>/dev/null || true
# Construire et démarrer les services
log_info "Construction et démarrage des services..."
docker-compose up -d --build
# Attendre que les services soient prêts
log_info "Attente du démarrage des services..."
sleep 30
# Vérifier la santé des services
log_info "Vérification de la santé des services..."
# Vérifier PostgreSQL
if docker-compose exec -T regisflow-db pg_isready -U regisflow >/dev/null 2>&1; then
log_success "PostgreSQL est opérationnel"
else
log_error "PostgreSQL n'est pas accessible"
docker-compose logs regisflow-db
exit 1
fi
# Vérifier l'application
sleep 10
if curl -s -f http://localhost:5000/health >/dev/null 2>&1; then
log_success "Application RegisFlow est opérationnelle"
else
log_error "L'application n'est pas accessible"
docker-compose logs regisflow
exit 1
fi
# Afficher les informations de connexion
echo ""
log_success "🎉 Déploiement terminé avec succès !"
echo "======================================="
log_info "URL de l'application: http://localhost:5000"
log_info "Compte administrateur par défaut:"
log_info " - Utilisateur: admin"
log_info " - Mot de passe: admin123"
log_warning "CHANGEZ le mot de passe administrateur après la première connexion !"
echo ""
log_info "Base de données PostgreSQL accessible sur le port 5433"
echo ""
# Afficher les commandes utiles
echo "Commandes utiles:"
echo "=================="
echo "📋 Voir les logs: docker-compose logs -f"
echo "📊 État des services: docker-compose ps"
echo "🔄 Redémarrer: docker-compose restart"
echo "🛑 Arrêter: docker-compose down"
echo "📈 Statistiques: docker stats"
echo ""
log_info "Pour configurer un reverse proxy, consultez PRODUCTION.md"
log_success "Déploiement terminé !"
-70
View File
@@ -1,70 +0,0 @@
# Guide pour changer de réseau dans Portainer
# RegisFlow - Configuration réseau flexible
# ==========================================
# INSTALLATION STANDARD
# ==========================================
# 1. Déployez RegisFlow avec docker-compose up -d
# 2. Dans Portainer, allez dans Stacks > regisflow
# 3. Utilisez "Migrate" ou "Redeploy" pour changer de réseau
# ==========================================
# CHANGER DE RÉSEAU DANS PORTAINER
# ==========================================
# Option 1 : Via l'interface Portainer
# 1. Containers > regisflow-app/regisflow-db
# 2. "Disconnect" du réseau actuel
# 3. "Connect" au nouveau réseau
# 4. Redémarrer les containers
# Option 2 : Via la Stack Portainer
# 1. Stacks > votre-stack-regisflow
# 2. Editor > Modifier la section networks
# 3. Deploy the stack
# ==========================================
# RÉSEAUX COMPATIBLES PORTAINER
# ==========================================
# Réseau nginx_default (configuration actuelle)
networks:
default:
external: true
name: nginx_default
# Autres réseaux existants
networks:
default:
external: true
name: autre-reseau-existant
# Réseau macvlan (IP directe)
networks:
default:
driver: macvlan
driver_opts:
parent: eth0
# Réseau host (sans isolation)
# Supprimez la section networks et ajoutez :
# network_mode: host dans chaque service
# ==========================================
# PROCÉDURE MIGRATION PORTAINER
# ==========================================
# 1. Arrêter la stack dans Portainer
# 2. Modifier le docker-compose.yml si nécessaire
# 3. Redéployer la stack
# 4. Vérifier la connectivité réseau
# ==========================================
# DÉPANNAGE RÉSEAU
# ==========================================
# Vérifier les réseaux Docker :
# docker network ls
#
# Inspecter un réseau :
# docker network inspect nom-du-reseau
#
# Connecter manuellement un container :
# docker network connect nom-reseau nom-container
-77
View File
@@ -1,77 +0,0 @@
version: '3.8'
# Docker Compose pour Portainer - Construction automatique
# Ce fichier gère tout automatiquement sans configuration supplémentaire
services:
# Base de données PostgreSQL
regisflow-db:
image: postgres:15-alpine
container_name: regisflow-db
environment:
POSTGRES_DB: regisflow
POSTGRES_USER: regisflow
POSTGRES_PASSWORD: RegisFlow2024!PostgreSQL
volumes:
- regisflow_postgres_data:/var/lib/postgresql/data
ports:
- "5433:5432"
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U regisflow -d regisflow"]
interval: 30s
timeout: 10s
retries: 5
start_period: 30s
networks:
- regisflow_network
# Application RegisFlow - Construction depuis le répertoire courant
regisflow-app:
build:
context: .
dockerfile: Dockerfile
target: production
image: regisflow-app:latest
container_name: regisflow-app
depends_on:
regisflow-db:
condition: service_healthy
environment:
NODE_ENV: production
PORT: 5000
DATABASE_URL: postgresql://regisflow:RegisFlow2024!PostgreSQL@regisflow-db:5432/regisflow
SESSION_SECRET: RegisFlow2024SessionSecretKey1234567890ABCDEF
TZ: Europe/Paris
SECURE_COOKIES: false
DATA_RETENTION_MONTHS: 19
BACKUP_RETENTION_DAYS: 90
MAX_BACKUP_COUNT: 20
volumes:
- regisflow_backup_data:/app/backups
- regisflow_logs_data:/app/logs
ports:
- "5000:5000"
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:5000/health || exit 1"]
interval: 30s
timeout: 15s
retries: 3
start_period: 90s
networks:
- regisflow_network
# Volumes avec noms uniques pour éviter les conflits
volumes:
regisflow_postgres_data:
driver: local
regisflow_backup_data:
driver: local
regisflow_logs_data:
driver: local
# Réseau dédié avec nom unique
networks:
regisflow_network:
driver: bridge
name: regisflow_net
-113
View File
@@ -1,113 +0,0 @@
version: '3.8'
# Configuration Docker Compose optimisée pour Production
# Usage: docker-compose -f docker-compose.prod.yml up -d
services:
# Base de données PostgreSQL Production
regisflow-db:
image: postgres:15-alpine
container_name: regisflow-db-prod
environment:
POSTGRES_DB: regisflow
POSTGRES_USER: regisflow
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_INITDB_ARGS: "--auth-host=scram-sha-256 --auth-local=scram-sha-256"
volumes:
- postgres_data_prod:/var/lib/postgresql/data
- ./postgresql.conf:/etc/postgresql/postgresql.conf:ro
ports:
- "5433:5432"
restart: unless-stopped
deploy:
resources:
limits:
memory: 1G
cpus: '1.0'
reservations:
memory: 512M
cpus: '0.5'
healthcheck:
test: ["CMD-SHELL", "pg_isready -U regisflow -d regisflow"]
interval: 30s
timeout: 10s
retries: 5
start_period: 60s
command: postgres -c config_file=/etc/postgresql/postgresql.conf
# Application RegisFlow Production
regisflow:
build:
context: .
dockerfile: Dockerfile
target: production
args:
- NODE_ENV=production
image: regisflow:production
container_name: regisflow-app-prod
depends_on:
regisflow-db:
condition: service_healthy
pull_policy: never
environment:
NODE_ENV: production
PORT: 5000
DATABASE_URL: postgresql://regisflow:${POSTGRES_PASSWORD}@regisflow-db:5432/regisflow
SESSION_SECRET: ${SESSION_SECRET}
TZ: ${TZ:-Europe/Paris}
SECURE_COOKIES: ${SECURE_COOKIES:-true}
DATA_RETENTION_MONTHS: ${DATA_RETENTION_MONTHS:-19}
BACKUP_RETENTION_DAYS: ${BACKUP_RETENTION_DAYS:-90}
MAX_BACKUP_COUNT: ${MAX_BACKUP_COUNT:-20}
NODE_OPTIONS: "--max-old-space-size=1024"
volumes:
- backup_data_prod:/app/backups
- logs_data_prod:/app/logs
ports:
- "5000:5000"
restart: unless-stopped
deploy:
resources:
limits:
memory: 1.5G
cpus: '2.0'
reservations:
memory: 512M
cpus: '0.5'
healthcheck:
test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:5000/health || exit 1"]
interval: 30s
timeout: 15s
retries: 3
start_period: 120s
logging:
driver: "json-file"
options:
max-size: "100m"
max-file: "5"
# Volumes persistants pour production
volumes:
postgres_data_prod:
driver: local
driver_opts:
type: none
o: bind
device: /opt/regisflow/data/postgres
backup_data_prod:
driver: local
driver_opts:
type: none
o: bind
device: /opt/regisflow/data/backups
logs_data_prod:
driver: local
driver_opts:
type: none
o: bind
device: /opt/regisflow/data/logs
# Réseau pour reverse proxy
networks:
default:
name: regisflow-network
driver: bridge
-22
View File
@@ -1,22 +0,0 @@
#!/bin/bash
# Script pour créer l'image exacte que Portainer attend
echo "🔧 Création de l'image regisflow-regisflow:latest pour Portainer"
# Construire l'image avec le nom exact que Portainer cherche
docker build -t regisflow-regisflow:latest .
if [ $? -eq 0 ]; then
echo "✅ Image regisflow-regisflow:latest créée avec succès"
# Vérifier que l'image existe
echo "📋 Vérification de l'image:"
docker images | grep regisflow-regisflow
echo ""
echo "🐳 L'image est maintenant disponible pour Portainer"
echo "💡 Vous pouvez maintenant redéployer votre stack dans Portainer"
else
echo "❌ Échec de la création de l'image"
exit 1
fi
-151
View File
@@ -1,151 +0,0 @@
#!/bin/bash
# Script d'initialisation de la base de données RegisFlow
# Usage: ./init-db.sh [DATABASE_URL]
set -e
# Configuration par défaut
DEFAULT_DB_HOST="localhost"
DEFAULT_DB_PORT="5433"
DEFAULT_DB_NAME="regisflow"
DEFAULT_DB_USER="regisflow"
DEFAULT_DB_PASSWORD="RegisFlow2024!PostgreSQL"
# Couleurs pour les messages
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
log_info() {
echo -e "${BLUE}ℹ️ $1${NC}"
}
log_success() {
echo -e "${GREEN}✅ $1${NC}"
}
log_warning() {
echo -e "${YELLOW}⚠️ $1${NC}"
}
log_error() {
echo -e "${RED}❌ $1${NC}"
}
# Fonction pour extraire les informations de DATABASE_URL
parse_database_url() {
local url="$1"
# Extraire les composants de l'URL PostgreSQL
if [[ $url =~ postgresql://([^:]+):([^@]+)@([^:]+):([^/]+)/(.+) ]]; then
DB_USER="${BASH_REMATCH[1]}"
DB_PASSWORD="${BASH_REMATCH[2]}"
DB_HOST="${BASH_REMATCH[3]}"
DB_PORT="${BASH_REMATCH[4]}"
DB_NAME="${BASH_REMATCH[5]}"
else
log_error "Format DATABASE_URL invalide. Utilisez: postgresql://user:password@host:port/database"
exit 1
fi
}
# Déterminer la configuration de la base de données
if [ -n "$1" ]; then
log_info "Utilisation de DATABASE_URL fournie: $1"
parse_database_url "$1"
elif [ -n "$DATABASE_URL" ]; then
log_info "Utilisation de DATABASE_URL depuis l'environnement"
parse_database_url "$DATABASE_URL"
else
log_info "Utilisation de la configuration par défaut"
DB_HOST="$DEFAULT_DB_HOST"
DB_PORT="$DEFAULT_DB_PORT"
DB_NAME="$DEFAULT_DB_NAME"
DB_USER="$DEFAULT_DB_USER"
DB_PASSWORD="$DEFAULT_DB_PASSWORD"
fi
log_info "Configuration de la base de données:"
log_info " Host: $DB_HOST"
log_info " Port: $DB_PORT"
log_info " Database: $DB_NAME"
log_info " User: $DB_USER"
# Vérifier que psql est installé
if ! command -v psql &> /dev/null; then
log_error "psql n'est pas installé. Installez PostgreSQL client."
exit 1
fi
# Vérifier la connexion à PostgreSQL
log_info "Test de connexion à PostgreSQL..."
export PGPASSWORD="$DB_PASSWORD"
if ! psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -c "\q" 2>/dev/null; then
log_error "Impossible de se connecter à PostgreSQL"
log_info "Vérifiez que PostgreSQL est démarré et accessible"
log_info "Commande de test: psql -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME"
exit 1
fi
log_success "Connexion PostgreSQL réussie"
# Exécuter le script d'initialisation
log_info "Exécution du script d'initialisation..."
if [ -f "init.sql" ]; then
if psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -f init.sql; then
log_success "Script d'initialisation exécuté avec succès"
else
log_error "Erreur lors de l'exécution du script d'initialisation"
exit 1
fi
else
log_error "Fichier init.sql non trouvé"
exit 1
fi
# Vérifier que les tables ont été créées
log_info "Vérification des tables créées..."
TABLES=$(psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -t -c "SELECT tablename FROM pg_tables WHERE schemaname='public';" | tr -d ' ' | grep -v '^$')
if echo "$TABLES" | grep -q "users\|stores\|sales\|sessions"; then
log_success "Tables principales créées:"
echo "$TABLES" | while read -r table; do
if [ -n "$table" ]; then
log_info " - $table"
fi
done
else
log_error "Les tables principales n'ont pas été créées correctement"
exit 1
fi
# Vérifier l'utilisateur admin
log_info "Vérification de l'utilisateur administrateur..."
ADMIN_COUNT=$(psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -t -c "SELECT COUNT(*) FROM users WHERE username='admin';" | tr -d ' ')
if [ "$ADMIN_COUNT" = "1" ]; then
log_success "Utilisateur admin créé avec succès"
else
log_warning "Problème avec la création de l'utilisateur admin"
fi
# Afficher le résumé
echo ""
log_success "🎉 Initialisation de la base de données terminée!"
echo "======================================================"
log_info "Base de données: $DB_NAME sur $DB_HOST:$DB_PORT"
log_info "Utilisateur administrateur:"
log_info " - Username: admin"
log_info " - Password: admin123"
log_warning "IMPORTANT: Changez le mot de passe admin après la première connexion!"
echo ""
# Nettoyer les variables d'environnement
unset PGPASSWORD
log_success "Prêt pour le déploiement!"
-110
View File
@@ -1,110 +0,0 @@
# Configuration Nginx pour RegisFlow Production
# À placer dans /etc/nginx/sites-available/regisflow
server {
listen 80;
server_name votre-domaine.com www.votre-domaine.com;
# Redirection HTTPS (recommandé)
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name votre-domaine.com www.votre-domaine.com;
# Certificats SSL (Let's Encrypt recommandé)
ssl_certificate /etc/letsencrypt/live/votre-domaine.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/votre-domaine.com/privkey.pem;
# Configuration SSL moderne
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# Headers de sécurité
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header Referrer-Policy "strict-origin-when-cross-origin";
# Taille maximale pour les uploads (photos)
client_max_body_size 50M;
# Timeouts
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
proxy_buffers 32 4k;
proxy_buffer_size 8k;
# Compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_proxied any;
gzip_comp_level 6;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/json
application/javascript
application/xml+rss
application/atom+xml
image/svg+xml;
# Cache pour les assets statiques
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
proxy_pass http://localhost:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
expires 30d;
add_header Cache-Control "public, immutable";
access_log off;
}
# API endpoints (pas de cache)
location /api/ {
proxy_pass http://localhost:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Pas de cache pour les API
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Pragma "no-cache";
add_header Expires "0";
}
# Health check
location /health {
proxy_pass http://localhost:5000;
access_log off;
}
# Application principale
location / {
proxy_pass http://localhost:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Cache court pour les pages
expires 1h;
add_header Cache-Control "public";
}
# Logs
access_log /var/log/nginx/regisflow-access.log;
error_log /var/log/nginx/regisflow-error.log;
}
-75
View File
@@ -1,75 +0,0 @@
version: '3.8'
# Configuration Stack Portainer pour RegisFlow avec build automatique
# Cette version construit l'image automatiquement depuis le code source
services:
# Base de données PostgreSQL
regisflow-db:
image: postgres:15-alpine
container_name: regisflow-db
environment:
POSTGRES_DB: regisflow
POSTGRES_USER: regisflow
POSTGRES_PASSWORD: RegisFlow2024!PostgreSQL
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5433:5432"
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U regisflow -d regisflow"]
interval: 30s
timeout: 10s
retries: 5
start_period: 30s
networks:
- regisflow-net
# Application RegisFlow - Construction automatique
regisflow:
build:
context: .
dockerfile: Dockerfile
target: production
container_name: regisflow-app
depends_on:
regisflow-db:
condition: service_healthy
environment:
NODE_ENV: production
PORT: 5000
DATABASE_URL: postgresql://regisflow:RegisFlow2024!PostgreSQL@regisflow-db:5432/regisflow
SESSION_SECRET: RegisFlow2024SessionSecretKey1234567890ABCDEF
TZ: Europe/Paris
SECURE_COOKIES: false
DATA_RETENTION_MONTHS: 19
BACKUP_RETENTION_DAYS: 90
MAX_BACKUP_COUNT: 20
volumes:
- backup_data:/app/backups
- logs_data:/app/logs
ports:
- "5000:5000"
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:5000/health || exit 1"]
interval: 30s
timeout: 15s
retries: 3
start_period: 90s
networks:
- regisflow-net
# Volumes persistants
volumes:
postgres_data:
driver: local
backup_data:
driver: local
logs_data:
driver: local
# Réseau dédié
networks:
regisflow-net:
driver: bridge
-68
View File
@@ -1,68 +0,0 @@
version: '3.8'
# Configuration Stack Portainer pour RegisFlow
# À utiliser directement dans Portainer comme Stack
services:
# Base de données PostgreSQL
regisflow-db:
image: postgres:15-alpine
container_name: regisflow-db
environment:
POSTGRES_DB: regisflow
POSTGRES_USER: regisflow
POSTGRES_PASSWORD: RegisFlow2024!PostgreSQL
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5433:5432"
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U regisflow -d regisflow"]
interval: 30s
timeout: 10s
retries: 5
start_period: 30s
# Application RegisFlow - Construction depuis le code source
regisflow:
build:
context: .
dockerfile: Dockerfile
target: production
container_name: regisflow-app
depends_on:
regisflow-db:
condition: service_healthy
environment:
NODE_ENV: production
PORT: 5000
DATABASE_URL: postgresql://regisflow:RegisFlow2024!PostgreSQL@regisflow-db:5432/regisflow
SESSION_SECRET: RegisFlow2024SessionSecretKey1234567890ABCDEF
TZ: Europe/Paris
SECURE_COOKIES: false
DATA_RETENTION_MONTHS: 19
BACKUP_RETENTION_DAYS: 90
MAX_BACKUP_COUNT: 20
volumes:
- backup_data:/app/backups
- logs_data:/app/logs
ports:
- "5000:5000"
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:5000/health || exit 1"]
interval: 30s
timeout: 15s
retries: 3
start_period: 90s
# Volumes persistants
volumes:
postgres_data:
backup_data:
logs_data:
# Utilisation du réseau par défaut
networks:
default:
name: regisflow-network
-52
View File
@@ -1,52 +0,0 @@
# Configuration PostgreSQL optimisée pour production RegisFlow
# CONNECTIONS AND AUTHENTICATION
listen_addresses = '*'
port = 5432
max_connections = 100
superuser_reserved_connections = 3
# MEMORY
shared_buffers = 256MB
effective_cache_size = 512MB
work_mem = 4MB
maintenance_work_mem = 64MB
# WRITE AHEAD LOG
wal_level = replica
max_wal_size = 1GB
min_wal_size = 80MB
checkpoint_completion_target = 0.7
wal_buffers = 16MB
# QUERY TUNING
random_page_cost = 1.1
effective_io_concurrency = 200
# LOGGING
log_destination = 'stderr'
logging_collector = on
log_directory = 'log'
log_filename = 'postgresql-%Y-%m-%d.log'
log_rotation_age = 1d
log_rotation_size = 100MB
log_min_duration_statement = 1000
log_checkpoints = on
log_connections = on
log_disconnections = on
log_lock_waits = on
log_statement = 'ddl'
# AUTOVACUUM
autovacuum = on
autovacuum_max_workers = 3
autovacuum_naptime = 30s
# LOCALE AND FORMATTING
datestyle = 'iso, mdy'
timezone = 'Europe/Paris'
lc_messages = 'en_US.utf8'
lc_monetary = 'en_US.utf8'
lc_numeric = 'en_US.utf8'
lc_time = 'en_US.utf8'
default_text_search_config = 'pg_catalog.english'
+3 -5
View File
@@ -276,23 +276,21 @@ Preferred communication style: Simple, everyday language.
### Production Deployment System (January 11, 2025)
- ✅ Complete production deployment configuration with Docker Compose
- ✅ Automated deployment script (deploy-production.sh) with safety checks
- ✅ Production-optimized Dockerfile with multi-stage builds and security hardening
- ✅ PostgreSQL production configuration with performance tuning
- ✅ Nginx reverse proxy configuration with SSL/TLS and security headers
- ✅ Health check endpoints for monitoring and load balancer integration
- ✅ Environment-specific configurations (.env.production template)
- ✅ Resource limits and logging configuration for production containers
- ✅ Persistent volume management for data persistence and backups
- ✅ Production security features: non-root user, secure cookies, session management
- ✅ Replit Deployment integration ready for one-click production deployment
- ✅ All production configurations validated and deployment suggested to user
- ✅ Photo capture system fully integrated with database storage
- ✅ Modal de détails des ventes opérationnel avec support complet des photos
- ✅ API et schéma de base de données synchronisés pour la production
- ✅ Bug critique corrigé : mapping camelCase/snake_case pour photo_ticket
- ✅ NewSaleForm.tsx corrigé pour inclure photoTicket dans la soumission
- ✅ API routes.ts corrigé avec mapping automatique des photos
- ✅ **Production Cleanup**: Removed all unnecessary deployment files and debug code
- ✅ **Clean Architecture**: Simplified to essential files only (Dockerfile, docker-compose.yml, init.sql)
- ✅ **Debug Removal**: All debug logs and temporary files cleaned for production
- ✅ RegisFlow prêt pour déploiement en production avec toutes les fonctionnalités
### Docker Configuration & Cleanup (January 9, 2025)
-31
View File
@@ -1,31 +0,0 @@
#!/usr/bin/env node
// Polyfill pour import.meta.dirname dans Node.js 18
import { fileURLToPath } from 'url';
import path from 'path';
import fs from 'fs';
// Obtenir le répertoire courant
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const projectRoot = path.resolve(__dirname, '..');
// Lire le fichier dist/index.js et remplacer import.meta.dirname
const distPath = path.join(projectRoot, 'dist', 'index.js');
let distContent = fs.readFileSync(distPath, 'utf-8');
// Remplacer toutes les instances de import.meta.dirname par une valeur statique
const replacement = `"${projectRoot.replace(/\\/g, '\\\\')}"`;
distContent = distContent.replace(/import\.meta\.dirname/g, replacement);
// Aussi corriger les chemins pour le serveur statique
distContent = distContent.replace(/path3\.resolve\(\s*import\.meta\.dirname,\s*"public"\s*\)/g,
`path3.resolve("${projectRoot.replace(/\\/g, '\\\\')}", "public")`);
// Écrire le fichier modifié
fs.writeFileSync(distPath, distContent);
console.log('✅ Node.js 18 compatibility fix applied');
// Démarrer l'application
import('../dist/index.js').catch(console.error);
-166
View File
@@ -1,166 +0,0 @@
#!/bin/bash
# Script de validation pour RegisFlow - Prêt pour la production
# Ce script vérifie que tous les composants sont correctement configurés
set -e
# Couleurs pour les messages
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
BLUE='\033[0;34m'
NC='\033[0m'
log_info() {
echo -e "${BLUE}ℹ️ $1${NC}"
}
log_success() {
echo -e "${GREEN}✅ $1${NC}"
}
log_warning() {
echo -e "${YELLOW}⚠️ $1${NC}"
}
log_error() {
echo -e "${RED}❌ $1${NC}"
}
echo "🚀 Validation RegisFlow - Prêt pour la production"
echo "=================================================="
# 1. Vérifier les fichiers essentiels
log_info "Vérification des fichiers essentiels..."
REQUIRED_FILES=(
"package.json"
"Dockerfile"
"docker-compose.yml"
"init.sql"
"init-db.sh"
"docker-entrypoint-simple.sh"
"replit.md"
)
for file in "${REQUIRED_FILES[@]}"; do
if [ -f "$file" ]; then
log_success "Fichier présent: $file"
else
log_error "Fichier manquant: $file"
exit 1
fi
done
# 2. Vérifier les permissions des scripts
log_info "Vérification des permissions des scripts..."
EXECUTABLE_FILES=(
"init-db.sh"
"docker-entrypoint-simple.sh"
"deploy-production.sh"
)
for file in "${EXECUTABLE_FILES[@]}"; do
if [ -x "$file" ]; then
log_success "Permissions OK: $file"
else
log_warning "Ajout des permissions: $file"
chmod +x "$file"
fi
done
# 3. Vérifier la structure de la base de données
log_info "Vérification de la structure de la base de données..."
if command -v node >/dev/null 2>&1; then
if node -e "
const { db } = require('./server/db.ts');
const { sales } = require('./shared/schema.ts');
console.log('Schema validation passed');
process.exit(0);
" 2>/dev/null; then
log_success "Schéma de base de données valide"
else
log_warning "Impossible de valider le schéma (normal en développement)"
fi
else
log_warning "Node.js non trouvé, validation du schéma ignorée"
fi
# 4. Vérifier init.sql pour photo_ticket
log_info "Vérification du script SQL..."
if grep -q "photo_ticket TEXT" init.sql; then
log_success "Colonne photo_ticket présente dans init.sql"
else
log_error "Colonne photo_ticket manquante dans init.sql"
exit 1
fi
# 5. Vérifier les dépendances Docker
log_info "Vérification de Docker..."
if command -v docker >/dev/null 2>&1; then
log_success "Docker installé"
if command -v docker-compose >/dev/null 2>&1; then
log_success "Docker Compose installé"
else
log_warning "Docker Compose non trouvé (docker compose moderne peut être utilisé)"
fi
else
log_warning "Docker non installé (requis pour le déploiement)"
fi
# 6. Vérifier les variables d'environnement de production
log_info "Vérification des variables d'environnement..."
if [ -f ".env.production" ]; then
log_success "Fichier .env.production présent"
# Vérifier les variables critiques
REQUIRED_VARS=(
"POSTGRES_PASSWORD"
"SESSION_SECRET"
)
for var in "${REQUIRED_VARS[@]}"; do
if grep -q "^${var}=" .env.production; then
log_success "Variable configurée: $var"
else
log_warning "Variable manquante dans .env.production: $var"
fi
done
else
log_warning "Fichier .env.production manquant (recommandé pour la production)"
fi
# 7. Vérifier la configuration du build
log_info "Vérification de la configuration de build..."
if grep -q "photo_ticket" shared/schema.ts; then
log_success "Schema TypeScript mis à jour avec photo_ticket"
else
log_error "Schema TypeScript manque photo_ticket"
exit 1
fi
# 8. Résumé final
echo ""
echo "=================================================="
log_success "🎉 Validation terminée avec succès!"
echo ""
log_info "Statut du déploiement:"
log_success "✅ Base de données: Prête (avec support photo_ticket)"
log_success "✅ Application: Prête (capture photo complète)"
log_success "✅ Docker: Configuré pour la production"
log_success "✅ Scripts: Exécutables et validés"
log_success "✅ Sécurité: Configuration recommandée"
echo ""
log_info "🚀 RegisFlow est prêt pour la mise en production!"
log_info "💡 Utilisez 'docker-compose up -d' pour déployer"
log_info "🔐 Credentials par défaut: admin / admin123"
log_warning "⚠️ Changez le mot de passe admin après le premier déploiement"
echo ""