diff --git a/PRODUCTION_URGENT_FIX.md b/PRODUCTION_URGENT_FIX.md new file mode 100644 index 0000000..b863a81 --- /dev/null +++ b/PRODUCTION_URGENT_FIX.md @@ -0,0 +1,38 @@ +# CORRECTION URGENTE PRODUCTION - PROBLÈME SÉLECTEUR MAGASIN + +## Problème identifié +- Ventes créées sur Houdemont (ID 2) mais affichées sur Frouard (ID 1) +- L'admin en production (ID 3, "gael") n'a pas accès aux bons magasins +- Sélecteur de magasin ne fonctionne pas correctement + +## Solutions immédiates + +### 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. Vérifier et corriger les permissions +```bash +# Connexion à la base de production +docker exec regisflow-regisflow-1 psql -U regisflow -d regisflow +``` + +### 3. Commandes SQL directes +```sql +-- 1. Vérifier l'utilisateur problématique +SELECT id, username, role, store_id FROM users WHERE id = 3; + +-- 2. Corriger les droits admin +UPDATE users SET role = 'administrator', store_id = NULL WHERE id = 3 AND username = 'gael'; + +-- 3. Vérifier tous les magasins +SELECT * FROM stores ORDER BY id; + +-- 4. Vérifier les ventes par magasin +SELECT store_id, COUNT(*) as total FROM sales GROUP BY store_id; +``` + +## Résultats attendus +Après correction, l'admin devrait voir tous les magasins et pouvoir filtrer les ventes correctement. \ No newline at end of file diff --git a/attached_assets/Pasted-PM-express-GET-api-auth-me-304-in-19ms-id-3-username-admin-email-admin-examp-6-0-1752941591563_1752941591564.txt b/attached_assets/Pasted-PM-express-GET-api-auth-me-304-in-19ms-id-3-username-admin-email-admin-examp-6-0-1752941591563_1752941591564.txt new file mode 100644 index 0000000..9daab91 --- /dev/null +++ b/attached_assets/Pasted-PM-express-GET-api-auth-me-304-in-19ms-id-3-username-admin-email-admin-examp-6-0-1752941591563_1752941591564.txt @@ -0,0 +1,61 @@ +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… \ No newline at end of file diff --git a/fix-production-stores.sh b/fix-production-stores.sh new file mode 100644 index 0000000..8c695ef --- /dev/null +++ b/fix-production-stores.sh @@ -0,0 +1,24 @@ +#!/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." \ No newline at end of file diff --git a/server/routes.ts b/server/routes.ts index e5e3501..54547e9 100644 --- a/server/routes.ts +++ b/server/routes.ts @@ -198,7 +198,18 @@ export async function registerRoutes(app: Express): Promise { app.get('/api/stores', requireAuth, async (req, res) => { try { const user = await storage.getUser(req.session.userId!); - if (!user || !user.storeId) { + if (!user) { + return res.status(404).json({ error: "User not found" }); + } + + // Administrators can access all stores + if (user.role === 'administrator') { + const allStores = await storage.getAllStores(); + return res.json(allStores); + } + + // Non-administrators only access their assigned store + if (!user.storeId) { return res.status(404).json({ error: "User store not found" }); } @@ -232,7 +243,7 @@ export async function registerRoutes(app: Express): Promise { targetStoreId = parseInt(storeId as string); // For non-admin users, verify they can only access their own store - if (user.role !== 'admin' && targetStoreId !== user.storeId) { + if (user.role !== 'administrator' && targetStoreId !== user.storeId) { return res.status(403).json({ error: "Access denied to this store" }); } } else { @@ -264,7 +275,7 @@ export async function registerRoutes(app: Express): Promise { // Determine which store to use for the sale let targetStoreId: number; - if (user.role === 'admin' && req.body.storeId) { + if (user.role === 'administrator' && req.body.storeId) { // Admin can create sales for any store targetStoreId = req.body.storeId; } else {