Files
Autoparts-DB/manager/app.py
consultoria-as a386ca5b4a
Some checks failed
CI / lint-and-test (3.11) (push) Has been cancelled
CI / lint-and-test (3.13) (push) Has been cancelled
Mejoras de sesion: estabilizacion, IA, Nexus Yonke y marketplace B2B
- F0 blindaje: Redis/Celery, pg_hba sin trust LAN, secretos a env 600, backups, webhook auth, jobs muertos
- F1 caja: bugs POS, reembolsos al corte, apartados, CFDI, topes de descuento en cotizacion/apartado
- F2/F7 IA de catalogo: autocategorizacion, dedup de SKUs con embeddings, OCR de facturas, descripciones, claves SAT, limpieza de fitment
- F3 IA en el flujo: vision Yonke, preguntas MeLi, venta cruzada, anomalias, sinonimos, busqueda semantica (rerank/embeddings)
- F4/F8 escala y cartera: /metrics+Prometheus+Grafana, pool, score de credito, churn, metricas multi-tenant
- Nexus Yonke (M1-M6): modelo de datos 1-de-1, alta por donador, vitrina publica, MeLi usado, consignacion, garantia por dias, reportes, etiquetas
- Marketplace B2B entre yonkes (catalogo + pedidos cross-tenant)
- Seguridad: auth en /api/admin/* (35 endpoints), alertas por tenant
- Migraciones v4.27/v4.28; timers expire-demos y rollup-metrics
2026-10-12 00:57:31 +00:00

106 lines
3.5 KiB
Python

"""Nexus Instance Manager — Flask Application."""
import os
import sys
from datetime import datetime
from flask import Flask, jsonify, render_template, send_from_directory, request
# Ensure POS modules are importable for tenant_manager reuse
POS_DIR = os.environ.get("POS_DIR", "/home/Autopartes/pos")
if POS_DIR not in sys.path:
sys.path.insert(0, POS_DIR)
from config import APP_NAME, APP_VERSION
from blueprints.auth_bp import auth_bp, require_manager_auth
from blueprints.tenants_bp import tenants_bp
from blueprints.demos_bp import demos_bp
from blueprints.health_bp import health_bp
from blueprints.admin_bp import admin_bp
from blueprints.portfolio_bp import portfolio_bp
def create_app():
app = Flask(
__name__,
template_folder="templates",
static_folder="static"
)
app.secret_key = os.environ.get("MANAGER_JWT_SECRET", "dev-secret-change-me")
# Register blueprints
app.register_blueprint(auth_bp)
app.register_blueprint(tenants_bp)
app.register_blueprint(demos_bp)
app.register_blueprint(health_bp)
app.register_blueprint(admin_bp)
app.register_blueprint(portfolio_bp)
# ─── Frontend Routes ───────────────────────────────────────────────────
@app.route("/")
def index():
return render_template("index.html")
@app.route("/login")
def login_page():
return render_template("index.html")
@app.route("/dashboard")
def dashboard_page():
return render_template("index.html")
@app.route("/tenants")
def tenants_page():
return render_template("index.html")
@app.route("/demos")
def demos_page():
return render_template("index.html")
@app.route("/health")
def health_page():
return render_template("index.html")
@app.route("/portfolio")
def portfolio_page():
return render_template("index.html")
@app.route("/migrations")
def migrations_page():
return render_template("index.html")
# ─── Static Asset Helpers ──────────────────────────────────────────────
@app.route("/static/<path:filename>")
def static_files(filename):
return send_from_directory("static", filename)
# ─── API Status ────────────────────────────────────────────────────────
@app.route("/api/status")
def api_status():
return jsonify({
"app": APP_NAME,
"version": APP_VERSION,
"timestamp": datetime.utcnow().isoformat(),
"pos_dir": POS_DIR
})
# ─── Error Handlers ────────────────────────────────────────────────────
@app.errorhandler(404)
def not_found(e):
if request.path.startswith("/api/"):
return jsonify({"error": "Not found"}), 404
return render_template("index.html")
@app.errorhandler(500)
def internal_error(e):
if request.path.startswith("/api/"):
return jsonify({"error": "Internal server error"}), 500
return render_template("index.html")
return app
# Entry point for Gunicorn: gunicorn -w 2 -b 0.0.0.0:5003 app:app
app = create_app()
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5003, debug=True)