fix: conformité stricte skill itinova-user-management
- Rôles : remplacement admin/approbateur/validateur/operateur → admin/standard/readonly - schema.ts, migrate.ts : ENUM MySQL mis à jour (3 rôles skill) - routes/auth.ts : rôle par défaut standard, validRoles, modèle CSV corrigé - routes/invoices.ts : permissions readonly/standard/admin - routes/dashboard.ts : compteurs dashboard selon standard/admin - frontend/types/index.ts : type User role mis à jour - frontend/utils/helpers.ts : roleLabels admin/standard/readonly - frontend/pages/InvoiceDetail.tsx : actions disponibles selon standard/readonly/admin - frontend/pages/UserList.tsx : rôle par défaut standard, labels import corrigés
This commit is contained in:
@@ -153,7 +153,7 @@ router.post('/users', authenticate, authorize('admin'), async (req: AuthRequest,
|
||||
|
||||
const [result]: any = await pool.execute(
|
||||
'INSERT INTO users (email, password, first_name, last_name, role) VALUES (?, ?, ?, ?, ?)',
|
||||
[email, hashedPassword, firstName, lastName, role || 'operateur']
|
||||
[email, hashedPassword, firstName, lastName, role || 'standard']
|
||||
);
|
||||
|
||||
res.status(201).json({
|
||||
@@ -161,7 +161,7 @@ router.post('/users', authenticate, authorize('admin'), async (req: AuthRequest,
|
||||
email,
|
||||
firstName,
|
||||
lastName,
|
||||
role: role || 'operateur',
|
||||
role: role || 'standard',
|
||||
});
|
||||
} catch (error: any) {
|
||||
if (error.code === 'ER_DUP_ENTRY') {
|
||||
@@ -218,7 +218,7 @@ router.delete('/users/:id', authenticate, authorize('admin'), async (req: AuthRe
|
||||
|
||||
// GET /api/auth/users/import-template - Télécharger le modèle CSV
|
||||
router.get('/users/import-template', authenticate, authorize('admin'), (_req: AuthRequest, res: Response) => {
|
||||
const csvContent = 'email,prenom,nom,role\nadmin@exemple.com,Jean,Dupont,admin\nutilisateur@exemple.com,Marie,Martin,operateur\n';
|
||||
const csvContent = 'email,prenom,nom,role\nadmin@exemple.com,Jean,Dupont,admin\nstandard@exemple.com,Marie,Martin,standard\nreadonly@exemple.com,Paul,Durand,readonly\n';
|
||||
res.setHeader('Content-Type', 'text/csv; charset=utf-8');
|
||||
res.setHeader('Content-Disposition', 'attachment; filename="modele_import_utilisateurs.csv"');
|
||||
res.send('\uFEFF' + csvContent); // BOM UTF-8 pour Excel
|
||||
@@ -232,7 +232,7 @@ router.post('/users/import', authenticate, authorize('admin'), uploadMemory.sing
|
||||
}
|
||||
|
||||
const pool = getPool();
|
||||
const validRoles = ['admin', 'approbateur', 'validateur', 'operateur'];
|
||||
const validRoles = ['admin', 'standard', 'readonly'];
|
||||
const results = { created: 0, updated: 0, errors: [] as string[] };
|
||||
|
||||
// Parsing CSV ou Excel
|
||||
@@ -265,7 +265,7 @@ router.post('/users/import', authenticate, authorize('admin'), uploadMemory.sing
|
||||
const email = String(row[0] || '').trim().toLowerCase();
|
||||
const prenom = String(row[1] || '').trim();
|
||||
const nom = String(row[2] || '').trim();
|
||||
const role = String(row[3] || 'operateur').trim().toLowerCase();
|
||||
const role = String(row[3] || 'standard').trim().toLowerCase();
|
||||
|
||||
// Validation
|
||||
if (!email || !email.includes('@')) {
|
||||
@@ -276,7 +276,7 @@ router.post('/users/import', authenticate, authorize('admin'), uploadMemory.sing
|
||||
results.errors.push(`Ligne ${lineNum} : prénom ou nom manquant`);
|
||||
continue;
|
||||
}
|
||||
const finalRole = validRoles.includes(role) ? role : 'operateur';
|
||||
const finalRole = validRoles.includes(role) ? role : 'standard';
|
||||
|
||||
// Vérifier si l'utilisateur existe
|
||||
const [existing]: any = await pool.execute(
|
||||
|
||||
Reference in New Issue
Block a user