Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 22 additions & 6 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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")
Expand Down
19 changes: 11 additions & 8 deletions components/etiquetas/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -33,7 +35,8 @@ def crear_etiqueta():
return jsonify({"id": etiqueta.id, "nombre": etiqueta.nombre}), 201


@etiquetas_bp.route('/<int:id_etiqueta>', methods=['GET'])
# 4. Actualizamos las rutas con ID para incluir el prefijo manualmente
@etiquetas_bp.route('/api/etiquetas/<int:id_etiqueta>', methods=['GET'])
def obtener_etiqueta(id_etiqueta):
"""Obtiene una etiqueta por su ID."""
etiqueta = Etiqueta.query.get(id_etiqueta)
Expand All @@ -42,7 +45,7 @@ def obtener_etiqueta(id_etiqueta):
return jsonify({"id": etiqueta.id, "nombre": etiqueta.nombre})


@etiquetas_bp.route('/<int:id_etiqueta>', methods=['PATCH'])
@etiquetas_bp.route('/api/etiquetas/<int:id_etiqueta>', methods=['PATCH'])
def actualizar_etiqueta(id_etiqueta):
"""Actualiza el nombre de una etiqueta existente."""
etiqueta = Etiqueta.query.get(id_etiqueta)
Expand All @@ -67,7 +70,7 @@ def actualizar_etiqueta(id_etiqueta):
return jsonify({"id": etiqueta.id, "nombre": etiqueta.nombre})


@etiquetas_bp.route('/<int:id_etiqueta>', methods=['DELETE'])
@etiquetas_bp.route('/api/etiquetas/<int:id_etiqueta>', methods=['DELETE'])
def eliminar_etiqueta(id_etiqueta):
"""Elimina una etiqueta por su ID."""
etiqueta = Etiqueta.query.get(id_etiqueta)
Expand All @@ -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"})