mirror of
https://github.com/jhd3197/ServerKit.git
synced 2026-10-30 16:47:01 +09:00
- One-shot auto-install migration (extension_migration.py): converted builtins auto-install on upgrade, marketplace-only on fresh install, user uninstall respected - Convert GPU Monitor → serverkit-gpu and Workflow Builder → serverkit-workflows (manifest-driven nav/route/title/palette; pages + backend stay core, D2) - Module toggles (#14): module_service + /api/v1/modules + 503 guards on email/wordpress; frontend useModules hook, sidebar gating, ModuleRoute guard, Settings → Modules card - Marketplace curation polish (#15): by-ServerKit badge, real category chips, detail modal with icon + screenshots - Tests: test_extension_migration.py, test_module_toggles.py (backend suite green) Tab-grouped conversions (#8/#9/#10/#12/#13) deferred to after the Phase 3 tab-slot primitive (#27) to avoid a grouped-UX regression — see plan doc. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
52 lines
1.6 KiB
Python
52 lines
1.6 KiB
Python
"""Modules API — toggle heavy core verticals (Email, WordPress) on/off.
|
|
|
|
Read is available to any authenticated user (the frontend needs it to hide nav
|
|
and guard routes); flipping a toggle is admin-only.
|
|
"""
|
|
from flask import Blueprint, request, jsonify
|
|
from flask_jwt_extended import jwt_required
|
|
|
|
from app.services import module_service
|
|
from app.services.audit_service import AuditService
|
|
from app.models.audit_log import AuditLog
|
|
|
|
modules_bp = Blueprint('modules', __name__)
|
|
|
|
|
|
def _current_user():
|
|
from flask_jwt_extended import get_jwt_identity
|
|
from app.models.user import User
|
|
return User.query.get(get_jwt_identity())
|
|
|
|
|
|
@modules_bp.route('', methods=['GET'])
|
|
@modules_bp.route('/', methods=['GET'])
|
|
@jwt_required()
|
|
def list_modules():
|
|
return jsonify({'modules': module_service.list_modules()})
|
|
|
|
|
|
@modules_bp.route('/<name>', methods=['PUT'])
|
|
@jwt_required()
|
|
def set_module(name):
|
|
user = _current_user()
|
|
if not user or not user.is_admin:
|
|
return jsonify({'error': 'Admin access required'}), 403
|
|
|
|
if name not in module_service.MODULES:
|
|
return jsonify({'error': f'Unknown module: {name}'}), 404
|
|
|
|
data = request.get_json() or {}
|
|
if 'enabled' not in data:
|
|
return jsonify({'error': 'enabled (boolean) required'}), 400
|
|
|
|
enabled = module_service.set_module_enabled(name, bool(data['enabled']), user_id=user.id)
|
|
AuditService.log(
|
|
action=AuditLog.ACTION_RESOURCE_ENABLE if enabled else AuditLog.ACTION_RESOURCE_DISABLE,
|
|
user_id=user.id,
|
|
target_type='module',
|
|
target_id=None,
|
|
details={'module': name, 'enabled': enabled},
|
|
)
|
|
return jsonify({'name': name, 'enabled': enabled})
|