feat(sync): add academic data reset tool, configurable sheets URL and fix sync timeout
This commit is contained in:
@@ -981,3 +981,118 @@ def delete_milestone_type(id):
|
||||
'message': 'Tipificación eliminada permanentemente.'
|
||||
}), 200
|
||||
|
||||
# ---------------------------------------------------------
|
||||
# GOOGLE SHEETS CONFIGURATION & ACADEMIC DATA RESET TOOL
|
||||
# ---------------------------------------------------------
|
||||
|
||||
@api_admin_bp.route('/sheets-config', methods=['GET'])
|
||||
@jwt_required
|
||||
def get_sheets_config():
|
||||
"""Obtiene la configuración actual del Google Sheet para sincronización."""
|
||||
from app.models.setting import SystemSetting
|
||||
from app.services.sheets_importer import BASE_CSV_URL, normalize_sheets_url
|
||||
import os
|
||||
|
||||
db_url = SystemSetting.get_value('google_sheets_url')
|
||||
env_url = os.getenv('GOOGLE_SHEETS_URL')
|
||||
active_url = db_url or env_url or BASE_CSV_URL
|
||||
source = 'database' if db_url else ('environment' if env_url else 'default')
|
||||
|
||||
return jsonify({
|
||||
'status': 'success',
|
||||
'config': {
|
||||
'active_url': active_url,
|
||||
'source': source,
|
||||
'db_url': db_url,
|
||||
'default_url': BASE_CSV_URL,
|
||||
'normalized_url': normalize_sheets_url(active_url)
|
||||
}
|
||||
}), 200
|
||||
|
||||
@api_admin_bp.route('/sheets-config', methods=['POST'])
|
||||
@jwt_required
|
||||
def update_sheets_config():
|
||||
"""Actualiza la URL del Google Sheet en SystemSetting."""
|
||||
from app.models.setting import SystemSetting
|
||||
from app.services.sheets_importer import normalize_sheets_url
|
||||
|
||||
data = request.get_json(silent=True) or request.form.to_dict() or {}
|
||||
url = (data.get('url') or data.get('google_sheets_url') or '').strip()
|
||||
|
||||
if not url:
|
||||
return jsonify({
|
||||
'error': 'ValidationError',
|
||||
'message': 'La URL de Google Sheets no puede estar vacía.'
|
||||
}), 400
|
||||
|
||||
normalized = normalize_sheets_url(url)
|
||||
SystemSetting.set_value('google_sheets_url', url, 'URL del Google Sheet académico configurada desde panel')
|
||||
|
||||
return jsonify({
|
||||
'status': 'success',
|
||||
'message': 'Configuración de Google Sheets guardada correctamente.',
|
||||
'config': {
|
||||
'active_url': url,
|
||||
'normalized_url': normalized,
|
||||
'source': 'database'
|
||||
}
|
||||
}), 200
|
||||
|
||||
@api_admin_bp.route('/reset-academic-data', methods=['POST'])
|
||||
@jwt_required
|
||||
def reset_academic_data_api():
|
||||
"""
|
||||
Herramienta de limpieza/purga de datos académicos para pruebas del importador.
|
||||
Permite eliminar reservas, comisiones, asignaturas, carreras y aulas.
|
||||
"""
|
||||
from scripts.reset_academic_data import execute_academic_reset
|
||||
data = request.get_json(silent=True) or request.form.to_dict() or {}
|
||||
|
||||
reset_all = data.get('all', False) in [True, 'true', '1', 'on']
|
||||
reset_reservations = reset_all or data.get('reservations', True) in [True, 'true', '1', 'on']
|
||||
reset_commissions = reset_all or data.get('commissions', False) in [True, 'true', '1', 'on']
|
||||
reset_subjects = reset_all or data.get('subjects', False) in [True, 'true', '1', 'on']
|
||||
reset_careers = reset_all or data.get('careers', False) in [True, 'true', '1', 'on']
|
||||
reset_classrooms = reset_all or data.get('classrooms', False) in [True, 'true', '1', 'on']
|
||||
|
||||
if reset_all:
|
||||
reset_reservations = True
|
||||
reset_commissions = True
|
||||
reset_subjects = True
|
||||
reset_careers = True
|
||||
reset_classrooms = True
|
||||
|
||||
result = execute_academic_reset(
|
||||
reset_reservations=reset_reservations,
|
||||
reset_commissions=reset_commissions,
|
||||
reset_subjects=reset_subjects,
|
||||
reset_careers=reset_careers,
|
||||
reset_classrooms=reset_classrooms
|
||||
)
|
||||
|
||||
if result.get('success'):
|
||||
try:
|
||||
from app.models.audit_log import AuditLog
|
||||
audit = AuditLog(
|
||||
user_id=getattr(request, 'current_user_id', None),
|
||||
action_type='ACADEMIC_DATA_PURGE',
|
||||
details=f"Purga académica ejecutada: {result.get('deleted')}",
|
||||
ip_address=request.remote_addr
|
||||
)
|
||||
db.session.add(audit)
|
||||
db.session.commit()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return jsonify({
|
||||
'status': 'success',
|
||||
'message': result.get('message', 'Datos reiniciados con éxito.'),
|
||||
'deleted': result.get('deleted', {})
|
||||
}), 200
|
||||
else:
|
||||
return jsonify({
|
||||
'status': 'error',
|
||||
'message': result.get('error', 'Error durante la purga de datos.')
|
||||
}), 500
|
||||
|
||||
|
||||
|
||||
@@ -169,11 +169,14 @@ def sync_google_sheets():
|
||||
"""Ejecuta la sincronización real con las hojas de cálculo de Google Sheets."""
|
||||
from app.services.sheets_importer import GoogleSheetsImporter
|
||||
try:
|
||||
importer = GoogleSheetsImporter()
|
||||
data = request.get_json(silent=True) or {}
|
||||
custom_url = data.get('sheets_url') or data.get('base_url')
|
||||
importer = GoogleSheetsImporter(base_url=custom_url)
|
||||
stats = importer.sync()
|
||||
return jsonify({
|
||||
'status': 'success',
|
||||
'stats': stats
|
||||
'stats': stats,
|
||||
'source_url': importer.base_url
|
||||
}), 200
|
||||
except Exception as e:
|
||||
return jsonify({
|
||||
|
||||
Reference in New Issue
Block a user