feat: Add asesor role with reports-only access - backend v1.0.10, frontend v1.0.16
This commit is contained in:
@@ -1284,8 +1284,8 @@ def get_dashboard_data(
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""Obtener datos del dashboard de informes"""
|
||||
if current_user.role != "admin":
|
||||
raise HTTPException(status_code=403, detail="Solo administradores pueden acceder a reportes")
|
||||
if current_user.role not in ["admin", "asesor"]:
|
||||
raise HTTPException(status_code=403, detail="No tienes permisos para acceder a reportes")
|
||||
|
||||
# Construir query base
|
||||
query = db.query(models.Inspection)
|
||||
@@ -1531,8 +1531,8 @@ def get_inspections_report(
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""Obtener lista de inspecciones con filtros"""
|
||||
if current_user.role != "admin":
|
||||
raise HTTPException(status_code=403, detail="Solo administradores pueden acceder a reportes")
|
||||
if current_user.role not in ["admin", "asesor"]:
|
||||
raise HTTPException(status_code=403, detail="No tienes permisos para acceder a reportes")
|
||||
|
||||
# Query base con select_from explícito
|
||||
query = db.query(
|
||||
|
||||
@@ -10,7 +10,7 @@ class User(Base):
|
||||
username = Column(String(50), unique=True, index=True, nullable=False)
|
||||
email = Column(String(100), unique=True, index=True)
|
||||
password_hash = Column(String(255), nullable=False)
|
||||
role = Column(String(20), nullable=False) # admin, mechanic
|
||||
role = Column(String(20), nullable=False) # admin, mechanic, asesor
|
||||
full_name = Column(String(100))
|
||||
is_active = Column(Boolean, default=True)
|
||||
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||
|
||||
@@ -20,7 +20,7 @@ services:
|
||||
retries: 5
|
||||
|
||||
backend:
|
||||
image: dymai/syntria-backend:1.0.9
|
||||
image: dymai/syntria-backend:1.0.10
|
||||
container_name: syntria-backend-prod
|
||||
restart: always
|
||||
depends_on:
|
||||
@@ -38,7 +38,7 @@ services:
|
||||
command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 4
|
||||
|
||||
frontend:
|
||||
image: dymai/syntria-frontend:1.0.15
|
||||
image: dymai/syntria-frontend:1.0.16
|
||||
container_name: syntria-frontend-prod
|
||||
restart: always
|
||||
depends_on:
|
||||
|
||||
@@ -67,20 +67,26 @@ export default function Sidebar({ user, activeTab, setActiveTab, sidebarOpen, se
|
||||
{sidebarOpen && <span>Usuarios</span>}
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button
|
||||
onClick={() => setActiveTab('reports')}
|
||||
className={`w-full flex items-center ${sidebarOpen ? 'gap-3 px-4' : 'justify-center px-2'} py-3 rounded-lg transition ${
|
||||
activeTab === 'reports'
|
||||
? 'bg-gradient-to-r from-indigo-600 to-purple-600 text-white shadow-lg'
|
||||
: 'text-indigo-200 hover:bg-indigo-900/50'
|
||||
}`}
|
||||
title={!sidebarOpen ? 'Reportes' : ''}
|
||||
>
|
||||
<span className="text-xl">📊</span>
|
||||
{sidebarOpen && <span>Reportes</span>}
|
||||
</button>
|
||||
</li>
|
||||
</>
|
||||
)}
|
||||
{(user.role === 'admin' || user.role === 'asesor') && (
|
||||
<li>
|
||||
<button
|
||||
onClick={() => setActiveTab('reports')}
|
||||
className={`w-full flex items-center ${sidebarOpen ? 'gap-3 px-4' : 'justify-center px-2'} py-3 rounded-lg transition ${
|
||||
activeTab === 'reports'
|
||||
? 'bg-gradient-to-r from-indigo-600 to-purple-600 text-white shadow-lg'
|
||||
: 'text-indigo-200 hover:bg-indigo-900/50'
|
||||
}`}
|
||||
title={!sidebarOpen ? 'Reportes' : ''}
|
||||
>
|
||||
<span className="text-xl">📊</span>
|
||||
{sidebarOpen && <span>Reportes</span>}
|
||||
</button>
|
||||
</li>
|
||||
)}
|
||||
{user.role === 'admin' && (
|
||||
<>
|
||||
<li>
|
||||
<button
|
||||
onClick={() => setActiveTab('api-tokens')}
|
||||
@@ -123,7 +129,9 @@ export default function Sidebar({ user, activeTab, setActiveTab, sidebarOpen, se
|
||||
{sidebarOpen && (
|
||||
<div className="flex-1 min-w-0">
|
||||
<p className="text-sm font-medium truncate text-white">{user.full_name || user.username}</p>
|
||||
<p className="text-xs text-indigo-300">{user.role === 'admin' ? '👑 Admin' : '🔧 Mecánico'}</p>
|
||||
<p className="text-xs text-indigo-300">
|
||||
{user.role === 'admin' ? '👑 Admin' : user.role === 'asesor' ? '📊 Asesor' : '🔧 Mecánico'}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user