feat(manager): add Nexus Instance Manager for demo orchestration
- Complete Flask-based control panel for multi-tenant POS instances - Dashboard with global stats, system health, and recent demos - Demo provisioning in 1 click with auto-expiration tracking - Tenant management: activate/deactivate, reset data, delete - Health monitoring: PostgreSQL, Redis, disk, memory, systemd services - Migration orchestration UI for running schema updates across all tenants - JWT authentication with manager_users table - Dark theme SPA frontend with real-time search and actions - systemd service file included
This commit is contained in:
60
manager/blueprints/tenants_bp.py
Normal file
60
manager/blueprints/tenants_bp.py
Normal file
@@ -0,0 +1,60 @@
|
||||
"""Tenant management blueprint."""
|
||||
from flask import Blueprint, request, jsonify
|
||||
from blueprints.auth_bp import require_manager_auth
|
||||
from services import tenant_service
|
||||
|
||||
tenants_bp = Blueprint("tenants", __name__, url_prefix="/api/tenants")
|
||||
|
||||
|
||||
@tenants_bp.route("", methods=["GET"])
|
||||
@require_manager_auth
|
||||
def list_tenants():
|
||||
include_stats = request.args.get("stats", "false").lower() == "true"
|
||||
return jsonify({"data": tenant_service.list_tenants(include_stats=include_stats)})
|
||||
|
||||
|
||||
@tenants_bp.route("/<int:tenant_id>", methods=["GET"])
|
||||
@require_manager_auth
|
||||
def get_tenant(tenant_id):
|
||||
tenant = tenant_service.get_tenant(tenant_id)
|
||||
if not tenant:
|
||||
return jsonify({"error": "Tenant not found"}), 404
|
||||
return jsonify({"data": tenant})
|
||||
|
||||
|
||||
@tenants_bp.route("/<int:tenant_id>/stats", methods=["GET"])
|
||||
@require_manager_auth
|
||||
def get_tenant_stats(tenant_id):
|
||||
tenant = tenant_service.get_tenant(tenant_id)
|
||||
if not tenant:
|
||||
return jsonify({"error": "Tenant not found"}), 404
|
||||
return jsonify({"data": tenant_service._get_tenant_quick_stats(tenant["db_name"])})
|
||||
|
||||
|
||||
@tenants_bp.route("/<int:tenant_id>/toggle", methods=["POST"])
|
||||
@require_manager_auth
|
||||
def toggle_tenant(tenant_id):
|
||||
data = request.get_json() or {}
|
||||
active = data.get("active", True)
|
||||
result = tenant_service.toggle_tenant(tenant_id, active)
|
||||
return jsonify(result)
|
||||
|
||||
|
||||
@tenants_bp.route("/<int:tenant_id>/reset", methods=["POST"])
|
||||
@require_manager_auth
|
||||
def reset_tenant(tenant_id):
|
||||
try:
|
||||
result = tenant_service.reset_tenant(tenant_id)
|
||||
return jsonify(result)
|
||||
except Exception as e:
|
||||
return jsonify({"error": str(e)}), 500
|
||||
|
||||
|
||||
@tenants_bp.route("/<int:tenant_id>", methods=["DELETE"])
|
||||
@require_manager_auth
|
||||
def delete_tenant(tenant_id):
|
||||
try:
|
||||
result = tenant_service.delete_tenant(tenant_id)
|
||||
return jsonify(result)
|
||||
except Exception as e:
|
||||
return jsonify({"error": str(e)}), 500
|
||||
Reference in New Issue
Block a user