Backend v1.0.71:

- Implementado soft delete para preguntas
- Nuevas columnas: is_deleted (boolean), updated_at (timestamp)
- Migración SQL: add_soft_delete_to_questions.sql
- Endpoint DELETE marca preguntas como eliminadas en lugar de borrarlas
- GET /api/checklists/{id} filtra preguntas eliminadas (is_deleted=false)
- Validación de subpreguntas activas antes de eliminar
- Índices agregados para optimizar queries
- Mantiene integridad de respuestas históricas y PDFs generados
- Permite limpiar checklists sin afectar inspecciones completadas
This commit is contained in:
2025-11-27 15:32:56 -03:00
parent 027f22551c
commit ed3f513075
7 changed files with 75 additions and 11 deletions

View File

@@ -204,7 +204,7 @@ def send_completed_inspection_to_n8n(inspection, db):
# No lanzamos excepción para no interrumpir el flujo normal
BACKEND_VERSION = "1.0.69"
BACKEND_VERSION = "1.0.71"
app = FastAPI(title="Checklist Inteligente API", version=BACKEND_VERSION)
# S3/MinIO configuration
@@ -780,13 +780,17 @@ def get_checklists(
@app.get("/api/checklists/{checklist_id}", response_model=schemas.ChecklistWithQuestions)
def get_checklist(checklist_id: int, db: Session = Depends(get_db)):
checklist = db.query(models.Checklist).options(
joinedload(models.Checklist.questions)
).filter(models.Checklist.id == checklist_id).first()
checklist = db.query(models.Checklist).filter(models.Checklist.id == checklist_id).first()
if not checklist:
raise HTTPException(status_code=404, detail="Checklist no encontrado")
# Cargar solo preguntas NO eliminadas
checklist.questions = db.query(models.Question).filter(
models.Question.checklist_id == checklist_id,
models.Question.is_deleted == False
).order_by(models.Question.order).all()
# Agregar allowed_mechanics
permissions = db.query(models.ChecklistPermission.mechanic_id).filter(
models.ChecklistPermission.checklist_id == checklist.id
@@ -1050,6 +1054,21 @@ def delete_question(
if not db_question:
raise HTTPException(status_code=404, detail="Pregunta no encontrada")
if db_question.is_deleted:
raise HTTPException(status_code=400, detail="La pregunta ya está eliminada")
# Verificar si tiene subpreguntas activas
active_subquestions = db.query(models.Question).filter(
models.Question.parent_question_id == question_id,
models.Question.is_deleted == False
).count()
if active_subquestions > 0:
raise HTTPException(
status_code=400,
detail=f"No se puede eliminar la pregunta porque tiene {active_subquestions} subpregunta(s) activa(s). Elimina primero las subpreguntas."
)
# Registrar auditoría antes de eliminar
audit_log = models.QuestionAuditLog(
question_id=question_id,
@@ -1061,9 +1080,16 @@ def delete_question(
)
db.add(audit_log)
db.delete(db_question)
# SOFT DELETE: marcar como eliminada en lugar de borrar físicamente
db_question.is_deleted = True
db_question.updated_at = datetime.utcnow()
db.commit()
return {"message": "Pregunta eliminada"}
return {
"message": "Pregunta eliminada exitosamente",
"note": "Las respuestas históricas se mantienen intactas. La pregunta no aparecerá en nuevas inspecciones."
}
@app.get("/api/questions/{question_id}/audit", response_model=List[schemas.QuestionAuditLog])