Remove obsolete files and tidy up project directory
Deletes unnecessary production debug files, migration scripts, and alternative Docker files for a cleaner project structure. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 4b008663-bd72-492b-b0b6-fa252367e730 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/0715008c-7244-40f4-befc-26c014852236/4b008663-bd72-492b-b0b6-fa252367e730/gfGF2TH
No files matched your search
@@ -1,100 +0,0 @@
|
|||||||
# Alternative Dockerfile - Approach Simple et Direct
|
|
||||||
FROM node:20-alpine AS builder
|
|
||||||
|
|
||||||
RUN apk add --no-cache python3 make g++ git
|
|
||||||
WORKDIR /build
|
|
||||||
COPY package*.json ./
|
|
||||||
RUN npm ci --include=dev --prefer-offline
|
|
||||||
COPY . .
|
|
||||||
RUN npm run build && ls -la dist/ && test -f dist/index.js
|
|
||||||
|
|
||||||
# Production Stage avec approach simplifiée
|
|
||||||
FROM node:20-alpine AS production
|
|
||||||
|
|
||||||
RUN apk add --no-cache dumb-init postgresql-client wget curl bash
|
|
||||||
|
|
||||||
# Créer l'utilisateur
|
|
||||||
RUN addgroup -g 1001 -S nodejs && adduser -S regisflow -u 1001 -G nodejs
|
|
||||||
|
|
||||||
WORKDIR /app
|
|
||||||
RUN mkdir -p /app/backups /app/logs /app/data
|
|
||||||
|
|
||||||
# Copier les fichiers depuis le builder
|
|
||||||
COPY --from=builder --chown=regisflow:nodejs /build/package*.json ./
|
|
||||||
COPY --from=builder --chown=regisflow:nodejs /build/dist ./dist
|
|
||||||
COPY --from=builder --chown=regisflow:nodejs /build/shared ./shared
|
|
||||||
COPY --from=builder --chown=regisflow:nodejs /build/drizzle.config.ts ./
|
|
||||||
COPY --from=builder --chown=regisflow:nodejs /build/init.sql ./
|
|
||||||
|
|
||||||
# Installer TOUTES les dépendances (dev inclus) pour avoir drizzle-kit
|
|
||||||
RUN npm ci --include=dev --prefer-offline
|
|
||||||
|
|
||||||
# Copier les assets publics
|
|
||||||
COPY --from=builder --chown=regisflow:nodejs /build/dist/public ./public
|
|
||||||
|
|
||||||
# Vérifier que drizzle-kit est disponible
|
|
||||||
RUN npx drizzle-kit --version
|
|
||||||
|
|
||||||
# Nettoyer
|
|
||||||
RUN npm cache clean --force && rm -rf /tmp/*
|
|
||||||
|
|
||||||
# Créer le script d'entrée INLINE dans le Dockerfile au lieu de le copier
|
|
||||||
RUN cat > /app/start.sh << 'EOF'
|
|
||||||
#!/bin/bash
|
|
||||||
set -e
|
|
||||||
echo "🚀 RegisFlow starting..."
|
|
||||||
|
|
||||||
if [ -z "$DATABASE_URL" ]; then
|
|
||||||
echo "❌ DATABASE_URL not set"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
DB_HOST=$(echo $DATABASE_URL | sed -n 's|.*@\([^:/]*\).*|\1|p')
|
|
||||||
DB_PORT=$(echo $DATABASE_URL | sed -n 's|.*:\([0-9]*\)/.*|\1|p')
|
|
||||||
DB_USER=$(echo $DATABASE_URL | sed -n 's|.*://\([^:]*\):.*|\1|p')
|
|
||||||
|
|
||||||
echo "⏳ Waiting for database..."
|
|
||||||
timeout=90
|
|
||||||
while ! pg_isready -h "$DB_HOST" -p "${DB_PORT:-5432}" -U "$DB_USER" -q && [ $timeout -gt 0 ]; do
|
|
||||||
sleep 3
|
|
||||||
timeout=$((timeout-3))
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ $timeout -le 0 ]; then
|
|
||||||
echo "❌ Database timeout"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "✅ Database ready"
|
|
||||||
mkdir -p /app/logs /app/backups
|
|
||||||
|
|
||||||
echo "🔄 Running migrations..."
|
|
||||||
if npm run db:push; then
|
|
||||||
echo "✅ Migrations successful"
|
|
||||||
else
|
|
||||||
echo "❌ Migration failed, but continuing anyway..."
|
|
||||||
echo " Application will auto-create tables on first connection"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "🌟 Starting application..."
|
|
||||||
exec npm start
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Donner les permissions au script
|
|
||||||
RUN chmod +x /app/start.sh && chown regisflow:nodejs /app/start.sh
|
|
||||||
|
|
||||||
# Changer définitivement vers l'utilisateur non-root
|
|
||||||
USER regisflow
|
|
||||||
|
|
||||||
EXPOSE 5000
|
|
||||||
|
|
||||||
ENV NODE_ENV=production
|
|
||||||
ENV PORT=5000
|
|
||||||
ENV TZ=Europe/Paris
|
|
||||||
|
|
||||||
# Health check
|
|
||||||
HEALTHCHECK --interval=30s --timeout=15s --start-period=90s --retries=3 \
|
|
||||||
CMD wget --no-verbose --tries=1 --spider http://localhost:5000/health || exit 1
|
|
||||||
|
|
||||||
# Utiliser le script inline
|
|
||||||
ENTRYPOINT ["dumb-init", "--", "/app/start.sh"]
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
# Dockerfile multi-stage pour RegisFlow Production - Version Corrigée
|
|
||||||
# Stage 1: Build
|
|
||||||
FROM node:20-alpine AS builder
|
|
||||||
|
|
||||||
# Installer les dépendances de build
|
|
||||||
RUN apk add --no-cache python3 make g++ git
|
|
||||||
|
|
||||||
# Créer le répertoire de build
|
|
||||||
WORKDIR /build
|
|
||||||
|
|
||||||
# Copier les fichiers de dépendances
|
|
||||||
COPY package*.json ./
|
|
||||||
|
|
||||||
# Installer toutes les dépendances (dev + prod)
|
|
||||||
RUN npm ci --include=dev --prefer-offline
|
|
||||||
|
|
||||||
# Copier le code source complet
|
|
||||||
COPY . .
|
|
||||||
|
|
||||||
# Construire l'application client et serveur
|
|
||||||
RUN npm run build
|
|
||||||
|
|
||||||
# Vérifier que les fichiers de build existent
|
|
||||||
RUN ls -la dist/ && test -f dist/index.js
|
|
||||||
|
|
||||||
# Stage 2: Production
|
|
||||||
FROM node:20-alpine AS production
|
|
||||||
|
|
||||||
# Installer uniquement les dépendances système nécessaires pour production
|
|
||||||
RUN apk add --no-cache \
|
|
||||||
dumb-init \
|
|
||||||
postgresql-client \
|
|
||||||
wget \
|
|
||||||
curl \
|
|
||||||
bash \
|
|
||||||
&& rm -rf /var/cache/apk/*
|
|
||||||
|
|
||||||
# Créer un utilisateur non-root avec des permissions limitées
|
|
||||||
RUN addgroup -g 1001 -S nodejs && \
|
|
||||||
adduser -S regisflow -u 1001 -G nodejs
|
|
||||||
|
|
||||||
# Créer les répertoires avec permissions appropriées
|
|
||||||
WORKDIR /app
|
|
||||||
RUN mkdir -p /app/backups /app/logs /app/data && \
|
|
||||||
chown -R regisflow:nodejs /app
|
|
||||||
|
|
||||||
# Copier uniquement les fichiers nécessaires depuis le builder
|
|
||||||
COPY --from=builder --chown=regisflow:nodejs /build/package*.json ./
|
|
||||||
COPY --from=builder --chown=regisflow:nodejs /build/dist ./dist
|
|
||||||
COPY --from=builder --chown=regisflow:nodejs /build/shared ./shared
|
|
||||||
COPY --from=builder --chown=regisflow:nodejs /build/drizzle.config.ts ./
|
|
||||||
COPY --from=builder --chown=regisflow:nodejs /build/init.sql ./
|
|
||||||
|
|
||||||
# Installer uniquement les dépendances de production
|
|
||||||
RUN npm ci --omit=dev --prefer-offline
|
|
||||||
|
|
||||||
# Copier les assets client au bon endroit pour serveStatic
|
|
||||||
COPY --from=builder --chown=regisflow:nodejs /build/dist/public ./public
|
|
||||||
|
|
||||||
# Nettoyer le cache npm
|
|
||||||
RUN npm cache clean --force && \
|
|
||||||
rm -rf /tmp/*
|
|
||||||
|
|
||||||
# Copier le script d'entrée directement dans /app (accessible)
|
|
||||||
COPY docker-entrypoint.sh /app/docker-entrypoint.sh
|
|
||||||
RUN chmod +x /app/docker-entrypoint.sh && \
|
|
||||||
chown regisflow:nodejs /app/docker-entrypoint.sh
|
|
||||||
|
|
||||||
# Changer vers l'utilisateur non-root
|
|
||||||
USER regisflow
|
|
||||||
|
|
||||||
# Exposer le port
|
|
||||||
EXPOSE 5000
|
|
||||||
|
|
||||||
# Variables d'environnement de production
|
|
||||||
ENV NODE_ENV=production
|
|
||||||
ENV PORT=5000
|
|
||||||
ENV NODE_OPTIONS="--max-old-space-size=768"
|
|
||||||
ENV TZ=Europe/Paris
|
|
||||||
|
|
||||||
# Labels pour la documentation
|
|
||||||
LABEL maintainer="RegisFlow Team"
|
|
||||||
LABEL version="1.0.0"
|
|
||||||
LABEL description="Application RegisFlow pour la gestion des ventes de feux d'artifice"
|
|
||||||
|
|
||||||
# Health check amélioré
|
|
||||||
HEALTHCHECK --interval=30s --timeout=15s --start-period=90s --retries=3 \
|
|
||||||
CMD wget --no-verbose --tries=1 --spider http://localhost:5000/health || exit 1
|
|
||||||
|
|
||||||
# Utiliser dumb-init pour gérer les signaux et lancer le script depuis /app
|
|
||||||
ENTRYPOINT ["dumb-init", "--", "/app/docker-entrypoint.sh"]
|
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
# DIAGNOSTIC - Problème liste utilisateurs en production
|
|
||||||
|
|
||||||
## 🚨 Problème signalé
|
|
||||||
La liste des utilisateurs n'apparaît plus dans l'administration en production.
|
|
||||||
|
|
||||||
## ✅ État en développement
|
|
||||||
- API `/api/admin/users` fonctionne correctement
|
|
||||||
- Retourne 5 utilisateurs : admin, gael, FFNANCY, ff292, ff579
|
|
||||||
- Interface d'administration accessible
|
|
||||||
|
|
||||||
## 🔍 Diagnostic production
|
|
||||||
|
|
||||||
### 1. Vérifier l'utilisateur admin
|
|
||||||
```bash
|
|
||||||
docker exec regisflow-regisflow-1 psql -U regisflow -d regisflow -c "
|
|
||||||
SELECT 'ADMIN ACTUEL:' as info, id, username, role, store_id, is_active
|
|
||||||
FROM users WHERE username IN ('gael', 'admin') ORDER BY id;
|
|
||||||
"
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Tester l'authentification
|
|
||||||
```bash
|
|
||||||
# Test de connexion
|
|
||||||
curl -X POST http://votre-domaine:5000/api/auth/login \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{"username":"gael","password":"votre_mot_de_passe"}' \
|
|
||||||
-c /tmp/prod_admin.txt
|
|
||||||
|
|
||||||
# Vérifier les infos utilisateur
|
|
||||||
curl http://votre-domaine:5000/api/auth/me \
|
|
||||||
-b /tmp/prod_admin.txt
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Tester la route admin
|
|
||||||
```bash
|
|
||||||
# Test route utilisateurs admin
|
|
||||||
curl http://votre-domaine:5000/api/admin/users \
|
|
||||||
-b /tmp/prod_admin.txt
|
|
||||||
|
|
||||||
# Réponse attendue : JSON array avec les utilisateurs
|
|
||||||
# Erreur possible : {"error":"Insufficient permissions"}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Vérifier les logs d'application
|
|
||||||
```bash
|
|
||||||
docker logs regisflow-regisflow-1 --tail 50 | grep -E "(admin|users|403|500)"
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🔧 Solutions possibles
|
|
||||||
|
|
||||||
### Solution 1: Problème de permissions utilisateur
|
|
||||||
```sql
|
|
||||||
-- Si l'utilisateur gael n'a pas les bons droits
|
|
||||||
UPDATE users SET role = 'administrator', store_id = NULL WHERE username = 'gael';
|
|
||||||
```
|
|
||||||
|
|
||||||
### Solution 2: Session expirée ou corrompue
|
|
||||||
```bash
|
|
||||||
# Redémarrer l'application pour nettoyer les sessions
|
|
||||||
docker restart regisflow-regisflow-1
|
|
||||||
```
|
|
||||||
|
|
||||||
### Solution 3: Problème de route middleware
|
|
||||||
- Vérifier que la route `/api/admin/users` utilise `requireRole(['administrator'])`
|
|
||||||
- S'assurer que `gael` a bien le rôle `administrator` (pas `admin`)
|
|
||||||
|
|
||||||
### Solution 4: Frontend cache/build
|
|
||||||
```bash
|
|
||||||
# En cas de problème de cache frontend
|
|
||||||
docker exec regisflow-regisflow-1 rm -rf /app/dist
|
|
||||||
docker restart regisflow-regisflow-1
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📊 État attendu après correction
|
|
||||||
|
|
||||||
### Base de données
|
|
||||||
```sql
|
|
||||||
-- Utilisateur gael doit avoir :
|
|
||||||
id | username | role | store_id | is_active
|
|
||||||
3 | gael | administrator | NULL | true
|
|
||||||
```
|
|
||||||
|
|
||||||
### API Response
|
|
||||||
```json
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"id": 3,
|
|
||||||
"username": "gael",
|
|
||||||
"role": "administrator",
|
|
||||||
"storeId": null,
|
|
||||||
"isActive": true,
|
|
||||||
...
|
|
||||||
},
|
|
||||||
...
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Interface
|
|
||||||
- Liste des utilisateurs visible dans l'onglet Administration
|
|
||||||
- Possibilité de créer/modifier/supprimer des utilisateurs
|
|
||||||
- Accès aux autres onglets (Magasins, Sauvegarde, Purge)
|
|
||||||
|
|
||||||
## 🚀 Commande de correction complète
|
|
||||||
```bash
|
|
||||||
# Correction en une seule commande
|
|
||||||
docker exec regisflow-regisflow-1 psql -U regisflow -d regisflow -c "
|
|
||||||
UPDATE users SET role = 'administrator', store_id = NULL WHERE username = 'gael';
|
|
||||||
SELECT 'UTILISATEUR CORRIGÉ:' as status, id, username, role, store_id FROM users WHERE username = 'gael';
|
|
||||||
" && docker restart regisflow-regisflow-1
|
|
||||||
```
|
|
||||||
@@ -1,144 +0,0 @@
|
|||||||
# 🚀 RegisFlow Production Deployment Checklist 2025
|
|
||||||
|
|
||||||
## ✅ Pré-Déploiement
|
|
||||||
|
|
||||||
### Configuration Système
|
|
||||||
- [ ] **Docker installé** : Version 20.10+ avec Docker Compose 2.0+
|
|
||||||
- [ ] **Ressources système** : Minimum 2GB RAM, 5GB disque libre
|
|
||||||
- [ ] **Ports disponibles** : 5000 (app) et 5433 (PostgreSQL) libres
|
|
||||||
- [ ] **Permissions utilisateur** : Accès Docker sans sudo
|
|
||||||
|
|
||||||
### Configuration Sécurité
|
|
||||||
- [ ] **Variables d'environnement** : `.env.production` créé depuis le template
|
|
||||||
- [ ] **POSTGRES_PASSWORD** : Modifié avec mot de passe sécurisé (16+ caractères)
|
|
||||||
- [ ] **SESSION_SECRET** : Généré avec clé unique 32+ caractères
|
|
||||||
- [ ] **SECURE_COOKIES** : Activé pour production HTTPS
|
|
||||||
- [ ] **Firewall** : Configuration ports 5000/5433 selon besoins
|
|
||||||
|
|
||||||
## 🔧 Déploiement
|
|
||||||
|
|
||||||
### Build et Démarrage
|
|
||||||
- [ ] **Clone repository** : Code source récupéré
|
|
||||||
- [ ] **Build Docker** : `docker-compose build` sans erreurs
|
|
||||||
- [ ] **Démarrage services** : `docker-compose up -d` réussi
|
|
||||||
- [ ] **Health check** : `curl http://localhost:5000/health` retourne status: healthy
|
|
||||||
|
|
||||||
### Vérification Base de Données
|
|
||||||
- [ ] **PostgreSQL démarré** : Container regisflow-db actif
|
|
||||||
- [ ] **Tables créées** : Migration automatique réussie
|
|
||||||
- [ ] **Connexion application** : Pas d'erreurs de connexion DB
|
|
||||||
- [ ] **Admin créé** : Compte admin/admin123 disponible
|
|
||||||
|
|
||||||
## 🧪 Tests Fonctionnels
|
|
||||||
|
|
||||||
### Interface Utilisateur
|
|
||||||
- [ ] **Page login** : http://localhost:5000 accessible
|
|
||||||
- [ ] **Connexion admin** : Login admin/admin123 fonctionne
|
|
||||||
- [ ] **Navigation** : Toutes les pages se chargent
|
|
||||||
- [ ] **Responsive** : Interface correcte mobile/tablet/desktop
|
|
||||||
|
|
||||||
### Fonctionnalités Métier
|
|
||||||
- [ ] **Nouvelle vente** : Formulaire de vente opérationnel
|
|
||||||
- [ ] **Multi-produits** : Ajout/suppression produits OK
|
|
||||||
- [ ] **Photos** : Capture caméra ou upload fichier fonctionnel
|
|
||||||
- [ ] **Validation** : EAN-13 et champs obligatoires vérifiés
|
|
||||||
- [ ] **Sauvegarde** : Vente enregistrée en base de données
|
|
||||||
|
|
||||||
### Exports et Rapports
|
|
||||||
- [ ] **Historique ventes** : Liste et filtres opérationnels
|
|
||||||
- [ ] **Export PDF** : Génération PDF avec photos
|
|
||||||
- [ ] **Export CSV** : Export CSV avec données complètes
|
|
||||||
- [ ] **Export Excel** : Export Excel avec photos intégrées
|
|
||||||
|
|
||||||
### Administration
|
|
||||||
- [ ] **Gestion utilisateurs** : Création/modification/suppression
|
|
||||||
- [ ] **Gestion magasins** : CRUD magasins complet
|
|
||||||
- [ ] **Sauvegardes** : Backup automatique et manuel
|
|
||||||
- [ ] **Purge données** : Suppression automatique 19+ mois
|
|
||||||
|
|
||||||
## 🔒 Sécurité Production
|
|
||||||
|
|
||||||
### Authentication
|
|
||||||
- [ ] **Sessions sécurisées** : Cookies HttpOnly activés
|
|
||||||
- [ ] **Rôles utilisateurs** : Admin/Manager/Employee respectés
|
|
||||||
- [ ] **Isolation magasins** : Données séparées par magasin
|
|
||||||
- [ ] **Mot de passe admin** : Changé depuis défaut admin123
|
|
||||||
|
|
||||||
### Base de Données
|
|
||||||
- [ ] **Chiffrement connexion** : SCRAM-SHA-256 activé
|
|
||||||
- [ ] **Isolation containers** : Réseau Docker sécurisé
|
|
||||||
- [ ] **Volumes persistants** : Données sauvegardées
|
|
||||||
- [ ] **Backup chiffré** : Sauvegardes sécurisées
|
|
||||||
|
|
||||||
### Système
|
|
||||||
- [ ] **Utilisateur non-root** : Application s'exécute sans privilèges
|
|
||||||
- [ ] **Ressources limitées** : CPU/RAM bornés
|
|
||||||
- [ ] **Logs structurés** : Monitoring et audit trail
|
|
||||||
- [ ] **Health checks** : Supervision continue
|
|
||||||
|
|
||||||
## 📊 Monitoring Production
|
|
||||||
|
|
||||||
### Surveillance Automatique
|
|
||||||
- [ ] **Health endpoint** : `/health` retourne métriques complètes
|
|
||||||
- [ ] **Logs application** : `docker-compose logs` informatifs
|
|
||||||
- [ ] **Métriques système** : CPU/RAM/Disque surveillés
|
|
||||||
- [ ] **Alertes erreurs** : Notifications en cas de problème
|
|
||||||
|
|
||||||
### Sauvegardes
|
|
||||||
- [ ] **Backup automatique** : Toutes les 12h (00:00 et 12:00)
|
|
||||||
- [ ] **Rétention backups** : 20 sauvegardes maximum
|
|
||||||
- [ ] **Purge automatique** : 1er du mois à 02:00
|
|
||||||
- [ ] **Statistiques** : Interface admin affiche stats
|
|
||||||
|
|
||||||
### Performance
|
|
||||||
- [ ] **Temps de réponse** : < 2s pour pages principales
|
|
||||||
- [ ] **Upload photos** : < 30s pour photos 10MB
|
|
||||||
- [ ] **Base de données** : Latence < 100ms
|
|
||||||
- [ ] **Mémoire** : Utilisation < 80% allouée
|
|
||||||
|
|
||||||
## 🚨 Urgences et Récupération
|
|
||||||
|
|
||||||
### Procédures de Récupération
|
|
||||||
- [ ] **Backup restore** : Procédure testée et documentée
|
|
||||||
- [ ] **Rollback version** : Retour version précédente possible
|
|
||||||
- [ ] **Recovery database** : Restauration PostgreSQL
|
|
||||||
- [ ] **Contacts support** : Équipe technique identifiée
|
|
||||||
|
|
||||||
### Diagnostics Rapides
|
|
||||||
```bash
|
|
||||||
# Status général
|
|
||||||
docker-compose ps
|
|
||||||
|
|
||||||
# Health application
|
|
||||||
curl http://localhost:5000/health
|
|
||||||
|
|
||||||
# Logs en temps réel
|
|
||||||
docker-compose logs -f regisflow
|
|
||||||
|
|
||||||
# Test base de données
|
|
||||||
docker exec regisflow-db pg_isready -U regisflow
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📈 Post-Déploiement
|
|
||||||
|
|
||||||
### Formation Utilisateurs
|
|
||||||
- [ ] **Guide utilisateur** : Documentation fournie
|
|
||||||
- [ ] **Formation admin** : Administration système
|
|
||||||
- [ ] **Procédures métier** : Processus ventes documentés
|
|
||||||
- [ ] **Support utilisateur** : Canal support défini
|
|
||||||
|
|
||||||
### Maintenance Préventive
|
|
||||||
- [ ] **Planning updates** : Mises à jour programmées
|
|
||||||
- [ ] **Monitoring continu** : Surveillance 24/7 configurée
|
|
||||||
- [ ] **Backup verification** : Tests restore périodiques
|
|
||||||
- [ ] **Audit sécurité** : Révision trimestrielle
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**✅ RegisFlow Production Ready 2025**
|
|
||||||
|
|
||||||
Date de validation : _____________________
|
|
||||||
|
|
||||||
Responsable déploiement : _____________________
|
|
||||||
|
|
||||||
Signature : _____________________
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
# CORRECTION URGENTE ADMIN PRODUCTION
|
|
||||||
|
|
||||||
## Problème identifié
|
|
||||||
- En production: Utilisateur admin ID 3 avec rôle "admin" au lieu de "administrator"
|
|
||||||
- Logs montrent: `{"id":3,"username":"admin","email":"admin@exampl...`
|
|
||||||
|
|
||||||
## Solutions appliquées
|
|
||||||
|
|
||||||
### 1. Correction automatique (déjà ajoutée au code)
|
|
||||||
Le fichier `server/storage.ts` contient maintenant une correction automatique qui se déclenche au démarrage.
|
|
||||||
|
|
||||||
### 2. Correction manuelle SQL (si nécessaire)
|
|
||||||
|
|
||||||
**Commande Docker pour production:**
|
|
||||||
```bash
|
|
||||||
docker exec regisflow-regisflow-1 psql -U regisflow -d regisflow -f /app/force-admin-correction.sql
|
|
||||||
```
|
|
||||||
|
|
||||||
**Ou commande SQL directe:**
|
|
||||||
```bash
|
|
||||||
docker exec regisflow-regisflow-1 psql -U regisflow -d regisflow -c "UPDATE users SET role = 'administrator' WHERE username = 'admin';"
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Vérification
|
|
||||||
```bash
|
|
||||||
docker exec regisflow-regisflow-1 psql -U regisflow -d regisflow -c "SELECT id, username, role FROM users WHERE username = 'admin';"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Résultats attendus
|
|
||||||
Après correction, l'onglet "Administration" apparaîtra dans l'interface utilisateur.
|
|
||||||
|
|
||||||
## Si le problème persiste
|
|
||||||
1. Redémarrer le container: `docker restart regisflow-regisflow-1`
|
|
||||||
2. Vider le cache navigateur
|
|
||||||
3. Se reconnecter avec admin/admin123
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
# RegisFlow Production Update 2025
|
|
||||||
|
|
||||||
## Problème Docker Résolu - Version Finale
|
|
||||||
|
|
||||||
### Problème Identifié
|
|
||||||
L'erreur `docker-entrypoint.sh: No such file or directory` était causée par des problèmes de permissions et de copie de fichiers dans le contexte Docker multi-stage.
|
|
||||||
|
|
||||||
### Solution Implémentée
|
|
||||||
|
|
||||||
#### Dockerfile.simple - Approche Robuste
|
|
||||||
Au lieu de copier un fichier externe, le script d'entrée est maintenant créé directement dans le Dockerfile avec gestion d'erreur des migrations :
|
|
||||||
|
|
||||||
```dockerfile
|
|
||||||
# Créer le script d'entrée INLINE dans le Dockerfile
|
|
||||||
RUN cat > /app/start.sh << 'EOF'
|
|
||||||
#!/bin/bash
|
|
||||||
set -e
|
|
||||||
echo "🚀 RegisFlow starting..."
|
|
||||||
# ... script complet inline ...
|
|
||||||
EOF
|
|
||||||
```
|
|
||||||
|
|
||||||
### Avantages de cette Approche
|
|
||||||
|
|
||||||
1. **Élimination du problème de copie** : Pas de fichier externe à copier
|
|
||||||
2. **Permissions garanties** : Script créé avec les bonnes permissions
|
|
||||||
3. **Simplicité** : Moins d'étapes, moins d'erreurs possibles
|
|
||||||
4. **Robustesse** : Fonctionne sur tous les environnements Docker
|
|
||||||
|
|
||||||
### Problèmes Additionnels Résolus
|
|
||||||
|
|
||||||
1. **drizzle-kit manquant** : Script inclut maintenant toutes les dépendances
|
|
||||||
2. **Migration robuste** : Échec de migration n'empêche plus le démarrage
|
|
||||||
3. **Auto-création** : Tables créées automatiquement à la première connexion
|
|
||||||
|
|
||||||
### Fichiers Modifiés
|
|
||||||
|
|
||||||
- `Dockerfile.simple` : Approche la plus robuste avec gestion d'erreur
|
|
||||||
- `docker-compose.yml` : Utilise Dockerfile.simple
|
|
||||||
- `docker-test-quick.sh` : Script de test mis à jour
|
|
||||||
|
|
||||||
### Test de Validation
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Test complet automatisé
|
|
||||||
./docker-test-quick.sh
|
|
||||||
|
|
||||||
# Ou étape par étape
|
|
||||||
docker-compose down -v
|
|
||||||
docker-compose build --no-cache
|
|
||||||
docker-compose up -d
|
|
||||||
curl http://localhost:5000/health
|
|
||||||
```
|
|
||||||
|
|
||||||
### Problème SSL PostgreSQL Résolu
|
|
||||||
|
|
||||||
4. **Erreur SSL** : "The server does not support SSL connections"
|
|
||||||
- **Solution** : Configuration SSL désactivée pour Docker local
|
|
||||||
- **Implémentation** : sslmode=disable dans DATABASE_URL
|
|
||||||
- **Robustesse** : Détection automatique du mode SSL nécessaire
|
|
||||||
|
|
||||||
5. **Erreur Permissions Admin** : "Insufficient permissions" pour admin
|
|
||||||
- **Problème** : Incohérence entre rôle 'admin' en DB et 'administrator' dans code
|
|
||||||
- **Solution** : Mise à jour rôle admin vers 'administrator' et correction routes
|
|
||||||
- **Implémentation** : UPDATE users + correction toutes routes requireRole()
|
|
||||||
|
|
||||||
### Status : ✅ RÉSOLU COMPLET
|
|
||||||
|
|
||||||
Cette solution garantit un déploiement Docker fiable en production sans les problèmes de fichiers manquants, migrations échouées, ou erreurs SSL.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Date** : 19 Juillet 2025
|
|
||||||
**Version** : RegisFlow Production 2025.1.1
|
|
||||||
**Status** : Production Ready
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
# CORRECTION URGENTE PRODUCTION - PROBLÈME SÉLECTEUR MAGASIN
|
|
||||||
|
|
||||||
## ✅ PROBLÈME IDENTIFIÉ ET RÉSOLU
|
|
||||||
|
|
||||||
### Problème principal
|
|
||||||
- Ventes créées sur le mauvais magasin malgré le sélecteur de magasin
|
|
||||||
- Frontend utilisait `user?.role === 'admin'` au lieu de `'administrator'`
|
|
||||||
- Le `storeId` n'était pas envoyé dans les requêtes de création de vente
|
|
||||||
|
|
||||||
### ✅ CORRECTIONS APPLIQUÉES
|
|
||||||
|
|
||||||
#### 1. Frontend corrigé
|
|
||||||
```javascript
|
|
||||||
// ✅ AVANT (incorrect)
|
|
||||||
...(user?.role === 'admin' && selectedStoreId && { storeId: selectedStoreId })
|
|
||||||
|
|
||||||
// ✅ APRÈS (correct)
|
|
||||||
...(user?.role === 'administrator' && selectedStoreId && { storeId: selectedStoreId })
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 2. Backend corrigé
|
|
||||||
```javascript
|
|
||||||
// ✅ Routes API corrigées pour utiliser 'administrator' au lieu de 'admin'
|
|
||||||
if (user.role !== 'administrator' && targetStoreId !== user.storeId)
|
|
||||||
if (user.role === 'administrator' && req.body.storeId)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Solutions pour production
|
|
||||||
|
|
||||||
#### 1. Corriger l'utilisateur admin production
|
|
||||||
```sql
|
|
||||||
-- Mettre à jour l'utilisateur gael (ID 3) pour qu'il ait les bons droits
|
|
||||||
UPDATE users SET role = 'administrator', store_id = NULL WHERE id = 3;
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 2. Redémarrer l'application
|
|
||||||
```bash
|
|
||||||
docker restart regisflow-regisflow-1
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 3. Test après correction
|
|
||||||
Les ventes devraient maintenant être créées sur le bon magasin sélectionné.
|
|
||||||
|
|
||||||
## ✅ RÉSULTATS ATTENDUS
|
|
||||||
- L'admin peut voir et sélectionner tous les magasins
|
|
||||||
- Les ventes sont créées sur le magasin sélectionné
|
|
||||||
- L'historique affiche les ventes du bon magasin
|
|
||||||
- La suppression de ventes fonctionne correctement
|
|
||||||
|
|
||||||
### ✅ CORRECTION SUPPLÉMENTAIRE - Suppression des ventes
|
|
||||||
Route DELETE corrigée pour utiliser 'administrator' au lieu de 'admin':
|
|
||||||
```javascript
|
|
||||||
app.delete('/api/sales/:id', requireRole(['administrator', 'manager']), ...)
|
|
||||||
```
|
|
||||||
@@ -1,120 +0,0 @@
|
|||||||
🔄 Attempting database migration...
|
|
||||||
|
|
||||||
> rest-express@1.0.0 db:push
|
|
||||||
|
|
||||||
> drizzle-kit push
|
|
||||||
|
|
||||||
No config path provided, using default 'drizzle.config.ts'
|
|
||||||
|
|
||||||
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...
|
|
||||||
|
|
||||||
[✓] Pulling schema from database...
|
|
||||||
|
|
||||||
[i] No changes detected
|
|
||||||
|
|
||||||
✅ Migration completed
|
|
||||||
|
|
||||||
🌟 Starting RegisFlow application...
|
|
||||||
|
|
||||||
> rest-express@1.0.0 start
|
|
||||||
|
|
||||||
> NODE_ENV=production node dist/index.js
|
|
||||||
|
|
||||||
/app/node_modules/pg-pool/index.js:45
|
|
||||||
|
|
||||||
Error.captureStackTrace(err)
|
|
||||||
|
|
||||||
^
|
|
||||||
|
|
||||||
Error: The server does not support SSL connections
|
|
||||||
|
|
||||||
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:210:12)
|
|
||||||
|
|
||||||
at async DatabaseStorage.initializeDefaults (file:///app/dist/index.js:384:27)
|
|
||||||
|
|
||||||
at async registerRoutes (file:///app/dist/index.js:636:22)
|
|
||||||
|
|
||||||
at async file:///app/dist/index.js:1277:18
|
|
||||||
|
|
||||||
Node.js v20.19.4
|
|
||||||
|
|
||||||
🚀 RegisFlow Production Starting...
|
|
||||||
|
|
||||||
⏳ Waiting for database regisflow-db:5432...
|
|
||||||
|
|
||||||
✅ Database ready
|
|
||||||
|
|
||||||
🔄 Attempting database migration...
|
|
||||||
|
|
||||||
> rest-express@1.0.0 db:push
|
|
||||||
|
|
||||||
> drizzle-kit push
|
|
||||||
|
|
||||||
No config path provided, using default 'drizzle.config.ts'
|
|
||||||
|
|
||||||
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...
|
|
||||||
|
|
||||||
[⡿] Pulling schema from database...
|
|
||||||
|
|
||||||
[✓] Pulling schema from database...
|
|
||||||
|
|
||||||
[i] No changes detected
|
|
||||||
|
|
||||||
✅ Migration completed
|
|
||||||
|
|
||||||
🌟 Starting RegisFlow application...
|
|
||||||
|
|
||||||
> rest-express@1.0.0 start
|
|
||||||
|
|
||||||
> NODE_ENV=production node dist/index.js
|
|
||||||
|
|
||||||
/app/node_modules/pg-pool/index.js:45
|
|
||||||
|
|
||||||
Error.captureStackTrace(err)
|
|
||||||
|
|
||||||
^
|
|
||||||
|
|
||||||
Error: The server does not support SSL connections
|
|
||||||
|
|
||||||
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:210:12)
|
|
||||||
|
|
||||||
at async DatabaseStorage.initializeDefaults (file:///app/dist/index.js:384:27)
|
|
||||||
|
|
||||||
at async registerRoutes (file:///app/dist/index.js:636:22)
|
|
||||||
|
|
||||||
at async file:///app/dist/index.js:1277:18
|
|
||||||
|
|
||||||
Node.js v20.19.4
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
[⢿] Pulling schema from database...
|
|
||||||
|
|
||||||
[✓] Pulling schema from database...
|
|
||||||
|
|
||||||
[i] No changes detected
|
|
||||||
|
|
||||||
✅ Migration completed
|
|
||||||
|
|
||||||
🌟 Starting RegisFlow application...
|
|
||||||
|
|
||||||
Database URL configured with SSL disabled
|
|
||||||
|
|
||||||
> rest-express@1.0.0 start
|
|
||||||
|
|
||||||
> NODE_ENV=production node dist/index.js
|
|
||||||
|
|
||||||
5:47:11 PM [express] serving on port 5000
|
|
||||||
|
|
||||||
📅 Automatic backup scheduler started
|
|
||||||
|
|
||||||
⏰ Backups will run every 12 hours (00:00 and 12:00)
|
|
||||||
|
|
||||||
📁 Backup directory: /app/backups
|
|
||||||
|
|
||||||
📚 Maximum backups kept: 10
|
|
||||||
|
|
||||||
🕐 Planificateur de purge des ventes démarré
|
|
||||||
|
|
||||||
⏰ Purge automatique : 1er de chaque mois à 02:00
|
|
||||||
|
|
||||||
📅 Rétention des données : 19 mois maximum
|
|
||||||
|
|
||||||
5:47:15 PM [express] GET /api/auth/me 304 in 31ms :: {"id":3,"username":"admin","email":"admin@examp…
|
|
||||||
|
|
||||||
5:47:16 PM [express] GET /api/sales 200 in 12ms :: []
|
|
||||||
|
|
||||||
5:47:16 PM [express] GET /api/auth/me 304 in 6ms :: {"id":3,"username":"admin","email":"admin@exampl…
|
|
||||||
|
|
||||||
5:47:16 PM [express] GET /api/auth/me 304 in 11ms :: {"id":3,"username":"admin","email":"admin@examp…
|
|
||||||
|
|
||||||
5:47:20 PM [express] GET /api/auth/me 304 in 6ms :: {"id":3,"username":"admin","email":"admin@exampl…
|
|
||||||
|
|
||||||
5:47:20 PM [express] GET /api/auth/me 304 in 6ms :: {"id":3,"username":"admin","email":"admin@exampl…
|
|
||||||
|
|
||||||
5:47:20 PM [express] GET /api/auth/me 304 in 5ms :: {"id":3,"username":"admin","email":"admin@exampl…
|
|
||||||
|
|
||||||
5:47:21 PM [express] GET /api/auth/me 304 in 6ms :: {"id":3,"username":"admin","email":"admin@exampl…
|
|
||||||
|
|
||||||
5:47:21 PM [express] GET /api/auth/me 304 in 5ms :: {"id":3,"username":"admin","email":"admin@exampl…
|
|
||||||
|
|
||||||
5:47:22 PM [express] GET /api/auth/me 304 in 5ms :: {"id":3,"username":"admin","email":"admin@exampl…
|
|
||||||
|
|
||||||
5:47:28 PM [express] GET /api/auth/me 304 in 5ms :: {"id":3,"username":"admin","email":"admin@exampl…
|
|
||||||
|
|
||||||
5:47:28 PM [express] GET /api/auth/me 304 in 5ms :: {"id":3,"username":"admin","email":"admin@exampl…
|
|
||||||
|
|
||||||
5:47:28 PM [express] GET /api/auth/me 304 in 9ms :: {"id":3,"username":"admin","email":"admin@exampl…
|
|
||||||
|
|
||||||
5:47:28 PM [express] GET /api/auth/me 304 in 3ms :: {"id":3,"username":"admin","email":"admin@exampl…
|
|
||||||
|
|
||||||
5:47:28 PM [express] GET /api/stores 304 in 7ms :: [{"id":3,"name":"Magasin Principal","address":"À …
|
|
||||||
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
4:35:13 PM [express] GET /api/auth/me 401 in 2ms :: {"error":"Authentication required"}
|
|
||||||
|
|
||||||
4:35:13 PM [express] GET /api/auth/default-credentials-status 200 in 311ms :: {"showDefaultCredentia…
|
|
||||||
|
|
||||||
4:35:34 PM [express] POST /api/auth/login 200 in 327ms :: {"user":{"id":1,"username":"admin","email"…
|
|
||||||
|
|
||||||
4:35:35 PM [express] GET /api/auth/me 200 in 5ms :: {"id":1,"username":"admin","email":"admin@exampl…
|
|
||||||
|
|
||||||
4:35:35 PM [express] GET /api/auth/me 304 in 4ms :: {"id":1,"username":"admin","email":"admin@exampl…
|
|
||||||
|
|
||||||
4:35:35 PM [express] GET /api/auth/me 304 in 3ms :: {"id":1,"username":"admin","email":"admin@exampl…
|
|
||||||
|
|
||||||
4:35:35 PM [express] GET /api/auth/me 304 in 4ms :: {"id":1,"username":"admin","email":"admin@exampl…
|
|
||||||
|
|
||||||
4:35:35 PM [express] GET /api/admin/stores 200 in 5ms :: [{"id":1,"name":"Magasin Principal","addres…
|
|
||||||
|
|
||||||
4:36:29 PM [express] POST /api/sales 201 in 181ms :: {"id":1,"storeId":1,"userId":1,"timestamp":"202…
|
|
||||||
|
|
||||||
4:36:32 PM [express] GET /api/auth/me 304 in 4ms :: {"id":1,"username":"admin","email":"admin@exampl…
|
|
||||||
|
|
||||||
4:36:32 PM [express] GET /api/sales 200 in 62ms :: [{"id":1,"storeId":1,"userId":1,"timestamp":"2025…
|
|
||||||
|
|
||||||
4:37:01 PM [express] GET /api/auth/me 304 in 30ms :: {"id":1,"username":"admin","email":"admin@examp…
|
|
||||||
|
|
||||||
4:37:01 PM [express] GET /api/admin/users 200 in 7ms :: [{"id":1,"username":"admin","email":"admin@e…
|
|
||||||
|
|
||||||
4:37:01 PM [express] GET /api/admin/purge/stats 200 in 11ms :: {"totalSales":1,"oldSales":0,"cutoffD…
|
|
||||||
|
|
||||||
4:37:01 PM [express] GET /api/admin/backup/stats 304 in 28ms :: {"totalBackups":10,"backupDirectory"…
|
|
||||||
|
|
||||||
Import backup error: TypeError: value.toISOString is not a function
|
|
||||||
|
|
||||||
at PgTimestamp.mapToDriverValue (file:///app/node_modules/drizzle-orm/pg-core/columns/timestamp.js:34:18)
|
|
||||||
|
|
||||||
at file:///app/node_modules/drizzle-orm/sql/sql.js:131:73
|
|
||||||
|
|
||||||
at Array.map (<anonymous>)
|
|
||||||
|
|
||||||
at SQL.buildQueryFromSourceParams (file:///app/node_modules/drizzle-orm/sql/sql.js:73:32)
|
|
||||||
|
|
||||||
at file:///app/node_modules/drizzle-orm/sql/sql.js:92:21
|
|
||||||
|
|
||||||
at Array.map (<anonymous>)
|
|
||||||
|
|
||||||
at SQL.buildQueryFromSourceParams (file:///app/node_modules/drizzle-orm/sql/sql.js:73:32)
|
|
||||||
|
|
||||||
at file:///app/node_modules/drizzle-orm/sql/sql.js:95:21
|
|
||||||
|
|
||||||
at Array.map (<anonymous>)
|
|
||||||
|
|
||||||
at SQL.buildQueryFromSourceParams (file:///app/node_modules/drizzle-orm/sql/sql.js:73:32)
|
|
||||||
|
|
||||||
4:37:16 PM [express] POST /api/admin/backup/import 500 in 70ms :: {"error":"Failed to import backup"…
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
NODE_ENV=production node dist/index.js
|
|
||||||
|
|
||||||
5:12:31 PM [express] serving on port 5000
|
|
||||||
|
|
||||||
📅 Automatic backup scheduler started
|
|
||||||
|
|
||||||
⏰ Backups will run every 12 hours (00:00 and 12:00)
|
|
||||||
|
|
||||||
📁 Backup directory: /app/backups
|
|
||||||
|
|
||||||
📚 Maximum backups kept: 10
|
|
||||||
|
|
||||||
🕐 Planificateur de purge des ventes démarré
|
|
||||||
|
|
||||||
⏰ Purge automatique : 1er de chaque mois à 02:00
|
|
||||||
|
|
||||||
📅 Rétention des données : 19 mois maximum
|
|
||||||
|
|
||||||
5:25:38 PM [express] GET /api/auth/me 304 in 6ms :: {"id":3,"username":"admin","email":"admin@exampl…
|
|
||||||
|
|
||||||
5:25:38 PM [express] GET /api/auth/me 304 in 5ms :: {"id":3,"username":"admin","email":"admin@exampl…
|
|
||||||
|
|
||||||
5:25:39 PM [express] GET /api/auth/me 304 in 8ms :: {"id":3,"username":"admin","email":"admin@exampl…
|
|
||||||
|
|
||||||
5:25:39 PM [express] GET /api/auth/me 304 in 7ms :: {"id":3,"username":"admin","email":"admin@exampl…
|
|
||||||
|
|
||||||
5:25:39 PM [express] GET /api/stores 200 in 8ms :: [{"id":3,"name":"Magasin Principal","address":"À …
|
|
||||||
|
|
||||||
5:25:39 PM [express] GET /api/auth/me 304 in 5ms :: {"id":3,"username":"admin","email":"admin@exampl…
|
|
||||||
|
|
||||||
5:25:40 PM [express] GET /api/sales 200 in 10ms :: []
|
|
||||||
|
|
||||||
5:25:43 PM [express] GET /api/auth/me 304 in 5ms :: {"id":3,"username":"admin","email":"admin@exampl…
|
|
||||||
|
|
||||||
5:25:43 PM [express] GET /api/auth/me 304 in 4ms :: {"id":3,"username":"admin","email":"admin@exampl…
|
|
||||||
|
|
||||||
5:25:44 PM [express] GET /api/auth/me 304 in 4ms :: {"id":3,"username":"admin","email":"admin@exampl…
|
|
||||||
|
|
||||||
5:25:44 PM [express] GET /api/auth/me 304 in 4ms :: {"id":3,"username":"admin","email":"admin@exampl…
|
|
||||||
|
|
||||||
5:25:50 PM [express] POST /api/auth/logout 200 in 3ms :: {"message":"Logged out successfully"}
|
|
||||||
|
|
||||||
5:25:50 PM [express] GET /api/sales 401 in 2ms :: {"error":"Authentication required"}
|
|
||||||
|
|
||||||
5:25:50 PM [express] GET /api/auth/me 401 in 2ms :: {"error":"Authentication required"}
|
|
||||||
|
|
||||||
5:25:50 PM [express] GET /api/auth/me 401 in 1ms :: {"error":"Authentication required"}
|
|
||||||
|
|
||||||
5:25:50 PM [express] GET /api/auth/default-credentials-status 200 in 362ms :: {"showDefaultCredentia…
|
|
||||||
|
|
||||||
5:25:54 PM [express] POST /api/auth/login 200 in 326ms :: {"user":{"id":3,"username":"admin","email"…
|
|
||||||
|
|
||||||
5:25:55 PM [express] GET /api/auth/me 304 in 14ms :: {"id":3,"username":"admin","email":"admin@examp…
|
|
||||||
|
|
||||||
5:25:55 PM [express] GET /api/auth/me 304 in 6ms :: {"id":3,"username":"admin","email":"admin@exampl…
|
|
||||||
|
|
||||||
5:25:55 PM [express] GET /api/auth/me 304 in 5ms :: {"id":3,"username":"admin","email":"admin@exampl…
|
|
||||||
|
|
||||||
5:25:55 PM [express] GET /api/auth/me 304 in 4ms :: {"id":3,"username":"admin","email":"admin@exampl…
|
|
||||||
|
|
||||||
5:25:55 PM [express] GET /api/stores 304 in 11ms :: [{"id":3,"name":"Magasin Principal","address":"À…
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
PM [express] GET /api/auth/me 304 in 19ms :: {"id":3,"username":"admin","email":"admin@examp…
|
|
||||||
|
|
||||||
6:07:30 PM [express] GET /api/auth/me 304 in 5ms :: {"id":3,"username":"admin","email":"admin@exampl…
|
|
||||||
|
|
||||||
6:07:31 PM [express] GET /api/auth/me 304 in 6ms :: {"id":3,"username":"admin","email":"admin@exampl…
|
|
||||||
|
|
||||||
6:07:32 PM [express] GET /api/auth/me 304 in 4ms :: {"id":3,"username":"admin","email":"admin@exampl…
|
|
||||||
|
|
||||||
6:07:33 PM [express] GET /api/sales 403 in 4ms :: {"error":"Access denied to this store"}
|
|
||||||
|
|
||||||
6:07:35 PM [express] GET /api/sales 403 in 7ms :: {"error":"Access denied to this store"}
|
|
||||||
|
|
||||||
6:07:39 PM [express] GET /api/sales 403 in 6ms :: {"error":"Access denied to this store"}
|
|
||||||
|
|
||||||
6:07:45 PM [express] GET /api/auth/me 304 in 6ms :: {"id":3,"username":"admin","email":"admin@exampl…
|
|
||||||
|
|
||||||
6:07:47 PM [express] GET /api/auth/me 304 in 5ms :: {"id":3,"username":"admin","email":"admin@exampl…
|
|
||||||
|
|
||||||
6:07:47 PM [express] GET /api/sales 403 in 4ms :: {"error":"Access denied to this store"}
|
|
||||||
|
|
||||||
6:07:47 PM [express] GET /api/auth/me 304 in 5ms :: {"id":3,"username":"admin","email":"admin@exampl…
|
|
||||||
|
|
||||||
6:08:07 PM [express] GET /api/auth/me 304 in 26ms :: {"id":3,"username":"admin","email":"admin@examp…
|
|
||||||
|
|
||||||
6:08:07 PM [express] GET /api/sales 403 in 6ms :: {"error":"Access denied to this store"}
|
|
||||||
|
|
||||||
6:08:38 PM [express] GET /api/admin/backup/stats 304 in 22ms :: {"totalBackups":10,"backupDirectory"…
|
|
||||||
|
|
||||||
6:08:38 PM [express] GET /api/admin/purge/stats 200 in 6ms :: {"totalSales":0,"oldSales":0,"cutoffDa…
|
|
||||||
|
|
||||||
6:09:08 PM [express] GET /api/admin/backup/stats 304 in 37ms :: {"totalBackups":10,"backupDirectory"…
|
|
||||||
|
|
||||||
6:09:08 PM [express] GET /api/admin/purge/stats 200 in 12ms :: {"totalSales":0,"oldSales":0,"cutoffD…
|
|
||||||
|
|
||||||
6:09:38 PM [express] GET /api/admin/backup/stats 304 in 26ms :: {"totalBackups":10,"backupDirectory"…
|
|
||||||
|
|
||||||
6:09:38 PM [express] GET /api/admin/purge/stats 200 in 6ms :: {"totalSales":0,"oldSales":0,"cutoffDa…
|
|
||||||
|
|
||||||
6:10:08 PM [express] GET /api/admin/backup/stats 304 in 41ms :: {"totalBackups":10,"backupDirectory"…
|
|
||||||
|
|
||||||
6:10:08 PM [express] GET /api/admin/purge/stats 200 in 9ms :: {"totalSales":0,"oldSales":0,"cutoffDa…
|
|
||||||
|
|
||||||
6:10:38 PM [express] GET /api/admin/backup/stats 304 in 18ms :: {"totalBackups":10,"backupDirectory"…
|
|
||||||
|
|
||||||
6:10:38 PM [express] GET /api/admin/purge/stats 200 in 10ms :: {"totalSales":0,"oldSales":0,"cutoffD…
|
|
||||||
|
|
||||||
6:11:08 PM [express] GET /api/admin/backup/stats 304 in 23ms :: {"totalBackups":10,"backupDirectory"…
|
|
||||||
|
|
||||||
6:11:08 PM [express] GET /api/admin/purge/stats 200 in 6ms :: {"totalSales":0,"oldSales":0,"cutoffDa…
|
|
||||||
|
|
||||||
6:11:38 PM [express] GET /api/admin/purge/stats 200 in 9ms :: {"totalSales":0,"oldSales":0,"cutoffDa…
|
|
||||||
|
|
||||||
6:11:38 PM [express] GET /api/admin/backup/stats 304 in 35ms :: {"totalBackups":10,"backupDirectory"…
|
|
||||||
|
|
||||||
6:11:48 PM [express] GET /api/auth/me 304 in 5ms :: {"id":3,"username":"admin","email":"admin@exampl…
|
|
||||||
|
|
||||||
6:11:48 PM [express] GET /api/auth/me 304 in 11ms :: {"id":3,"username":"admin","email":"admin@examp…
|
|
||||||
|
|
||||||
6:11:48 PM [express] GET /api/sales 403 in 5ms :: {"error":"Access denied to this store"}
|
|
||||||
|
|
||||||
6:11:50 PM [express] GET /api/auth/me 304 in 4ms :: {"id":3,"username":"admin","email":"admin@exampl…
|
|
||||||
|
Before Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 8.9 KiB |
|
Before Width: | Height: | Size: 93 KiB |
|
Before Width: | Height: | Size: 136 KiB |
|
Before Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 126 KiB |
|
Before Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 320 KiB |
@@ -1,42 +0,0 @@
|
|||||||
-- Script de vérification pour RegisFlow Production
|
|
||||||
-- À exécuter pour valider que la base de données est prête
|
|
||||||
|
|
||||||
-- Vérifier la version PostgreSQL
|
|
||||||
SELECT version();
|
|
||||||
|
|
||||||
-- Vérifier les tables principales
|
|
||||||
\dt
|
|
||||||
|
|
||||||
-- Compter les utilisateurs
|
|
||||||
SELECT COUNT(*) as total_users FROM users;
|
|
||||||
|
|
||||||
-- Compter les magasins
|
|
||||||
SELECT COUNT(*) as total_stores FROM stores;
|
|
||||||
|
|
||||||
-- Compter les ventes
|
|
||||||
SELECT COUNT(*) as total_sales FROM sales;
|
|
||||||
|
|
||||||
-- Vérifier l'utilisateur admin par défaut
|
|
||||||
SELECT username, role, email FROM users WHERE role = 'admin';
|
|
||||||
|
|
||||||
-- Vérifier les index pour performance
|
|
||||||
\di
|
|
||||||
|
|
||||||
-- Taille de la base de données
|
|
||||||
SELECT pg_size_pretty(pg_database_size('regisflow')) as database_size;
|
|
||||||
|
|
||||||
-- Dernières ventes (si des données existent)
|
|
||||||
SELECT id, vendeur, nom, prenom, created_at
|
|
||||||
FROM sales
|
|
||||||
ORDER BY created_at DESC
|
|
||||||
LIMIT 5;
|
|
||||||
|
|
||||||
-- Vérifier les sessions actives
|
|
||||||
SELECT COUNT(*) as active_sessions FROM sessions;
|
|
||||||
|
|
||||||
-- Status général
|
|
||||||
SELECT
|
|
||||||
'RegisFlow Production Check' as status,
|
|
||||||
CURRENT_TIMESTAMP as check_time,
|
|
||||||
current_database() as database_name,
|
|
||||||
current_user as database_user;
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
#!/usr/bin/env node
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Script de diagnostic pour problème administration production
|
|
||||||
* Teste les routes d'administration et permissions
|
|
||||||
*/
|
|
||||||
|
|
||||||
const https = require('https');
|
|
||||||
const http = require('http');
|
|
||||||
|
|
||||||
// Configuration production - remplacez par votre domaine
|
|
||||||
const PROD_URL = 'your-production-domain.com';
|
|
||||||
const PROD_PORT = 5000;
|
|
||||||
|
|
||||||
// Test des routes d'administration
|
|
||||||
async function testAdminRoutes() {
|
|
||||||
console.log('🔍 DIAGNOSTIC ADMINISTRATION PRODUCTION');
|
|
||||||
console.log('=====================================');
|
|
||||||
|
|
||||||
// 1. Test de connexion auth
|
|
||||||
console.log('\n1. Test connexion administrateur...');
|
|
||||||
try {
|
|
||||||
const loginData = {
|
|
||||||
username: 'gael', // ou l'utilisateur admin en production
|
|
||||||
password: 'your_password' // Remplacez par le bon mot de passe
|
|
||||||
};
|
|
||||||
|
|
||||||
console.log('POST /api/auth/login');
|
|
||||||
console.log('- Username:', loginData.username);
|
|
||||||
console.log('- Vérifiez le mot de passe manuellement');
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
console.error('❌ Erreur login:', error.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. Test route /api/admin/users
|
|
||||||
console.log('\n2. Test route admin users...');
|
|
||||||
console.log('GET /api/admin/users');
|
|
||||||
console.log('- Route nécessite role: administrator');
|
|
||||||
console.log('- Utilisateur gael doit avoir store_id = NULL');
|
|
||||||
|
|
||||||
// 3. Test route /api/auth/me
|
|
||||||
console.log('\n3. Test informations utilisateur...');
|
|
||||||
console.log('GET /api/auth/me');
|
|
||||||
console.log('- Doit retourner role: administrator');
|
|
||||||
console.log('- Doit retourner storeId: null');
|
|
||||||
|
|
||||||
console.log('\n📋 COMMANDES DE DIAGNOSTIC PRODUCTION:');
|
|
||||||
console.log('=====================================');
|
|
||||||
|
|
||||||
console.log('\n# 1. Vérifier l\'état de l\'utilisateur admin:');
|
|
||||||
console.log('docker exec regisflow-regisflow-1 psql -U regisflow -d regisflow -c "SELECT id, username, role, store_id FROM users WHERE username = \'gael\';"');
|
|
||||||
|
|
||||||
console.log('\n# 2. Tester la route d\'administration:');
|
|
||||||
console.log('curl -X POST http://votre-domaine:5000/api/auth/login \\');
|
|
||||||
console.log(' -H "Content-Type: application/json" \\');
|
|
||||||
console.log(' -d \'{"username":"gael","password":"votre_mot_de_passe"}\' \\');
|
|
||||||
console.log(' -c /tmp/admin_test.txt');
|
|
||||||
|
|
||||||
console.log('\ncurl http://votre-domaine:5000/api/admin/users \\');
|
|
||||||
console.log(' -b /tmp/admin_test.txt');
|
|
||||||
|
|
||||||
console.log('\n# 3. Vérifier les logs de l\'application:');
|
|
||||||
console.log('docker logs regisflow-regisflow-1 --tail 50');
|
|
||||||
|
|
||||||
console.log('\n# 4. Si problème de permissions, corriger:');
|
|
||||||
console.log('docker exec regisflow-regisflow-1 psql -U regisflow -d regisflow -c "UPDATE users SET role = \'administrator\', store_id = NULL WHERE username = \'gael\';"');
|
|
||||||
console.log('docker restart regisflow-regisflow-1');
|
|
||||||
|
|
||||||
console.log('\n✅ RÉSULTATS ATTENDUS:');
|
|
||||||
console.log('- /api/admin/users retourne un tableau JSON des utilisateurs');
|
|
||||||
console.log('- Interface d\'administration affiche la liste');
|
|
||||||
console.log('- Pas d\'erreur "Insufficient permissions"');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Exécuter le diagnostic
|
|
||||||
testAdminRoutes().catch(console.error);
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -e
|
|
||||||
|
|
||||||
echo "🚀 RegisFlow Docker entrypoint started (Production v2025)"
|
|
||||||
|
|
||||||
# Vérifier les variables d'environnement essentielles
|
|
||||||
if [ -z "$DATABASE_URL" ]; then
|
|
||||||
echo "❌ ERROR: DATABASE_URL environment variable is not set"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$SESSION_SECRET" ]; then
|
|
||||||
echo "⚠️ WARNING: SESSION_SECRET not set, using default (not recommended for production)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "📊 Environment configured - NODE_ENV: $NODE_ENV"
|
|
||||||
echo "🗄️ Database URL configured"
|
|
||||||
echo "🌍 Timezone: $TZ"
|
|
||||||
|
|
||||||
# Patch pour Node.js compatibility (import.meta.dirname)
|
|
||||||
if [ -f "dist/index.js" ] && ! grep -q "__dirname" dist/index.js; then
|
|
||||||
echo "🔧 Applying Node.js compatibility patch..."
|
|
||||||
sed -i 's|import\.meta\.dirname|process.cwd()|g' dist/index.js
|
|
||||||
echo "✅ Compatibility patch applied"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Extraction des informations de connexion pour pg_isready
|
|
||||||
DB_HOST=$(echo $DATABASE_URL | sed -n 's|.*@\([^:/]*\).*|\1|p')
|
|
||||||
DB_PORT=$(echo $DATABASE_URL | sed -n 's|.*:\([0-9]*\)/.*|\1|p')
|
|
||||||
DB_USER=$(echo $DATABASE_URL | sed -n 's|.*://\([^:]*\):.*|\1|p')
|
|
||||||
|
|
||||||
echo "🔗 Connecting to: $DB_HOST:${DB_PORT:-5432}"
|
|
||||||
|
|
||||||
# Attendre que la base de données soit prête avec retry amélioré
|
|
||||||
echo "⏳ Waiting for database to be ready..."
|
|
||||||
timeout=90
|
|
||||||
while ! pg_isready -h "$DB_HOST" -p "${DB_PORT:-5432}" -U "$DB_USER" -q && [ $timeout -gt 0 ]; do
|
|
||||||
echo "Database not ready, waiting... ($timeout seconds left)"
|
|
||||||
sleep 3
|
|
||||||
timeout=$((timeout-3))
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ $timeout -le 0 ]; then
|
|
||||||
echo "❌ Database connection timeout after 90 seconds"
|
|
||||||
echo "🔍 Debug info:"
|
|
||||||
echo " HOST: $DB_HOST"
|
|
||||||
echo " PORT: ${DB_PORT:-5432}"
|
|
||||||
echo " USER: $DB_USER"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "✅ Database is ready and accessible"
|
|
||||||
|
|
||||||
# Créer les répertoires nécessaires
|
|
||||||
mkdir -p /app/logs /app/backups
|
|
||||||
echo "📁 Created application directories"
|
|
||||||
|
|
||||||
# Exécuter les migrations de base de données
|
|
||||||
echo "🔄 Running database migrations..."
|
|
||||||
if npm run db:push; then
|
|
||||||
echo "✅ Database migrations completed successfully"
|
|
||||||
else
|
|
||||||
echo "❌ Database migration failed"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Vérification des permissions et de l'espace disque
|
|
||||||
echo "🔍 System checks:"
|
|
||||||
echo " Disk space: $(df -h /app | tail -1 | awk '{print $4}') available"
|
|
||||||
echo " Memory: $(free -h | grep Mem | awk '{print $7}') available"
|
|
||||||
echo " User: $(whoami)"
|
|
||||||
|
|
||||||
# Démarrer l'application
|
|
||||||
echo "🌟 Starting RegisFlow application on port $PORT..."
|
|
||||||
echo "🏥 Health check available at: http://localhost:$PORT/health"
|
|
||||||
exec npm start
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -e
|
|
||||||
|
|
||||||
echo "🐳 RegisFlow Docker Quick Test"
|
|
||||||
echo "=============================="
|
|
||||||
|
|
||||||
# Nettoyer les anciens containers
|
|
||||||
echo "🧹 Cleaning up existing containers..."
|
|
||||||
docker-compose down -v 2>/dev/null || true
|
|
||||||
docker system prune -f >/dev/null 2>&1 || true
|
|
||||||
|
|
||||||
# Test de build avec l'approche simplifiée (skip migrations)
|
|
||||||
echo "🔨 Building fresh Docker image (simple approach - skip migrations)..."
|
|
||||||
if docker-compose build --no-cache regisflow; then
|
|
||||||
echo "✅ Build successful"
|
|
||||||
else
|
|
||||||
echo "❌ Build failed"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Créer .env.production si nécessaire
|
|
||||||
if [[ ! -f ".env.production" ]]; then
|
|
||||||
echo "📝 Creating .env.production from example..."
|
|
||||||
cp .env.production.example .env.production
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Test de démarrage
|
|
||||||
echo "🚀 Starting containers..."
|
|
||||||
if docker-compose up -d; then
|
|
||||||
echo "✅ Containers started"
|
|
||||||
|
|
||||||
# Attendre l'application
|
|
||||||
echo "⏳ Waiting for application..."
|
|
||||||
for i in {1..30}; do
|
|
||||||
if curl -s http://localhost:5000/health >/dev/null 2>&1; then
|
|
||||||
echo "✅ Application is responding!"
|
|
||||||
echo "🏥 Health: $(curl -s http://localhost:5000/health | grep -o '"status":"[^"]*"' || echo 'OK')"
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
echo " Attempt $i/30..."
|
|
||||||
sleep 2
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ $i -eq 30 ]; then
|
|
||||||
echo "❌ Application timeout"
|
|
||||||
echo "📋 Recent logs:"
|
|
||||||
docker-compose logs --tail=10 regisflow
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
else
|
|
||||||
echo "❌ Container startup failed"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "🎉 SUCCESS! RegisFlow is running"
|
|
||||||
echo "================================"
|
|
||||||
echo "Access: http://localhost:5000"
|
|
||||||
echo "Admin: admin / admin123"
|
|
||||||
echo ""
|
|
||||||
echo "To stop: docker-compose down"
|
|
||||||
echo "To see logs: docker-compose logs -f"
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
-- CORRECTION URGENTE ADMIN PRODUCTION
|
|
||||||
-- Exécuter sur la base de production
|
|
||||||
|
|
||||||
-- 1. Vérifier l'utilisateur problématique (ID 3 d'après les logs)
|
|
||||||
SELECT id, username, email, role, store_id FROM users WHERE id = 3;
|
|
||||||
|
|
||||||
-- 2. Corriger le rôle de l'utilisateur ID 3
|
|
||||||
UPDATE users SET role = 'administrator' WHERE id = 3 AND username = 'admin';
|
|
||||||
|
|
||||||
-- 3. Vérifier si correction appliquée
|
|
||||||
SELECT id, username, email, role, store_id FROM users WHERE id = 3;
|
|
||||||
|
|
||||||
-- 4. Nettoyer les sessions problématiques
|
|
||||||
DELETE FROM sessions WHERE data LIKE '%"id":3%' AND data NOT LIKE '%"role":"administrator"%';
|
|
||||||
|
|
||||||
-- 5. Vérifier tous les utilisateurs admin
|
|
||||||
SELECT id, username, email, role, store_id FROM users WHERE role = 'administrator';
|
|
||||||
|
|
||||||
-- 6. Forcer création admin backup si nécessaire
|
|
||||||
INSERT INTO users (username, password, email, first_name, last_name, role, store_id, is_active, created_at, updated_at)
|
|
||||||
VALUES ('admin_backup', '$2b$12$LQv3c1yqBwuvHi44M0Bfa.5jW.5J5J5J5J5J5J5J5J5J5J5J5J5J5J', 'admin_backup@regisflow.com', 'Admin', 'Backup', 'administrator', NULL, true, NOW(), NOW())
|
|
||||||
ON CONFLICT (username) DO NOTHING;
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
-- Script pour corriger le rôle admin en production
|
|
||||||
-- Ce script doit être exécuté sur la base de données de production
|
|
||||||
|
|
||||||
-- Vérifier tous les utilisateurs admin
|
|
||||||
SELECT id, username, role, email FROM users WHERE username = 'admin';
|
|
||||||
|
|
||||||
-- Mettre à jour tous les utilisateurs admin vers le rôle 'administrator'
|
|
||||||
UPDATE users SET role = 'administrator' WHERE username = 'admin' AND role = 'admin';
|
|
||||||
|
|
||||||
-- Vérifier que la mise à jour a fonctionné
|
|
||||||
SELECT id, username, role, email FROM users WHERE username = 'admin';
|
|
||||||
|
|
||||||
-- Vérifier que les routes admin fonctionnent (permissions)
|
|
||||||
SELECT COUNT(*) as total_users FROM users;
|
|
||||||
SELECT COUNT(*) as admin_users FROM users WHERE role = 'administrator';
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
-- CORRECTION COMPLÈTE PRODUCTION - Tous les problèmes identifiés
|
|
||||||
-- Exécuter ces commandes dans la base de données production
|
|
||||||
|
|
||||||
-- 1. Corriger l'utilisateur admin (ID 3) - permissions complètes
|
|
||||||
UPDATE users
|
|
||||||
SET role = 'administrator', store_id = NULL
|
|
||||||
WHERE id = 3 AND username = 'gael';
|
|
||||||
|
|
||||||
-- 2. Vérifier que la correction a bien été appliquée
|
|
||||||
SELECT 'UTILISATEUR ADMIN CORRIGÉ:' as status,
|
|
||||||
id, username, role, store_id
|
|
||||||
FROM users
|
|
||||||
WHERE id = 3;
|
|
||||||
|
|
||||||
-- 3. Vérifier tous les magasins disponibles
|
|
||||||
SELECT 'MAGASINS DISPONIBLES:' as info,
|
|
||||||
id, name, is_active
|
|
||||||
FROM stores
|
|
||||||
ORDER BY id;
|
|
||||||
|
|
||||||
-- 4. Vérifier la répartition des ventes par magasin
|
|
||||||
SELECT 'RÉPARTITION DES VENTES:' as info,
|
|
||||||
store_id,
|
|
||||||
COUNT(*) as total_ventes,
|
|
||||||
MAX(timestamp) as derniere_vente
|
|
||||||
FROM sales
|
|
||||||
GROUP BY store_id
|
|
||||||
ORDER BY store_id;
|
|
||||||
|
|
||||||
-- 5. Test de permissions (à exécuter après redémarrage de l'application)
|
|
||||||
-- curl -X POST http://votre-domaine:5000/api/auth/login \
|
|
||||||
-- -H "Content-Type: application/json" \
|
|
||||||
-- -d '{"username":"gael","password":"votre_mot_de_passe"}'
|
|
||||||
--
|
|
||||||
-- curl http://votre-domaine:5000/api/stores -H "Cookie: session_cookie"
|
|
||||||
-- (Devrait retourner tous les magasins)
|
|
||||||
--
|
|
||||||
-- curl http://votre-domaine:5000/api/sales?storeId=2 -H "Cookie: session_cookie"
|
|
||||||
-- (Devrait retourner les ventes du magasin Houdemont)
|
|
||||||
|
|
||||||
-- RÉSULTATS ATTENDUS APRÈS APPLICATION :
|
|
||||||
-- ✅ Magasins : Admin voit Frouard ET Houdemont dans le sélecteur
|
|
||||||
-- ✅ Création : Ventes créées sur le magasin sélectionné (pas toujours Frouard)
|
|
||||||
-- ✅ Historique : Affichage des ventes du magasin sélectionné
|
|
||||||
-- ✅ Suppression : Les ventes peuvent être supprimées par l'admin
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
echo "🔧 CORRECTION PRODUCTION - Problème sélecteur magasin"
|
|
||||||
echo "=================================================="
|
|
||||||
|
|
||||||
# Commande pour corriger l'utilisateur admin en production
|
|
||||||
echo ""
|
|
||||||
echo "1. Corriger l'utilisateur admin (ID 3 - gael) :"
|
|
||||||
echo "docker exec regisflow-regisflow-1 psql -U regisflow -d regisflow -c \"UPDATE users SET role = 'administrator', store_id = NULL WHERE id = 3;\""
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "2. Vérifier la correction :"
|
|
||||||
echo "docker exec regisflow-regisflow-1 psql -U regisflow -d regisflow -c \"SELECT id, username, role, store_id FROM users WHERE id = 3;\""
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "3. Redémarrer l'application :"
|
|
||||||
echo "docker restart regisflow-regisflow-1"
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "4. Test API après correction :"
|
|
||||||
echo "curl -X POST http://votre-domaine:5000/api/auth/login -H \"Content-Type: application/json\" -d '{\"username\":\"gael\",\"password\":\"mot_de_passe\"}''"
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "RÉSULTAT ATTENDU : L'admin verra tous les magasins et pourra filtrer les ventes correctement."
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
-- CORRECTION IMMÉDIATE ADMIN PRODUCTION
|
|
||||||
-- Basé sur les logs: l'utilisateur admin a l'ID 3 avec email tronqué
|
|
||||||
|
|
||||||
-- 1. Identifier l'utilisateur problématique
|
|
||||||
SELECT 'AVANT CORRECTION:' as status, id, username, email, role, store_id FROM users WHERE username = 'admin';
|
|
||||||
|
|
||||||
-- 2. CORRECTION FORCÉE: Mettre à jour TOUS les utilisateurs admin vers administrator
|
|
||||||
UPDATE users SET role = 'administrator' WHERE username = 'admin';
|
|
||||||
|
|
||||||
-- 3. CORRECTION SPÉCIFIQUE: Forcer l'utilisateur ID 3 (celui des logs de production)
|
|
||||||
UPDATE users SET role = 'administrator', email = 'admin@regisflow.com' WHERE id = 3;
|
|
||||||
|
|
||||||
-- 4. Vérifier la correction
|
|
||||||
SELECT 'APRÈS CORRECTION:' as status, id, username, email, role, store_id FROM users WHERE username = 'admin';
|
|
||||||
|
|
||||||
-- 5. Nettoyer les sessions avec mauvais rôle
|
|
||||||
DELETE FROM sessions WHERE data LIKE '%"id":3%' AND data NOT LIKE '%"role":"administrator"%';
|
|
||||||
|
|
||||||
-- 6. Afficher tous les administrateurs
|
|
||||||
SELECT 'TOUS LES ADMIN:' as status, id, username, email, role FROM users WHERE role = 'administrator';
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
-- Migration pour les ventes multi-produits
|
|
||||||
-- Cette migration convertit les ventes existantes vers le nouveau système
|
|
||||||
|
|
||||||
-- 1. Créer la nouvelle table sale_products
|
|
||||||
CREATE TABLE IF NOT EXISTS sale_products (
|
|
||||||
id SERIAL PRIMARY KEY,
|
|
||||||
sale_id INTEGER REFERENCES sales(id) ON DELETE CASCADE NOT NULL,
|
|
||||||
type_article VARCHAR(255) NOT NULL,
|
|
||||||
categorie VARCHAR(2) NOT NULL,
|
|
||||||
quantite INTEGER NOT NULL,
|
|
||||||
gencode VARCHAR(13) NOT NULL,
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
||||||
);
|
|
||||||
|
|
||||||
-- 2. Migrer les données existantes des ventes vers sale_products
|
|
||||||
INSERT INTO sale_products (sale_id, type_article, categorie, quantite, gencode)
|
|
||||||
SELECT
|
|
||||||
id,
|
|
||||||
type_article,
|
|
||||||
categorie,
|
|
||||||
quantite,
|
|
||||||
gencode
|
|
||||||
FROM sales
|
|
||||||
WHERE type_article IS NOT NULL;
|
|
||||||
|
|
||||||
-- 3. Supprimer les colonnes produit de la table sales (après migration réussie)
|
|
||||||
-- Ces commandes seront exécutées après validation de la migration
|
|
||||||
-- ALTER TABLE sales DROP COLUMN type_article;
|
|
||||||
-- ALTER TABLE sales DROP COLUMN categorie;
|
|
||||||
-- ALTER TABLE sales DROP COLUMN quantite;
|
|
||||||
-- ALTER TABLE sales DROP COLUMN gencode;
|
|
||||||
|
|
||||||
-- 4. Créer les index pour optimiser les recherches
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_sale_products_sale_id ON sale_products(sale_id);
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_sale_products_gencode ON sale_products(gencode);
|
|
||||||
|
|
||||||
-- 5. Ajouter les contraintes
|
|
||||||
ALTER TABLE sale_products ADD CONSTRAINT chk_sale_products_categorie
|
|
||||||
CHECK (categorie IN ('F2', 'F3'));
|
|
||||||
|
|
||||||
-- 6. Mettre à jour les séquences
|
|
||||||
SELECT setval('sale_products_id_seq', (SELECT COALESCE(MAX(id), 1) FROM sale_products));
|
|
||||||
@@ -358,6 +358,8 @@ Preferred communication style: Simple, everyday language.
|
|||||||
- ✅ **Database Permissions Validated**: All admin operations functional after role corrections
|
- ✅ **Database Permissions Validated**: All admin operations functional after role corrections
|
||||||
- ✅ **Session Management Fixed**: Application restart resolved authentication state issues
|
- ✅ **Session Management Fixed**: Application restart resolved authentication state issues
|
||||||
- ✅ **Production Stability Confirmed**: All core features operational in production environment
|
- ✅ **Production Stability Confirmed**: All core features operational in production environment
|
||||||
|
- ✅ **Project Cleanup**: Removed unused fix-* files and cleared attached_assets directory
|
||||||
|
- ✅ **Complete Cleanup**: Removed all temporary production debug files, migration scripts, and alternative Docker files
|
||||||
|
|
||||||
### Previous Docker Issues (January 13, 2025)
|
### Previous Docker Issues (January 13, 2025)
|
||||||
- ✅ Resolved cache corruption errors during Docker deployment
|
- ✅ Resolved cache corruption errors during Docker deployment
|
||||||
|
|||||||
@@ -1,191 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
echo "🚀 RegisFlow Docker Deployment Test"
|
|
||||||
echo "==================================="
|
|
||||||
|
|
||||||
# Fonction de test des prérequis
|
|
||||||
check_prerequisites() {
|
|
||||||
echo "📋 Checking prerequisites..."
|
|
||||||
|
|
||||||
# Docker
|
|
||||||
if ! command -v docker &> /dev/null; then
|
|
||||||
echo "❌ Docker not found. Please install Docker."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Docker Compose
|
|
||||||
if ! command -v docker-compose &> /dev/null; then
|
|
||||||
echo "❌ Docker Compose not found. Please install Docker Compose."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "✅ Docker and Docker Compose are available"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Fonction de validation des fichiers
|
|
||||||
check_files() {
|
|
||||||
echo "📁 Checking required files..."
|
|
||||||
|
|
||||||
required_files=(
|
|
||||||
"Dockerfile"
|
|
||||||
"docker-compose.yml"
|
|
||||||
"docker-entrypoint.sh"
|
|
||||||
".env.production.example"
|
|
||||||
"package.json"
|
|
||||||
)
|
|
||||||
|
|
||||||
for file in "${required_files[@]}"; do
|
|
||||||
if [[ ! -f "$file" ]]; then
|
|
||||||
echo "❌ Missing required file: $file"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "✅ All required files are present"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Test de build Docker
|
|
||||||
test_docker_build() {
|
|
||||||
echo "🔨 Testing Docker build..."
|
|
||||||
|
|
||||||
if docker-compose build --no-cache regisflow; then
|
|
||||||
echo "✅ Docker build successful"
|
|
||||||
else
|
|
||||||
echo "❌ Docker build failed"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Test de configuration
|
|
||||||
test_configuration() {
|
|
||||||
echo "⚙️ Testing configuration..."
|
|
||||||
|
|
||||||
if [[ ! -f ".env.production" ]]; then
|
|
||||||
echo "⚠️ .env.production not found, creating from example..."
|
|
||||||
cp .env.production.example .env.production
|
|
||||||
echo "📝 Please edit .env.production with your secure credentials!"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Vérifier que les variables critiques ne sont pas par défaut
|
|
||||||
if grep -q "CHANGEME" .env.production; then
|
|
||||||
echo "⚠️ WARNING: Default passwords detected in .env.production"
|
|
||||||
echo " Please change POSTGRES_PASSWORD and SESSION_SECRET"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "✅ Configuration checked"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Test de démarrage rapide
|
|
||||||
test_startup() {
|
|
||||||
echo "🚦 Testing container startup..."
|
|
||||||
|
|
||||||
# Nettoyer d'abord
|
|
||||||
docker-compose down -v 2>/dev/null
|
|
||||||
|
|
||||||
# Démarrer en mode détaché
|
|
||||||
if docker-compose up -d; then
|
|
||||||
echo "✅ Containers started successfully"
|
|
||||||
|
|
||||||
# Attendre que l'application soit prête
|
|
||||||
echo "⏳ Waiting for application to be ready..."
|
|
||||||
timeout=60
|
|
||||||
while ! curl -s http://localhost:5000/health >/dev/null && [ $timeout -gt 0 ]; do
|
|
||||||
echo " Waiting... ($timeout seconds left)"
|
|
||||||
sleep 2
|
|
||||||
timeout=$((timeout-2))
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ $timeout -gt 0 ]; then
|
|
||||||
echo "✅ Application is responding"
|
|
||||||
echo "🏥 Health check: $(curl -s http://localhost:5000/health | grep -o '"status":"[^"]*"')"
|
|
||||||
else
|
|
||||||
echo "❌ Application startup timeout"
|
|
||||||
echo "📋 Container logs:"
|
|
||||||
docker-compose logs --tail=20 regisflow
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
else
|
|
||||||
echo "❌ Container startup failed"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Test de connexion base de données
|
|
||||||
test_database() {
|
|
||||||
echo "🗄️ Testing database connection..."
|
|
||||||
|
|
||||||
if docker exec regisflow-db pg_isready -U regisflow -q; then
|
|
||||||
echo "✅ Database is accessible"
|
|
||||||
|
|
||||||
# Tester les tables
|
|
||||||
tables=$(docker exec regisflow-db psql -U regisflow -t -c "\dt" | wc -l)
|
|
||||||
echo "📊 Database has $tables tables"
|
|
||||||
|
|
||||||
else
|
|
||||||
echo "❌ Database connection failed"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Fonction de nettoyage
|
|
||||||
cleanup() {
|
|
||||||
echo "🧹 Cleaning up test containers..."
|
|
||||||
docker-compose down -v
|
|
||||||
echo "✅ Cleanup completed"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Test complet
|
|
||||||
run_full_test() {
|
|
||||||
check_prerequisites
|
|
||||||
check_files
|
|
||||||
test_configuration
|
|
||||||
test_docker_build
|
|
||||||
test_startup
|
|
||||||
test_database
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "🎉 ALL TESTS PASSED!"
|
|
||||||
echo "===================="
|
|
||||||
echo "RegisFlow is ready for production deployment"
|
|
||||||
echo ""
|
|
||||||
echo "Next steps:"
|
|
||||||
echo "1. Edit .env.production with secure credentials"
|
|
||||||
echo "2. Run: docker-compose up -d"
|
|
||||||
echo "3. Access: http://localhost:5000"
|
|
||||||
echo "4. Monitor: docker-compose logs -f"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
cleanup
|
|
||||||
}
|
|
||||||
|
|
||||||
# Exécuter le test ou afficher l'aide
|
|
||||||
case "${1:-test}" in
|
|
||||||
"test")
|
|
||||||
run_full_test
|
|
||||||
;;
|
|
||||||
"build")
|
|
||||||
check_prerequisites
|
|
||||||
check_files
|
|
||||||
test_docker_build
|
|
||||||
;;
|
|
||||||
"health")
|
|
||||||
curl -s http://localhost:5000/health | python3 -m json.tool || echo "Application not running"
|
|
||||||
;;
|
|
||||||
"cleanup")
|
|
||||||
cleanup
|
|
||||||
;;
|
|
||||||
"help")
|
|
||||||
echo "Usage: $0 [test|build|health|cleanup|help]"
|
|
||||||
echo " test - Run full deployment test (default)"
|
|
||||||
echo " build - Test Docker build only"
|
|
||||||
echo " health - Check application health"
|
|
||||||
echo " cleanup - Clean up test containers"
|
|
||||||
echo " help - Show this help"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Unknown option: $1"
|
|
||||||
echo "Use '$0 help' for usage information"
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||