refactor: Migrate insights routes to blueprints
- Create new blueprints/admin/routes_insights.py - Move 5 insights routes (dashboard + API endpoints) - Update template to use new /admin/insights-api/* paths - Add endpoint aliases for backward compatibility Phase 6.2b - Insights routes Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
54c1878d66
commit
42f04e065f
30
app.py
30
app.py
@ -4000,9 +4000,9 @@ def test_sanitization():
|
||||
# DEVELOPMENT INSIGHTS (Roadmap from user feedback)
|
||||
# ============================================================
|
||||
|
||||
@app.route('/admin/insights')
|
||||
@login_required
|
||||
def admin_insights():
|
||||
# @app.route('/admin/insights') # MOVED TO admin.admin_insights
|
||||
# @login_required
|
||||
def _old_admin_insights():
|
||||
"""Admin dashboard for development insights from forum and chat"""
|
||||
if not current_user.is_admin:
|
||||
flash('Brak uprawnień do tej strony.', 'error')
|
||||
@ -4011,9 +4011,9 @@ def admin_insights():
|
||||
return render_template('admin/insights.html')
|
||||
|
||||
|
||||
@app.route('/api/admin/insights', methods=['GET'])
|
||||
@login_required
|
||||
def api_get_insights():
|
||||
# @app.route('/api/admin/insights', methods=['GET']) # MOVED TO admin.api_get_insights
|
||||
# @login_required
|
||||
def _old_api_get_insights():
|
||||
"""Get development insights for roadmap"""
|
||||
if not current_user.is_admin:
|
||||
return jsonify({'success': False, 'error': 'Admin access required'}), 403
|
||||
@ -4040,9 +4040,9 @@ def api_get_insights():
|
||||
return jsonify({'success': False, 'error': str(e)}), 500
|
||||
|
||||
|
||||
@app.route('/api/admin/insights/<int:insight_id>/status', methods=['PUT'])
|
||||
@login_required
|
||||
def api_update_insight_status(insight_id):
|
||||
# @app.route('/api/admin/insights/<int:insight_id>/status', methods=['PUT']) # MOVED TO admin.api_update_insight_status
|
||||
# @login_required
|
||||
def _old_api_update_insight_status(insight_id):
|
||||
"""Update insight status (for roadmap planning)"""
|
||||
if not current_user.is_admin:
|
||||
return jsonify({'success': False, 'error': 'Admin access required'}), 403
|
||||
@ -4066,9 +4066,9 @@ def api_update_insight_status(insight_id):
|
||||
return jsonify({'success': False, 'error': str(e)}), 500
|
||||
|
||||
|
||||
@app.route('/api/admin/insights/sync', methods=['POST'])
|
||||
@login_required
|
||||
def api_sync_insights():
|
||||
# @app.route('/api/admin/insights/sync', methods=['POST']) # MOVED TO admin.api_sync_insights
|
||||
# @login_required
|
||||
def _old_api_sync_insights():
|
||||
"""Manually trigger knowledge sync from forum and chat"""
|
||||
if not current_user.is_admin:
|
||||
return jsonify({'success': False, 'error': 'Admin access required'}), 403
|
||||
@ -4100,9 +4100,9 @@ def api_sync_insights():
|
||||
return jsonify({'success': False, 'error': str(e)}), 500
|
||||
|
||||
|
||||
@app.route('/api/admin/insights/stats', methods=['GET'])
|
||||
@login_required
|
||||
def api_insights_stats():
|
||||
# @app.route('/api/admin/insights/stats', methods=['GET']) # MOVED TO admin.api_insights_stats
|
||||
# @login_required
|
||||
def _old_api_insights_stats():
|
||||
"""Get knowledge base statistics"""
|
||||
if not current_user.is_admin:
|
||||
return jsonify({'success': False, 'error': 'Admin access required'}), 403
|
||||
|
||||
@ -253,6 +253,12 @@ def register_blueprints(app):
|
||||
'admin_announcements_publish': 'admin.admin_announcements_publish',
|
||||
'admin_announcements_archive': 'admin.admin_announcements_archive',
|
||||
'admin_announcements_delete': 'admin.admin_announcements_delete',
|
||||
# Insights (Phase 6.2b)
|
||||
'admin_insights': 'admin.admin_insights',
|
||||
'api_get_insights': 'admin.api_get_insights',
|
||||
'api_update_insight_status': 'admin.api_update_insight_status',
|
||||
'api_sync_insights': 'admin.api_sync_insights',
|
||||
'api_insights_stats': 'admin.api_insights_stats',
|
||||
})
|
||||
logger.info("Created admin endpoint aliases")
|
||||
except ImportError as e:
|
||||
|
||||
@ -15,3 +15,4 @@ from . import routes_status # noqa: E402, F401
|
||||
from . import routes_social # noqa: E402, F401
|
||||
from . import routes_security # noqa: E402, F401
|
||||
from . import routes_announcements # noqa: E402, F401
|
||||
from . import routes_insights # noqa: E402, F401
|
||||
|
||||
146
blueprints/admin/routes_insights.py
Normal file
146
blueprints/admin/routes_insights.py
Normal file
@ -0,0 +1,146 @@
|
||||
"""
|
||||
Admin Insights Routes
|
||||
======================
|
||||
|
||||
Development insights from forum and chat for roadmap planning.
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
from flask import render_template, request, redirect, url_for, flash, jsonify
|
||||
from flask_login import login_required, current_user
|
||||
|
||||
from . import bp
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# INSIGHTS DASHBOARD
|
||||
# ============================================================
|
||||
|
||||
@bp.route('/insights')
|
||||
@login_required
|
||||
def admin_insights():
|
||||
"""Admin dashboard for development insights from forum and chat"""
|
||||
if not current_user.is_admin:
|
||||
flash('Brak uprawnień do tej strony.', 'error')
|
||||
return redirect(url_for('dashboard'))
|
||||
|
||||
return render_template('admin/insights.html')
|
||||
|
||||
|
||||
@bp.route('/insights-api', methods=['GET'])
|
||||
@login_required
|
||||
def api_get_insights():
|
||||
"""Get development insights for roadmap"""
|
||||
if not current_user.is_admin:
|
||||
return jsonify({'success': False, 'error': 'Admin access required'}), 403
|
||||
|
||||
try:
|
||||
from norda_knowledge_service import get_knowledge_service
|
||||
service = get_knowledge_service()
|
||||
|
||||
status = request.args.get('status')
|
||||
insights = service.get_development_insights(status=status)
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'insights': insights,
|
||||
'count': len(insights)
|
||||
})
|
||||
except ImportError:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': 'Knowledge service not available'
|
||||
}), 500
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting insights: {e}")
|
||||
return jsonify({'success': False, 'error': str(e)}), 500
|
||||
|
||||
|
||||
@bp.route('/insights-api/<int:insight_id>/status', methods=['PUT'])
|
||||
@login_required
|
||||
def api_update_insight_status(insight_id):
|
||||
"""Update insight status (for roadmap planning)"""
|
||||
if not current_user.is_admin:
|
||||
return jsonify({'success': False, 'error': 'Admin access required'}), 403
|
||||
|
||||
try:
|
||||
from norda_knowledge_service import get_knowledge_service
|
||||
service = get_knowledge_service()
|
||||
|
||||
data = request.get_json()
|
||||
status = data.get('status')
|
||||
note = data.get('note')
|
||||
|
||||
if not status:
|
||||
return jsonify({'success': False, 'error': 'Status is required'}), 400
|
||||
|
||||
success = service.update_insight_status(insight_id, status, note)
|
||||
|
||||
return jsonify({'success': success})
|
||||
except Exception as e:
|
||||
logger.error(f"Error updating insight status: {e}")
|
||||
return jsonify({'success': False, 'error': str(e)}), 500
|
||||
|
||||
|
||||
@bp.route('/insights-api/sync', methods=['POST'])
|
||||
@login_required
|
||||
def api_sync_insights():
|
||||
"""Manually trigger knowledge sync from forum and chat"""
|
||||
if not current_user.is_admin:
|
||||
return jsonify({'success': False, 'error': 'Admin access required'}), 403
|
||||
|
||||
try:
|
||||
from norda_knowledge_service import get_knowledge_service
|
||||
service = get_knowledge_service()
|
||||
|
||||
data = request.get_json() or {}
|
||||
days_back = data.get('days_back', 30)
|
||||
|
||||
results = {
|
||||
'forum': service.sync_forum_knowledge(days_back),
|
||||
'chat': service.sync_chat_knowledge(days_back),
|
||||
'questions': service.analyze_user_questions(days_back)
|
||||
}
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'results': results
|
||||
})
|
||||
except ImportError:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': 'Knowledge service not available'
|
||||
}), 500
|
||||
except Exception as e:
|
||||
logger.error(f"Error syncing insights: {e}")
|
||||
return jsonify({'success': False, 'error': str(e)}), 500
|
||||
|
||||
|
||||
@bp.route('/insights-api/stats', methods=['GET'])
|
||||
@login_required
|
||||
def api_insights_stats():
|
||||
"""Get knowledge base statistics"""
|
||||
if not current_user.is_admin:
|
||||
return jsonify({'success': False, 'error': 'Admin access required'}), 403
|
||||
|
||||
try:
|
||||
from norda_knowledge_service import get_knowledge_service
|
||||
service = get_knowledge_service()
|
||||
|
||||
stats = service.get_knowledge_stats()
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'stats': stats
|
||||
})
|
||||
except ImportError:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': 'Knowledge service not available'
|
||||
}), 500
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting stats: {e}")
|
||||
return jsonify({'success': False, 'error': str(e)}), 500
|
||||
@ -268,8 +268,8 @@ async function loadInsights() {
|
||||
|
||||
try {
|
||||
const url = currentStatus
|
||||
? `/api/admin/insights?status=${currentStatus}`
|
||||
: '/api/admin/insights';
|
||||
? `/admin/insights-api?status=${currentStatus}`
|
||||
: '/admin/insights-api';
|
||||
|
||||
const response = await fetch(url);
|
||||
const data = await response.json();
|
||||
@ -326,7 +326,7 @@ async function loadInsights() {
|
||||
|
||||
async function loadStats() {
|
||||
try {
|
||||
const response = await fetch('/api/admin/insights/stats');
|
||||
const response = await fetch('/admin/insights-api/stats');
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success && data.stats) {
|
||||
@ -342,7 +342,7 @@ async function updateInsightStatus(insightId, status) {
|
||||
if (!status) return;
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/admin/insights/${insightId}/status`, {
|
||||
const response = await fetch(`/admin/insights-api/${insightId}/status`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ status })
|
||||
@ -366,7 +366,7 @@ async function syncInsights() {
|
||||
btn.innerHTML = '<span class="spinner"></span> Synchronizuję...';
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/admin/insights/sync', {
|
||||
const response = await fetch('/admin/insights-api/sync', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ days_back: 30 })
|
||||
|
||||
Loading…
Reference in New Issue
Block a user