feat: Add asesor role with reports-only access - backend v1.0.10, frontend v1.0.16

This commit is contained in:
2025-11-20 16:23:52 -03:00
parent 5d2a96553e
commit 570cdb6739
4 changed files with 30 additions and 22 deletions

View File

@@ -1284,8 +1284,8 @@ def get_dashboard_data(
db: Session = Depends(get_db) db: Session = Depends(get_db)
): ):
"""Obtener datos del dashboard de informes""" """Obtener datos del dashboard de informes"""
if current_user.role != "admin": if current_user.role not in ["admin", "asesor"]:
raise HTTPException(status_code=403, detail="Solo administradores pueden acceder a reportes") raise HTTPException(status_code=403, detail="No tienes permisos para acceder a reportes")
# Construir query base # Construir query base
query = db.query(models.Inspection) query = db.query(models.Inspection)
@@ -1531,8 +1531,8 @@ def get_inspections_report(
db: Session = Depends(get_db) db: Session = Depends(get_db)
): ):
"""Obtener lista de inspecciones con filtros""" """Obtener lista de inspecciones con filtros"""
if current_user.role != "admin": if current_user.role not in ["admin", "asesor"]:
raise HTTPException(status_code=403, detail="Solo administradores pueden acceder a reportes") raise HTTPException(status_code=403, detail="No tienes permisos para acceder a reportes")
# Query base con select_from explícito # Query base con select_from explícito
query = db.query( query = db.query(

View File

@@ -10,7 +10,7 @@ class User(Base):
username = Column(String(50), unique=True, index=True, nullable=False) username = Column(String(50), unique=True, index=True, nullable=False)
email = Column(String(100), unique=True, index=True) email = Column(String(100), unique=True, index=True)
password_hash = Column(String(255), nullable=False) 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)) full_name = Column(String(100))
is_active = Column(Boolean, default=True) is_active = Column(Boolean, default=True)
created_at = Column(DateTime(timezone=True), server_default=func.now()) created_at = Column(DateTime(timezone=True), server_default=func.now())

View File

@@ -20,7 +20,7 @@ services:
retries: 5 retries: 5
backend: backend:
image: dymai/syntria-backend:1.0.9 image: dymai/syntria-backend:1.0.10
container_name: syntria-backend-prod container_name: syntria-backend-prod
restart: always restart: always
depends_on: depends_on:
@@ -38,7 +38,7 @@ services:
command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 4 command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 4
frontend: frontend:
image: dymai/syntria-frontend:1.0.15 image: dymai/syntria-frontend:1.0.16
container_name: syntria-frontend-prod container_name: syntria-frontend-prod
restart: always restart: always
depends_on: depends_on:

View File

@@ -67,6 +67,9 @@ export default function Sidebar({ user, activeTab, setActiveTab, sidebarOpen, se
{sidebarOpen && <span>Usuarios</span>} {sidebarOpen && <span>Usuarios</span>}
</button> </button>
</li> </li>
</>
)}
{(user.role === 'admin' || user.role === 'asesor') && (
<li> <li>
<button <button
onClick={() => setActiveTab('reports')} onClick={() => setActiveTab('reports')}
@@ -81,6 +84,9 @@ export default function Sidebar({ user, activeTab, setActiveTab, sidebarOpen, se
{sidebarOpen && <span>Reportes</span>} {sidebarOpen && <span>Reportes</span>}
</button> </button>
</li> </li>
)}
{user.role === 'admin' && (
<>
<li> <li>
<button <button
onClick={() => setActiveTab('api-tokens')} onClick={() => setActiveTab('api-tokens')}
@@ -123,7 +129,9 @@ export default function Sidebar({ user, activeTab, setActiveTab, sidebarOpen, se
{sidebarOpen && ( {sidebarOpen && (
<div className="flex-1 min-w-0"> <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-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>
)} )}
</div> </div>