from flask import Blueprint, request, jsonify from api.utils import get_validated_user_id, admin_required from db.tracking import get_tracking_events_by_child, get_tracking_events_by_user from models.tracking_event import TrackingEvent tracking_api = Blueprint('tracking_api', __name__) @tracking_api.route('/admin/tracking', methods=['GET']) @admin_required def get_tracking(): """ Admin endpoint to query tracking events with filters and pagination. Query params: - child_id: Filter by child ID (optional) - user_id: Filter by user ID (optional, admin only) - entity_type: Filter by entity type (task/reward/penalty) (optional) - action: Filter by action type (activated/requested/redeemed/cancelled) (optional) - limit: Max results (default 50, max 500) - offset: Pagination offset (default 0) """ child_id = request.args.get('child_id') filter_user_id = request.args.get('user_id') entity_type = request.args.get('entity_type') action = request.args.get('action') limit = int(request.args.get('limit', 50)) offset = int(request.args.get('offset', 0)) # Validate limit limit = min(max(limit, 1), 500) offset = max(offset, 0) # Validate filters if entity_type and entity_type not in ['task', 'reward', 'penalty']: return jsonify({'error': 'Invalid entity_type', 'code': 'INVALID_ENTITY_TYPE'}), 400 if action and action not in ['activated', 'requested', 'redeemed', 'cancelled']: return jsonify({'error': 'Invalid action', 'code': 'INVALID_ACTION'}), 400 # Query tracking events if child_id: events, total = get_tracking_events_by_child( child_id=child_id, limit=limit, offset=offset, entity_type=entity_type, action=action ) elif filter_user_id: events, total = get_tracking_events_by_user( user_id=filter_user_id, limit=limit, offset=offset, entity_type=entity_type ) else: return jsonify({ 'error': 'Either child_id or user_id is required', 'code': 'MISSING_FILTER' }), 400 # Convert to dict events_data = [event.to_dict() for event in events] return jsonify({ 'tracking_events': events_data, 'total': total, 'limit': limit, 'offset': offset, 'count': len(events_data) }), 200