backend y front trabajar por version de historial de cambios
This commit is contained in:
@@ -1148,6 +1148,142 @@ def update_answer(
|
||||
return db_answer
|
||||
|
||||
|
||||
# ============= AUDIT LOG ENDPOINTS =============
|
||||
@app.get("/api/inspections/{inspection_id}/audit-log", response_model=List[schemas.AuditLog])
|
||||
def get_inspection_audit_log(
|
||||
inspection_id: int,
|
||||
db: Session = Depends(get_db),
|
||||
current_user: models.User = Depends(get_current_user)
|
||||
):
|
||||
"""Obtener el historial de cambios de una inspección"""
|
||||
if current_user.role != "admin":
|
||||
raise HTTPException(status_code=403, detail="Solo administradores pueden ver el historial")
|
||||
|
||||
logs = db.query(models.InspectionAuditLog).filter(
|
||||
models.InspectionAuditLog.inspection_id == inspection_id
|
||||
).order_by(models.InspectionAuditLog.created_at.desc()).all()
|
||||
|
||||
# Agregar nombre de usuario a cada log
|
||||
result = []
|
||||
for log in logs:
|
||||
log_dict = {
|
||||
"id": log.id,
|
||||
"inspection_id": log.inspection_id,
|
||||
"answer_id": log.answer_id,
|
||||
"user_id": log.user_id,
|
||||
"action": log.action,
|
||||
"entity_type": log.entity_type,
|
||||
"field_name": log.field_name,
|
||||
"old_value": log.old_value,
|
||||
"new_value": log.new_value,
|
||||
"comment": log.comment,
|
||||
"created_at": log.created_at,
|
||||
"user_name": None
|
||||
}
|
||||
|
||||
user = db.query(models.User).filter(models.User.id == log.user_id).first()
|
||||
if user:
|
||||
log_dict["user_name"] = user.full_name or user.username
|
||||
|
||||
result.append(schemas.AuditLog(**log_dict))
|
||||
|
||||
return result
|
||||
|
||||
|
||||
@app.put("/api/answers/{answer_id}/admin-edit", response_model=schemas.Answer)
|
||||
def admin_edit_answer(
|
||||
answer_id: int,
|
||||
answer_edit: schemas.AnswerEdit,
|
||||
db: Session = Depends(get_db),
|
||||
current_user: models.User = Depends(get_current_user)
|
||||
):
|
||||
"""Editar una respuesta (solo admin) con registro de auditoría"""
|
||||
if current_user.role != "admin":
|
||||
raise HTTPException(status_code=403, detail="Solo administradores pueden editar respuestas")
|
||||
|
||||
db_answer = db.query(models.Answer).filter(models.Answer.id == answer_id).first()
|
||||
|
||||
if not db_answer:
|
||||
raise HTTPException(status_code=404, detail="Respuesta no encontrada")
|
||||
|
||||
# Registrar cambios en el log de auditoría
|
||||
changes = []
|
||||
|
||||
if answer_edit.answer_value is not None and answer_edit.answer_value != db_answer.answer_value:
|
||||
changes.append({
|
||||
"field_name": "answer_value",
|
||||
"old_value": db_answer.answer_value,
|
||||
"new_value": answer_edit.answer_value
|
||||
})
|
||||
db_answer.answer_value = answer_edit.answer_value
|
||||
|
||||
if answer_edit.status is not None and answer_edit.status != db_answer.status:
|
||||
changes.append({
|
||||
"field_name": "status",
|
||||
"old_value": db_answer.status,
|
||||
"new_value": answer_edit.status
|
||||
})
|
||||
|
||||
# Recalcular puntos
|
||||
question = db.query(models.Question).filter(
|
||||
models.Question.id == db_answer.question_id
|
||||
).first()
|
||||
|
||||
old_points = db_answer.points_earned
|
||||
if answer_edit.status == "ok":
|
||||
db_answer.points_earned = question.points
|
||||
elif answer_edit.status == "warning":
|
||||
db_answer.points_earned = int(question.points * 0.5)
|
||||
else:
|
||||
db_answer.points_earned = 0
|
||||
|
||||
if old_points != db_answer.points_earned:
|
||||
changes.append({
|
||||
"field_name": "points_earned",
|
||||
"old_value": str(old_points),
|
||||
"new_value": str(db_answer.points_earned)
|
||||
})
|
||||
|
||||
db_answer.status = answer_edit.status
|
||||
|
||||
if answer_edit.comment is not None and answer_edit.comment != db_answer.comment:
|
||||
changes.append({
|
||||
"field_name": "comment",
|
||||
"old_value": db_answer.comment or "",
|
||||
"new_value": answer_edit.comment
|
||||
})
|
||||
db_answer.comment = answer_edit.comment
|
||||
|
||||
if answer_edit.is_flagged is not None and answer_edit.is_flagged != db_answer.is_flagged:
|
||||
changes.append({
|
||||
"field_name": "is_flagged",
|
||||
"old_value": str(db_answer.is_flagged),
|
||||
"new_value": str(answer_edit.is_flagged)
|
||||
})
|
||||
db_answer.is_flagged = answer_edit.is_flagged
|
||||
|
||||
# Crear registros de auditoría para cada cambio
|
||||
for change in changes:
|
||||
audit_log = models.InspectionAuditLog(
|
||||
inspection_id=db_answer.inspection_id,
|
||||
answer_id=answer_id,
|
||||
user_id=current_user.id,
|
||||
action="updated",
|
||||
entity_type="answer",
|
||||
field_name=change["field_name"],
|
||||
old_value=change["old_value"],
|
||||
new_value=change["new_value"],
|
||||
comment=answer_edit.edit_comment or "Editado por administrador"
|
||||
)
|
||||
db.add(audit_log)
|
||||
|
||||
db_answer.updated_at = datetime.utcnow()
|
||||
db.commit()
|
||||
db.refresh(db_answer)
|
||||
|
||||
return db_answer
|
||||
|
||||
|
||||
# ============= MEDIA FILE ENDPOINTS =============
|
||||
@app.post("/api/answers/{answer_id}/upload", response_model=schemas.MediaFile)
|
||||
async def upload_photo(
|
||||
|
||||
Reference in New Issue
Block a user