Give administrators access to all stores and fix store selector

Updates user role checks and store access logic in /api/stores route, adds a fix script.

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/496YcVj
This commit is contained in:
michaelschal committed 2025-07-19 16:17:15 +00:00
1 parent 87722d8132
commit c909650566
4 files changed
+137 -3

No files matched your search

+38
View File
@@ -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.
@@ -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…
+24
View File
@@ -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."
+14 -3
View File
@@ -198,7 +198,18 @@ export async function registerRoutes(app: Express): Promise<Server> {
app.get('/api/stores', requireAuth, async (req, res) => { app.get('/api/stores', requireAuth, async (req, res) => {
try { try {
const user = await storage.getUser(req.session.userId!); 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" }); return res.status(404).json({ error: "User store not found" });
} }
@@ -232,7 +243,7 @@ export async function registerRoutes(app: Express): Promise<Server> {
targetStoreId = parseInt(storeId as string); targetStoreId = parseInt(storeId as string);
// For non-admin users, verify they can only access their own store // 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" }); return res.status(403).json({ error: "Access denied to this store" });
} }
} else { } else {
@@ -264,7 +275,7 @@ export async function registerRoutes(app: Express): Promise<Server> {
// Determine which store to use for the sale // Determine which store to use for the sale
let targetStoreId: number; let targetStoreId: number;
if (user.role === 'admin' && req.body.storeId) { if (user.role === 'administrator' && req.body.storeId) {
// Admin can create sales for any store // Admin can create sales for any store
targetStoreId = req.body.storeId; targetStoreId = req.body.storeId;
} else { } else {