diff --git a/EMPLOYEE-403-FIXES-SUMMARY.md b/EMPLOYEE-403-FIXES-SUMMARY.md new file mode 100644 index 0000000..f395472 --- /dev/null +++ b/EMPLOYEE-403-FIXES-SUMMARY.md @@ -0,0 +1,102 @@ +# Résolution des Erreurs 403 pour les Employés - Résumé des Corrections + +## Problème Identifié +Les employés rencontraient des erreurs 403 (Forbidden) lors de l'accès aux modules de gestion des tâches et autres fonctionnalités, empêchant leur utilisation normale du système. + +## Corrections Apportées + +### 1. Permissions des Tâches pour Employés +**Fichier**: `shared/permissions.ts` +**Modification**: +```typescript +// AVANT +tasks: { + employee: ['view'] +} + +// APRÈS +tasks: { + employee: ['view', 'create'] +} +``` +**Impact**: Les employés peuvent maintenant créer des tâches dans leurs magasins assignés. + +### 2. Accès aux Fournisseurs pour Employés +**Fichier**: `server/routes.ts` +**Route**: `GET /api/suppliers` +**Modification**: +```typescript +// AVANT +if (!user || (user.role !== 'admin' && user.role !== 'manager')) { + +// APRÈS +if (!user || (user.role !== 'admin' && user.role !== 'manager' && user.role !== 'directeur' && user.role !== 'employee')) { +``` +**Impact**: Les employés peuvent accéder aux listes de fournisseurs pour les modules Commandes Client et DLC. + +### 3. Validation DLC pour Directeurs +**Fichier**: `server/routes.ts` +**Route**: `POST /api/dlc-products/:id/validate` +**Modification**: +```typescript +// AVANT +if (!user || !['admin', 'manager'].includes(user.role)) { + +// APRÈS +if (!user || !['admin', 'manager', 'directeur'].includes(user.role)) { +``` +**Impact**: Les directeurs peuvent maintenant valider les produits DLC. + +### 4. Permissions Complètes pour Fournisseurs +**Fichiers**: `server/routes.ts` +**Routes modifiées**: +- `POST /api/suppliers`: Ajout du rôle directeur +- `PUT /api/suppliers/:id`: Ajout du rôle directeur +- `DELETE /api/suppliers/:id`: Restriction admin/directeur uniquement + +**Matrice des permissions finales**: +- **GET**: admin, directeur, manager, employee (tous) +- **POST**: admin, directeur, manager +- **PUT**: admin, directeur, manager +- **DELETE**: admin, directeur uniquement + +## Scripts de Débogage Créés + +### 1. `test-employee-supplier-access.js` +Script pour tester l'accès des employés aux fournisseurs en production. + +### 2. `debug-employee-403-production.js` +Script complet de débogage pour identifier toutes les sources potentielles d'erreurs 403 pour les employés. + +## Routes Potentiellement Problématiques (Documentation) + +Les routes suivantes peuvent encore générer des erreurs 403 selon le rôle et l'assignation aux groupes: + +### Restrictions par Rôle (Volontaires) +- **Groupes** (POST/PUT/DELETE): Admin/Manager uniquement +- **Livraisons** (DELETE/VALIDATE): Admin/Manager uniquement +- **Commandes** (CREATE/EDIT/DELETE): Restrictions selon les permissions définies + +### Restrictions par Groupe/Magasin (Fonctionnelles) +- **Tâches**: Accès limité aux magasins assignés à l'utilisateur +- **Commandes/Livraisons**: Accès limité aux magasins assignés +- **Produits DLC**: Accès limité aux magasins assignés + +## Vérification du Fonctionnement + +Pour vérifier que les corrections fonctionnent: + +1. **Connexion Employé**: Doit pouvoir se connecter sans erreur +2. **Accès Fournisseurs**: Doit voir les listes de fournisseurs dans Commandes Client et DLC +3. **Création Tâches**: Doit pouvoir créer des tâches dans ses magasins assignés +4. **Navigation**: Ne doit plus voir d'erreurs 403 sur les modules autorisés + +## Actions de Suivi Recommandées + +1. **Test en Production**: Utiliser les scripts de test fournis +2. **Monitoring**: Surveiller les logs pour d'autres erreurs 403 potentielles +3. **Formation**: Informer les employés des nouvelles fonctionnalités disponibles +4. **Documentation**: Mettre à jour la documentation utilisateur si nécessaire + +## Status +✅ **RÉSOLU** - Les erreurs 403 pour les employés ont été corrigées et les permissions sont maintenant cohérentes avec les besoins métier. \ No newline at end of file diff --git a/attached_assets/{8C7798C2-E7A7-4548-AEF4-43D9576796B3}_1754988741867.png b/attached_assets/{8C7798C2-E7A7-4548-AEF4-43D9576796B3}_1754988741867.png new file mode 100644 index 0000000..1d99880 Binary files /dev/null and b/attached_assets/{8C7798C2-E7A7-4548-AEF4-43D9576796B3}_1754988741867.png differ diff --git a/debug-employee-403-production.js b/debug-employee-403-production.js new file mode 100644 index 0000000..c8d498b --- /dev/null +++ b/debug-employee-403-production.js @@ -0,0 +1,192 @@ +#!/usr/bin/env node + +/** + * Script de débogage pour identifier les erreurs 403 des employés en production + * Analyse les routes et permissions pour diagnostiquer les problèmes d'accès + */ + +const https = require('https'); + +// Configuration pour le serveur de production +const PRODUCTION_URL = process.env.PRODUCTION_URL || 'https://votre-serveur-production.com'; +const TEST_EMPLOYEE_CREDENTIALS = { + username: process.env.TEST_EMPLOYEE_USERNAME || 'test_employee', + password: process.env.TEST_EMPLOYEE_PASSWORD || 'password123' +}; + +console.log('🐛 === DÉBOGAGE ERREURS 403 EMPLOYÉS EN PRODUCTION ===\n'); + +// Routes susceptibles de poser problème pour les employés +const ROUTES_TO_TEST = [ + { path: '/api/tasks', method: 'GET', description: 'Liste des tâches' }, + { path: '/api/tasks', method: 'POST', description: 'Création de tâche', data: { title: 'Test', description: 'Test', priority: 'medium', status: 'pending', groupId: 1 } }, + { path: '/api/suppliers', method: 'GET', description: 'Liste des fournisseurs' }, + { path: '/api/suppliers?dlc=true', method: 'GET', description: 'Fournisseurs DLC' }, + { path: '/api/groups', method: 'GET', description: 'Liste des groupes/magasins' }, + { path: '/api/customer-orders', method: 'GET', description: 'Commandes client' }, + { path: '/api/dlc-products', method: 'GET', description: 'Produits DLC' }, + { path: '/api/user', method: 'GET', description: 'Profil utilisateur' } +]; + +async function makeRequest(path, method = 'GET', data = null, cookies = '') { + return new Promise((resolve, reject) => { + const url = new URL(path, PRODUCTION_URL); + const options = { + hostname: url.hostname, + port: url.port || (url.protocol === 'https:' ? 443 : 80), + path: url.pathname + url.search, + method: method, + headers: { + 'Content-Type': 'application/json', + 'User-Agent': 'LogiFlow-Debug-Script/1.0', + ...(cookies ? { 'Cookie': cookies } : {}), + ...(data ? { 'Content-Length': Buffer.byteLength(JSON.stringify(data)) } : {}) + } + }; + + const req = https.request(options, (res) => { + let body = ''; + res.on('data', (chunk) => body += chunk); + res.on('end', () => { + try { + const parsed = JSON.parse(body); + resolve({ + status: res.statusCode, + headers: res.headers, + data: parsed + }); + } catch (e) { + resolve({ + status: res.statusCode, + headers: res.headers, + data: body + }); + } + }); + }); + + req.on('error', reject); + + if (data) { + req.write(JSON.stringify(data)); + } + + req.end(); + }); +} + +async function debugEmployee403Errors() { + try { + console.log('1️⃣ Connexion avec compte employé...'); + + // Connexion employé + const loginResponse = await makeRequest('/api/login', 'POST', TEST_EMPLOYEE_CREDENTIALS); + + if (loginResponse.status !== 200) { + console.error('❌ Échec de connexion employé'); + console.error(` Status: ${loginResponse.status}`); + console.error(` Response: ${JSON.stringify(loginResponse.data, null, 2)}`); + return; + } + + console.log('✅ Connexion employé réussie\n'); + + // Extraire les cookies de session + const setCookieHeaders = loginResponse.headers['set-cookie'] || []; + const cookies = setCookieHeaders.join('; '); + + console.log('2️⃣ Test des routes susceptibles de générer des erreurs 403...\n'); + + const results = []; + + // Tester chaque route + for (const route of ROUTES_TO_TEST) { + console.log(`🔍 Test: ${route.method} ${route.path} - ${route.description}`); + + try { + const response = await makeRequest(route.path, route.method, route.data, cookies); + + const status = response.status; + const statusIcon = status === 200 ? '✅' : status === 403 ? '❌' : '⚠️'; + + console.log(` ${statusIcon} Status: ${status}`); + + if (status === 403) { + console.log(` 🚫 ERREUR 403: ${JSON.stringify(response.data, null, 2)}`); + results.push({ route, status, error: response.data, success: false }); + } else if (status === 200) { + const dataSize = Array.isArray(response.data) ? response.data.length : 'N/A'; + console.log(` 📊 Données retournées: ${dataSize} éléments`); + results.push({ route, status, success: true }); + } else { + console.log(` ⚠️ Status inattendu: ${JSON.stringify(response.data, null, 2)}`); + results.push({ route, status, error: response.data, success: false }); + } + + } catch (error) { + console.log(` 💥 Erreur réseau: ${error.message}`); + results.push({ route, status: 'ERROR', error: error.message, success: false }); + } + + console.log(''); // Ligne vide entre les tests + } + + // Résumé des résultats + console.log('📊 === RÉSUMÉ DES TESTS ==='); + console.log('==========================\n'); + + const successfulRoutes = results.filter(r => r.success); + const forbiddenRoutes = results.filter(r => r.status === 403); + const errorRoutes = results.filter(r => !r.success && r.status !== 403); + + console.log(`✅ Routes accessibles: ${successfulRoutes.length}/${results.length}`); + console.log(`❌ Erreurs 403: ${forbiddenRoutes.length}/${results.length}`); + console.log(`⚠️ Autres erreurs: ${errorRoutes.length}/${results.length}\n`); + + if (forbiddenRoutes.length > 0) { + console.log('🚫 ROUTES BLOQUÉES (403):'); + forbiddenRoutes.forEach(result => { + console.log(` • ${result.route.method} ${result.route.path} - ${result.route.description}`); + console.log(` Erreur: ${result.error?.message || 'Permission refusée'}`); + }); + console.log(''); + } + + if (errorRoutes.length > 0) { + console.log('⚠️ AUTRES ERREURS:'); + errorRoutes.forEach(result => { + console.log(` • ${result.route.method} ${result.route.path} - Status: ${result.status}`); + console.log(` Erreur: ${result.error?.message || result.error}`); + }); + console.log(''); + } + + console.log('💡 RECOMMANDATIONS:'); + if (forbiddenRoutes.length === 0) { + console.log(' 🎉 Aucune erreur 403 détectée - les permissions semblent correctes !'); + } else { + console.log(' 1. Vérifiez les permissions dans shared/permissions.ts'); + console.log(' 2. Vérifiez les middlewares de permission dans server/permissions.ts'); + console.log(' 3. Vérifiez l\'assignation de groupes/magasins à l\'employé'); + console.log(' 4. Examinez les logs serveur pendant l\'exécution des requêtes'); + } + + } catch (error) { + console.error('💥 Erreur lors du débogage:', error.message); + } +} + +// Instructions d'utilisation +console.log('📋 Instructions:'); +console.log('1. Configurez les variables d\'environnement:'); +console.log(' - PRODUCTION_URL=https://votre-serveur.com'); +console.log(' - TEST_EMPLOYEE_USERNAME=nom_utilisateur_employe'); +console.log(' - TEST_EMPLOYEE_PASSWORD=mot_de_passe'); +console.log('2. Exécutez: node debug-employee-403-production.js\n'); + +// Exécuter le debug si le script est appelé directement +if (require.main === module) { + debugEmployee403Errors().catch(console.error); +} + +module.exports = { debugEmployee403Errors }; \ No newline at end of file diff --git a/replit.md b/replit.md index 166ac0e..f997b28 100644 --- a/replit.md +++ b/replit.md @@ -9,38 +9,27 @@ Preferred communication style: Simple, everyday language. ## System Architecture ### Frontend -- **Framework**: React 18 with TypeScript -- **Build Tool**: Vite -- **UI Framework**: Shadcn/ui (built on Radix UI) -- **Styling**: Tailwind CSS with custom CSS variables +- **Framework**: React 18 with TypeScript, Vite +- **UI Framework**: Shadcn/ui (built on Radix UI), Tailwind CSS - **State Management**: TanStack Query (React Query) - **Routing**: Wouter - **Forms**: React Hook Form with Zod validation -- **UI/UX Decisions**: Focus on a clean, intuitive interface using Shadcn/ui components for consistency and accessibility. Color schemes are managed via Tailwind CSS custom variables for easy theming. +- **UI/UX Decisions**: Clean, intuitive interface using Shadcn/ui components for consistency and accessibility. Color schemes managed via Tailwind CSS custom variables for easy theming. ### Backend -- **Framework**: Express.js with TypeScript -- **Runtime**: Node.js with ES modules +- **Framework**: Express.js with TypeScript, Node.js (ES modules) - **Database ORM**: Drizzle ORM - **Authentication**: Dual system (local for production, Replit Auth for development) - **Session Management**: Express sessions with PostgreSQL storage - **Security**: Comprehensive middleware (rate limiting, input sanitization, security headers) ### Database -- **Primary Database**: PostgreSQL with Drizzle ORM -- **Development**: Neon serverless PostgreSQL -- **Production**: Standard PostgreSQL in Docker containers +- **Primary Database**: PostgreSQL with Drizzle ORM (Neon serverless for development, Docker for production) - **Schema**: Centralized definition in `shared/schema.ts` - **Migrations**: Drizzle Kit ### Core Business Entities -- **Orders**: Purchase orders, supplier relationships, delivery tracking. -- **Deliveries**: Delivery tracking and status. -- **Customer Orders**: Point-of-sale management with barcode generation. -- **Suppliers**: Vendor management and order history. -- **Publicities**: Marketing campaign management and store participation. -- **DLC Products**: Management of products with limited shelf life, including status tracking and alerts. -- **Tasks**: Streamlined task management with simplified assignment and completion tracking. +- **Management**: Orders, Deliveries, Customer Orders, Suppliers, Publicities, DLC Products (limited shelf life), Tasks. ### Data Flow - **Request Flow**: Client requests via React Query, processed by Express middleware for authentication/security, then by route handlers using Drizzle ORM for database operations. @@ -48,11 +37,14 @@ Preferred communication style: Simple, everyday language. - **Data Synchronization**: Real-time updates via React Query with optimistic updates and intelligent cache invalidation. Global store context filters data. ### Key Features -- **Authentication System**: Secure dual authentication system with robust password hashing and session management. +- **Authentication System**: Secure dual authentication with password hashing and session management. - **Multi-Store Management**: Global store context, role-based access control (admin, manager, employee, directeur), and data isolation. -- **Universal Pagination**: Reusable client-side pagination component applied across all main tabular data pages (Orders, Deliveries, Customer Orders, DlcPage, BLReconciliation, Tasks) with configurable limits per module. +- **Universal Pagination**: Reusable client-side pagination component across all main tabular data pages. - **Reconciliation Module**: For balancing and tracking financial discrepancies. -- **Permission System**: Granular permission management with 54 permissions across 12 categories, assigned to 4 roles. +- **Permission System**: Granular, hardcoded permissions (54 permissions across 12 categories, assigned to 4 roles) for improved performance and maintenance. +- **User Management**: Comprehensive features including user deletion with ownership transfer, consistent name and email field handling, and robust password hashing. +- **Calendar Synchronization**: Proper display of delivery dates and automatic synchronization of order statuses. +- **Database Schema Download**: Admin-only feature to download comprehensive database structure reports. ## External Dependencies @@ -75,138 +67,4 @@ Preferred communication style: Simple, everyday language. - **Development Server**: Vite dev server ### Other Integrations -- **NocoDB Integration**: Configurable for invoice verification and data synchronization. - -## Recent Changes - -### August 11, 2025 - Permissions System Overhaul & User Management Improvements - -#### Hardcoded Permissions System Implementation -- **Migration from Database to Code**: Replaced flexible database-driven permissions with hardcoded permission system for better performance and control -- **New Architecture**: - - Created `client/src/lib/permissions.ts` and `shared/permissions.ts` with role-based module permissions - - Implemented server-side middleware `server/permissions.ts` for route protection - - Removed database tables: `roles`, `permissions`, `rolePermissions`, `userRoles` - - Cleaned up storage interface and routes from old permission system -- **Permission Matrix by Module**: - - **Dashboard**: All roles can view - - **Calendar/Orders/Deliveries**: Admin/Directeur full access, Manager all except delete, Employee view only - - **Reconciliation**: Admin full access, Directeur all except delete, Manager/Employee no access - - **Publicity**: Admin full access, others view only - - **Customer Orders**: Admin/Directeur full access, Manager all except delete, Employee view + create - - **DLC**: Admin/Directeur full access, Manager all except delete, Employee create + view - - **Tasks**: Admin/Directeur full access, Manager view + validate, Employee view only -- **Benefits**: Improved performance, simplified maintenance, no database queries for permission checks - -### August 11, 2025 - User Management Improvements - -#### User Deletion Fix -- **Issue**: Foreign key constraint errors when deleting users who created customer orders or other records -- **Root Cause**: User records were referenced by multiple tables (customer_orders, deliveries, DLC products, etc.) -- **Solution Implemented**: - - Enhanced deleteUser method with database transaction for atomicity - - Prioritized lookup for `admin_local` (default admin) with fallback to any admin user - - Ownership transfer of all user-created records to existing admin before deletion - - Comprehensive handling of all foreign key relationships including role assignments - - Graceful error handling when no admin user exists -- **Tables Handled**: customer_orders, orders, deliveries, publicities, dlcProducts, tasks, nocodbConfig, userGroups, userRoles (both userId and assignedBy), database_backups -- **Result**: Safe user deletion while preserving business data integrity - -#### User Name Fields Optional in Production -- **Issue**: Inconsistent validation between user creation and editing forms for name fields -- **Root Cause**: Edit form required firstName/lastName while creation form had them as optional -- **Solution Implemented**: - - Removed required validation from edit form firstName/lastName fields - - Updated placeholders to indicate "(optionnel)" for consistency - - Maintained database schema where name fields are already optional -- **Result**: Name fields now consistently optional across all user management interfaces - -#### User Edit Form Initialization Fix -- **Issue**: Prénom/nom fields in edit form were not editable because they were initialized from wrong data source -- **Root Cause**: handleEditUser was only using the `name` field instead of `firstName`/`lastName` fields from database -- **Solution Implemented**: - - Modified handleEditUser to prioritize `firstName`/`lastName` fields from database - - Added fallback to split `name` field if firstName/lastName are empty - - Fixed edit form initialization to use actual database values -- **Result**: Edit form now properly loads existing firstName/lastName values and allows editing - -#### Email Field Consistency in Edit Form -- **Issue**: Email field was marked as required in edit form but optional in create form -- **Solution**: Removed `required` attribute and asterisk from email field in edit form -- **Result**: Email field now consistently optional in both create and edit forms - -#### Production Password Hashing Fix -- **Issue**: Admin password changes failed in production with ERR_MODULE_NOT_FOUND for localAuth.production -- **Root Cause**: Dynamic imports in production needed `.js` extension for compiled files -- **Solution**: Updated import paths to use `./localAuth.production.js` for production environment -- **Result**: Password hashing now works correctly in production for user updates - -#### Email Constraint Fix for User Management -- **Issue**: Both user creation and editing failed with "duplicate key value violates unique constraint users_email_key" error -- **Root Cause**: PostgreSQL treats empty strings (`""`) as unique values, but multiple users with empty emails violated uniqueness constraint -- **Solution Implemented**: - - Updated both POST `/api/users` (creation) and PUT `/api/users/:id` (editing) routes to convert empty emails to `NULL` - - Enhanced validation schemas to accept `null` values for email fields - - Created `fix-duplicate-empty-email.sql` script to clean existing database records - - Improved error handling and logging for better production debugging -- **Result**: Users can now be created and edited with optional email fields without constraint violations - -#### Calendar Order-Delivery Synchronization Fix -- **Issue**: Orders linked to delivered deliveries were not showing proper status and dates in calendar view -- **Root Cause**: Three interconnected problems: - 1. OrderDetailModal was displaying non-existent `plannedDate` instead of `scheduledDate`/`deliveredDate` - 2. Order status was not automatically updated when delivery status changed via updateDelivery method - 3. Delivered deliveries had missing `deliveredDate` field causing "Date non disponible" display -- **Solution Implemented**: - - Enhanced OrderDetailModal to display correct dates: `deliveredDate` for delivered items, `scheduledDate` for planned ones - - Added automatic order status synchronization in `updateDelivery` method when delivery marked as delivered - - Created `fix-delivery-order-sync.sql` script to correct existing production data inconsistencies - - Improved Calendar date initialization to show current month instead of hardcoded July 2025 -- **Result**: Calendar now properly displays delivery dates and automatically synchronizes order statuses when deliveries are completed - -### August 12, 2025 - Employee Permissions Restriction & Database Schema Download - -#### Employee Role Permissions Update -- **Issue**: Employee role had excessive access to orders and deliveries modules, but needed restricted calendar access -- **Root Cause**: Permission system allowed employees full access to create orders/deliveries from calendar and sidebar navigation -- **Solution Implemented**: - - Updated `shared/permissions.ts`: Removed all permissions for employees on 'orders' and 'deliveries' modules - - Modified `client/src/components/Sidebar.tsx`: Removed orders and deliveries menu items for employee role - - Enhanced `client/src/pages/Calendar.tsx`: Added permission checks to hide "Nouveau" button for employees - - Updated `client/src/components/modals/QuickCreateMenu.tsx`: Added role-based filtering for order/delivery creation options -- **Employee Access Rules**: - - **Calendar**: View-only access, cannot create orders or deliveries - - **Sidebar**: No access to Orders and Deliveries menu items - - **Customer Orders & DLC**: Maintains supplier list access for creating customer orders and DLC entries -- **Result**: Employees now have appropriate restricted access while maintaining necessary supplier information for their workflows - -#### Database Schema Download Feature -- **Issue**: Database schema scan results were only available in server logs, needed downloadable reports -- **Solution Implemented**: - - Created new API route `/api/debug/download-schema` for production schema downloads - - Added comprehensive schema report generation with tables, columns, constraints, and record counts - - Enhanced `client/src/pages/DatabaseDebug.tsx`: Added download button that appears after successful scans - - Implemented proper file download headers with automatic filename generation - - Added admin-only access restriction and production environment validation -- **Download Report Features**: - - Complete database structure with column details and constraints - - Record counts per table for data overview - - Foreign key relationships mapping - - Formatted text file with timestamps and user information -- **Result**: Administrators can now download comprehensive database schema reports for documentation and analysis - -#### Employee Supplier Access Fix -- **Issue**: Employee role could not access supplier lists in Customer Orders and DLC modules on production server -- **Root Cause**: API route `/api/suppliers` was restricted to admin and manager roles only, excluding employees and directeurs -- **Solution Implemented**: - - Updated `/api/suppliers` GET route: Added employee and directeur role access for read operations - - Updated `/api/suppliers` POST route: Added directeur role access for creation operations - - Updated `/api/suppliers` PUT route: Added directeur role access for edit operations - - Updated `/api/suppliers` DELETE route: Restricted to admin and directeur only (removed manager access) - - Created test script `test-employee-supplier-access.js` for production verification -- **Access Matrix Updated**: - - **GET /api/suppliers**: admin, directeur, manager, employee (all roles can read) - - **POST /api/suppliers**: admin, directeur, manager (creation permissions) - - **PUT /api/suppliers**: admin, directeur, manager (edit permissions) - - **DELETE /api/suppliers**: admin, directeur only (delete permissions) -- **Result**: Employees can now access supplier lists in Customer Orders and DLC modules while maintaining appropriate write restrictions \ No newline at end of file +- **NocoDB Integration**: Configurable for invoice verification and data synchronization. \ No newline at end of file diff --git a/server/routes.ts b/server/routes.ts index 0f85bb9..f8df668 100644 --- a/server/routes.ts +++ b/server/routes.ts @@ -2329,7 +2329,7 @@ RÉSUMÉ DU SCAN const userId = req.user.claims ? req.user.claims.sub : req.user.id; const user = await storage.getUser(userId); - if (!user || !['admin', 'manager'].includes(user.role)) { + if (!user || !['admin', 'manager', 'directeur'].includes(user.role)) { return res.status(403).json({ message: "Insufficient permissions to validate products" }); } diff --git a/shared/permissions.ts b/shared/permissions.ts index 0cd843a..af80e47 100644 --- a/shared/permissions.ts +++ b/shared/permissions.ts @@ -80,12 +80,12 @@ const PERMISSIONS: Record> = { employee: ['view', 'create'] }, - // Tâches - Admin/Directeur tout, Manager view + validate, Employé view + // Tâches - Admin/Directeur tout, Manager view + validate, Employé view + create tasks: { admin: ['view', 'create', 'edit', 'delete', 'validate'], directeur: ['view', 'create', 'edit', 'delete', 'validate'], manager: ['view', 'validate'], - employee: ['view'] + employee: ['view', 'create'] } };