feat: administradores por proyecto y Configuracion solo para superadmin
- Un proyecto puede tener uno o mas administradores (role_in_project= 'admin' en project_members), independiente del rol global del usuario. Nuevo PUT /api/projects/:id/members/:userId/role; canWriteProject lo reconoce ademas del comportamiento previo (admin/superadmin/it_manager global, o project_lead miembro). UI: casilla al agregar miembro + boton de escudo para promover/degradar (nunca toca al Dueño). - Menu "Configuracion" (apariencia, catalogos, SMTP) visible y accesible solo para el superadmin: oculto en el nav y con guarda en la ruta /configuracion para quien la teclee directo. Escritura de catalogos restringida de [superadmin, admin] a solo superadmin para que el backend sea consistente con la UI. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -111,6 +111,15 @@ export async function isMember(projectId, userId) {
|
||||
return rows.length > 0;
|
||||
}
|
||||
|
||||
// null = no es miembro; 'member' = miembro sin rol especifico; 'admin'/'owner' = con ese rol.
|
||||
export async function getMembership(projectId, userId) {
|
||||
const [rows] = await pool.query('SELECT role_in_project FROM project_members WHERE project_id = ? AND user_id = ?', [
|
||||
projectId, userId,
|
||||
]);
|
||||
if (!rows.length) return null;
|
||||
return rows[0].role_in_project || 'member';
|
||||
}
|
||||
|
||||
export async function addMember(projectId, userId, roleInProject) {
|
||||
await pool.query(
|
||||
'INSERT IGNORE INTO project_members (project_id, user_id, role_in_project) VALUES (?, ?, ?)',
|
||||
@@ -119,6 +128,16 @@ export async function addMember(projectId, userId, roleInProject) {
|
||||
return listMembers(projectId);
|
||||
}
|
||||
|
||||
// Nunca toca una fila con role_in_project = 'owner' (protege al dueño de perder ese rol por aqui).
|
||||
export async function updateMemberRole(projectId, userId, roleInProject) {
|
||||
await pool.query(
|
||||
`UPDATE project_members SET role_in_project = ?
|
||||
WHERE project_id = ? AND user_id = ? AND (role_in_project IS NULL OR role_in_project <> 'owner')`,
|
||||
[roleInProject, projectId, userId]
|
||||
);
|
||||
return listMembers(projectId);
|
||||
}
|
||||
|
||||
export async function removeMember(projectId, userId) {
|
||||
await pool.query('DELETE FROM project_members WHERE project_id = ? AND user_id = ?', [projectId, userId]);
|
||||
return listMembers(projectId);
|
||||
|
||||
Reference in New Issue
Block a user