diff --git a/app.py b/app.py index 0c97475..07cf717 100644 --- a/app.py +++ b/app.py @@ -12,6 +12,8 @@ from functools import wraps from datetime import datetime from flask_migrate import Migrate +# 1. IMPORTANTE: Importar ProxyFix para Google Cloud Run/Render +from werkzeug.middleware.proxy_fix import ProxyFix # Imports de modelos y rutas from core.models import db, Usuario @@ -39,6 +41,16 @@ app = Flask(__name__) +# 2. IMPORTANTE: Configurar ProxyFix +# Esto le dice a Flask que confíe en los headers HTTPS de Cloud Run +app.wsgi_app = ProxyFix( + app.wsgi_app, + x_for=1, + x_proto=1, + x_host=1, + x_prefix=1 +) + def cerrar_sesion(): """ Cierra la sesión de base de datos de forma segura. @@ -76,11 +88,11 @@ def shutdown_session(exception=None): app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv("DATABASE_URL") app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False app.config['SQLALCHEMY_ENGINE_OPTIONS'] = { - "pool_size": 5, - "max_overflow": 10, - "pool_timeout": 30, - "pool_recycle": 1800, - "pool_pre_ping": True + "pool_size": 5, + "max_overflow": 10, + "pool_timeout": 30, + "pool_recycle": 1800, + "pool_pre_ping": True } db.init_app(app) @@ -112,7 +124,11 @@ def shutdown_session(exception=None): app.register_blueprint(qr_bp) app.register_blueprint(pdf_bp) app.register_blueprint(ubicacion_bp) -app.register_blueprint(etiquetas_bp, url_prefix='/api/etiquetas') + +# 3. CAMBIO CRÍTICO: Quitamos el url_prefix aquí +# Porque ya lo pusiste manualmente en routes.py (/api/etiquetas) +app.register_blueprint(etiquetas_bp) + app.register_blueprint(roles_bp) app.register_blueprint(overpass_bp) app.register_blueprint(admin_bp, url_prefix="/api") diff --git a/components/etiquetas/routes.py b/components/etiquetas/routes.py index 5dc763c..cbfd1ba 100644 --- a/components/etiquetas/routes.py +++ b/components/etiquetas/routes.py @@ -2,17 +2,19 @@ from core.models import db, Etiqueta from sqlalchemy.exc import IntegrityError -etiquetas_bp = Blueprint('etiquetas', __name__, url_prefix='/api/etiquetas') +# 1. Quitamos el url_prefix para tener control total de la ruta +etiquetas_bp = Blueprint('etiquetas', __name__) - -@etiquetas_bp.route('/', methods=['GET']) +# 2. Definimos la ruta explícita SIN barra al final +@etiquetas_bp.route('/api/etiquetas', methods=['GET']) def listar_etiquetas(): """Lista todas las etiquetas ordenadas por nombre.""" etiquetas = Etiqueta.query.order_by(Etiqueta.nombre).all() return jsonify([{"id": e.id, "nombre": e.nombre} for e in etiquetas]) -@etiquetas_bp.route('/', methods=['POST']) +# 3. Lo mismo para el POST: ruta sin barra final +@etiquetas_bp.route('/api/etiquetas', methods=['POST']) def crear_etiqueta(): """Crea una nueva etiqueta si el nombre es válido y no existe.""" data = request.json @@ -33,7 +35,8 @@ def crear_etiqueta(): return jsonify({"id": etiqueta.id, "nombre": etiqueta.nombre}), 201 -@etiquetas_bp.route('/', methods=['GET']) +# 4. Actualizamos las rutas con ID para incluir el prefijo manualmente +@etiquetas_bp.route('/api/etiquetas/', methods=['GET']) def obtener_etiqueta(id_etiqueta): """Obtiene una etiqueta por su ID.""" etiqueta = Etiqueta.query.get(id_etiqueta) @@ -42,7 +45,7 @@ def obtener_etiqueta(id_etiqueta): return jsonify({"id": etiqueta.id, "nombre": etiqueta.nombre}) -@etiquetas_bp.route('/', methods=['PATCH']) +@etiquetas_bp.route('/api/etiquetas/', methods=['PATCH']) def actualizar_etiqueta(id_etiqueta): """Actualiza el nombre de una etiqueta existente.""" etiqueta = Etiqueta.query.get(id_etiqueta) @@ -67,7 +70,7 @@ def actualizar_etiqueta(id_etiqueta): return jsonify({"id": etiqueta.id, "nombre": etiqueta.nombre}) -@etiquetas_bp.route('/', methods=['DELETE']) +@etiquetas_bp.route('/api/etiquetas/', methods=['DELETE']) def eliminar_etiqueta(id_etiqueta): """Elimina una etiqueta por su ID.""" etiqueta = Etiqueta.query.get(id_etiqueta) @@ -81,4 +84,4 @@ def eliminar_etiqueta(id_etiqueta): db.session.rollback() return jsonify({"error": "No se pudo eliminar, puede estar en uso"}), 500 - return jsonify({"mensaje": "Etiqueta eliminada correctamente"}) + return jsonify({"mensaje": "Etiqueta eliminada correctamente"}) \ No newline at end of file