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//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}')