feat: version 2.15.0 -- pestaña Compartir en Equipos (acceso de solo lectura)

Admin/superadmin dan acceso de solo lectura (Resumen, Equipos, Software) a otros usuarios;
el backend valida el acceso en cada endpoint y el menu aparece solo a quien lo tenga.
Migracion 026 (device_viewers).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Milton Gonzalez
2026-10-20 08:32:53 -05:00
parent d5f09dc91b
commit d60b4b1d77
13 changed files with 209 additions and 29 deletions
+24
View File
@@ -46,6 +46,30 @@ export async function findTokenSecret(id) {
export const setTokenActive = (id, active) => pool.query('UPDATE inventory_tokens SET is_active = ? WHERE id = ?', [active ? 1 : 0, id]);
export const deleteToken = (id) => pool.query('DELETE FROM inventory_tokens WHERE id = ?', [id]);
// ---------- Acceso compartido (solo lectura) ----------
export async function isViewer(userId) {
const [rows] = await pool.query('SELECT 1 FROM device_viewers WHERE user_id = ?', [userId]);
return rows.length > 0;
}
export async function listViewers() {
const [rows] = await pool.query(
`SELECT v.user_id, u.name, u.email, r.name AS role_name, v.created_at, g.name AS granted_by_name
FROM device_viewers v JOIN users u ON u.id = v.user_id JOIN roles r ON r.id = u.role_id
LEFT JOIN users g ON g.id = v.granted_by ORDER BY u.name`
);
return rows;
}
export const addViewer = (userId, grantedBy) => pool.query('INSERT IGNORE INTO device_viewers (user_id, granted_by) VALUES (?, ?)', [userId, grantedBy]);
export const removeViewer = (userId) => pool.query('DELETE FROM device_viewers WHERE user_id = ?', [userId]);
export async function findUserBrief(userId) {
const [[row]] = await pool.query('SELECT u.id, u.name, u.is_active, r.code AS role_code FROM users u JOIN roles r ON r.id = u.role_id WHERE u.id = ?', [userId]);
return row || null;
}
// ---------- Ingesta ----------
// Foto de lo que hay hoy en BD (para calcular el diff contra el reporte nuevo).