Initial commit
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
import logging
|
||||
from flask import Blueprint, jsonify, request
|
||||
from flask_login import login_required, current_user
|
||||
from flask_socketio import emit, join_room, leave_room
|
||||
from app import db, socketio
|
||||
from app.models import Notification, Ticket, TicketStatus, TicketPriority
|
||||
from app.services.log_service import log_action
|
||||
|
||||
api_bp = Blueprint('api', __name__, url_prefix='/api')
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# ─── Notifications API ────────────────────────────────────────────────────────
|
||||
|
||||
@api_bp.route('/notifications/unread-count')
|
||||
@login_required
|
||||
def unread_count():
|
||||
count = Notification.query.filter_by(user_id=current_user.id, is_read=False).count()
|
||||
return jsonify({'count': count})
|
||||
|
||||
|
||||
@api_bp.route('/notifications/<int:notif_id>/read', methods=['POST'])
|
||||
@login_required
|
||||
def mark_read(notif_id):
|
||||
notif = Notification.query.filter_by(id=notif_id, user_id=current_user.id).first_or_404()
|
||||
notif.is_read = True
|
||||
db.session.commit()
|
||||
return jsonify({'ok': True})
|
||||
|
||||
|
||||
@api_bp.route('/notifications/mark-all-read', methods=['POST'])
|
||||
@login_required
|
||||
def mark_all_read():
|
||||
Notification.query.filter_by(user_id=current_user.id, is_read=False).update({'is_read': True})
|
||||
db.session.commit()
|
||||
return jsonify({'ok': True})
|
||||
|
||||
|
||||
# ─── Ticket Stats API (IT) ────────────────────────────────────────────────────
|
||||
|
||||
@api_bp.route('/stats/tickets')
|
||||
@login_required
|
||||
def ticket_stats():
|
||||
if not current_user.is_it_staff:
|
||||
return jsonify({'error': 'Forbidden'}), 403
|
||||
stats = {
|
||||
'open' : Ticket.query.filter_by(status=TicketStatus.OPEN).count(),
|
||||
'in_progress' : Ticket.query.filter_by(status=TicketStatus.IN_PROGRESS).count(),
|
||||
'pending' : Ticket.query.filter_by(status=TicketStatus.PENDING).count(),
|
||||
'resolved' : Ticket.query.filter_by(status=TicketStatus.RESOLVED).count(),
|
||||
'closed' : Ticket.query.filter_by(status=TicketStatus.CLOSED).count(),
|
||||
}
|
||||
return jsonify(stats)
|
||||
|
||||
|
||||
# ─── WebSocket Events ─────────────────────────────────────────────────────────
|
||||
|
||||
@socketio.on('connect')
|
||||
def on_connect():
|
||||
if current_user.is_authenticated:
|
||||
join_room(f'user_{current_user.id}')
|
||||
logger.info(f'[SOCKET CONNECT] user_id={current_user.id}')
|
||||
|
||||
|
||||
@socketio.on('disconnect')
|
||||
def on_disconnect():
|
||||
if current_user.is_authenticated:
|
||||
leave_room(f'user_{current_user.id}')
|
||||
logger.info(f'[SOCKET DISCONNECT] user_id={current_user.id}')
|
||||
|
||||
|
||||
@socketio.on('join_ticket')
|
||||
def on_join_ticket(data):
|
||||
if current_user.is_authenticated:
|
||||
ticket_id = data.get('ticket_id')
|
||||
join_room(f'ticket_{ticket_id}')
|
||||
|
||||
|
||||
@socketio.on('leave_ticket')
|
||||
def on_leave_ticket(data):
|
||||
if current_user.is_authenticated:
|
||||
ticket_id = data.get('ticket_id')
|
||||
leave_room(f'ticket_{ticket_id}')
|
||||
Reference in New Issue
Block a user