From ad59152ccecc69580874e80123ad867495cd1800 Mon Sep 17 00:00:00 2001 From: ronalds Date: Tue, 25 Nov 2025 08:43:54 -0300 Subject: [PATCH] Corregir notificaicon check --- backend/app/core/config.py | 3 ++ backend/app/main.py | 74 ++++++++++++++++++++++++++++++++++++++ backend/app/models.py | 1 + backend/app/schemas.py | 1 + frontend/src/App.jsx | 49 ++++++++++++++++++++++--- 5 files changed, 124 insertions(+), 4 deletions(-) diff --git a/backend/app/core/config.py b/backend/app/core/config.py index fe9082c..6d453d0 100644 --- a/backend/app/core/config.py +++ b/backend/app/core/config.py @@ -25,6 +25,9 @@ class Settings(BaseSettings): # Environment ENVIRONMENT: str = "development" + # Notificaciones + NOTIFICACION_ENDPOINT: str = "" + # CORS - Orígenes permitidos separados por coma ALLOWED_ORIGINS: str = "http://localhost:3000,http://localhost:5173" diff --git a/backend/app/main.py b/backend/app/main.py index fc66fa0..6a7866b 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -18,6 +18,70 @@ from app import models, schemas import shutil from datetime import datetime, timedelta import sys +import requests + +# Función para enviar notificaciones al webhook +def send_answer_notification(answer, question, mechanic, db): + """Envía notificación al webhook cuando se responde una pregunta marcada""" + try: + if not app_config.settings.NOTIFICACION_ENDPOINT: + print("No hay endpoint de notificación configurado") + return + + # Obtener datos de la inspección + inspection = db.query(models.Inspection).filter( + models.Inspection.id == answer.inspection_id + ).first() + + if not inspection: + return + + # Preparar datos para enviar + notification_data = { + "tipo": "respuesta_pregunta", + "pregunta": { + "id": question.id, + "texto": question.text, + "seccion": question.section + }, + "respuesta": { + "id": answer.id, + "valor": answer.answer_value, + "estado": answer.status, + "comentario": answer.comment, + "puntos": answer.points_earned + }, + "inspeccion": { + "id": inspection.id, + "vehiculo_placa": inspection.vehicle_plate, + "vehiculo_marca": inspection.vehicle_brand, + "vehiculo_modelo": inspection.vehicle_model, + "cliente": inspection.client_name, + "or_number": inspection.or_number + }, + "mecanico": { + "id": mechanic.id, + "nombre": mechanic.full_name, + "email": mechanic.email + }, + "timestamp": datetime.utcnow().isoformat() + } + + # Enviar al webhook + response = requests.post( + app_config.settings.NOTIFICACION_ENDPOINT, + json=notification_data, + timeout=5 + ) + + if response.status_code == 200: + print(f"✅ Notificación enviada para pregunta {question.id}") + else: + print(f"⚠️ Error al enviar notificación: {response.status_code}") + + except Exception as e: + print(f"❌ Error enviando notificación: {e}") + # No lanzamos excepción para no interrumpir el flujo normal BACKEND_VERSION = "1.0.25" app = FastAPI(title="Checklist Inteligente API", version=BACKEND_VERSION) @@ -941,6 +1005,11 @@ def create_answer( existing_answer.updated_at = datetime.utcnow() db.commit() db.refresh(existing_answer) + + # Enviar notificación si la pregunta lo requiere + if question.send_notification: + send_answer_notification(existing_answer, question, current_user, db) + return existing_answer else: # Si status es pass/fail y no hay valor, no poner valor por defecto en answer_value @@ -954,6 +1023,11 @@ def create_answer( db.add(db_answer) db.commit() db.refresh(db_answer) + + # Enviar notificación si la pregunta lo requiere + if question.send_notification: + send_answer_notification(db_answer, question, current_user, db) + return db_answer diff --git a/backend/app/models.py b/backend/app/models.py index 8d5ad34..ad81356 100644 --- a/backend/app/models.py +++ b/backend/app/models.py @@ -71,6 +71,7 @@ class Question(Base): allow_photos = Column(Boolean, default=True) max_photos = Column(Integer, default=3) requires_comment_on_fail = Column(Boolean, default=False) + send_notification = Column(Boolean, default=False) # Conditional logic parent_question_id = Column(Integer, ForeignKey("questions.id"), nullable=True) diff --git a/backend/app/schemas.py b/backend/app/schemas.py index 12b17bd..9fca46d 100644 --- a/backend/app/schemas.py +++ b/backend/app/schemas.py @@ -97,6 +97,7 @@ class QuestionBase(BaseModel): allow_photos: bool = True max_photos: int = 3 requires_comment_on_fail: bool = False + send_notification: bool = False parent_question_id: Optional[int] = None show_if_answer: Optional[str] = None ai_prompt: Optional[str] = None diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 62ca7f3..6b2a026 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -908,6 +908,7 @@ function QuestionsManagerModal({ checklist, onClose }) { allow_photos: true, max_photos: 3, requires_comment_on_fail: false, + send_notification: false, parent_question_id: null, show_if_answer: '', ai_prompt: '' @@ -966,6 +967,7 @@ function QuestionsManagerModal({ checklist, onClose }) { allow_photos: true, max_photos: 3, requires_comment_on_fail: false, + send_notification: false, parent_question_id: null, show_if_answer: '', ai_prompt: '' @@ -1221,6 +1223,23 @@ function QuestionsManagerModal({ checklist, onClose }) { +
+
+ setFormData({ ...formData, send_notification: e.target.checked })} + className="w-4 h-4 text-yellow-600 border-gray-300 rounded focus:ring-yellow-500" + /> + +
+

+ Si activas esta opción, se enviará una notificación automática al administrador cada vez que un mecánico responda esta pregunta. +

+
+