Files
openccb/TOKEN_LIMITS_GUIDE.md
T
2026-03-23 16:11:15 -03:00

8.2 KiB

Límites de Tokens Mensuales por Usuario

Visión General

OpenCCB ahora soporta límites de tokens de IA mensuales configurables por usuario, permitiendo controlar el consumo de IA y prevenir usos excesivos.


Características

Configuración por Usuario

Cada usuario puede tener:

  • Límite mensual personalizado: Número máximo de tokens que puede consumir por mes
  • Día de reset: Día del mes cuando se reinicia el contador (1-28)
  • Ilimitado: Configurando límite en 0

Valores por Defecto

  • Límite: 100,000 tokens/mes
  • Día de reset: 1 (primero del mes)
  • Unlimited: monthly_token_limit = 0

Esquema de Base de Datos

Tabla users (Nuevas Columnas)

monthly_token_limit INTEGER DEFAULT 100000
  -- Límite mensual de tokens (0 = ilimitado)

token_limit_reset_day INTEGER DEFAULT 1
  -- Día del mes para resetear (1-28)

Vista ai_usage_monthly

Muestra el uso actual del mes por usuario:

SELECT * FROM ai_usage_monthly 
WHERE user_id = '{user-uuid}';

Columnas:

  • user_id: UUID del usuario
  • organization_id: UUID de la organización
  • usage_month: Mes de uso
  • total_tokens: Total de tokens consumidos
  • input_tokens: Tokens de entrada (prompts)
  • output_tokens: Tokens de salida (respuestas)
  • total_requests: Número de peticiones a IA
  • total_cost_usd: Costo estimado en USD

Funciones SQL

check_token_limit(user_id, additional_tokens)

Verifica si un usuario tiene tokens disponibles.

SELECT * FROM check_token_limit(
    'user-uuid'::UUID,
    1000  -- Tokens adicionales a verificar
);

Retorna:

  • has_available_tokens: BOOLEAN - ¿Tiene tokens disponibles?
  • monthly_limit: INTEGER - Límite mensual configurado
  • used_tokens: BIGINT - Tokens ya usados este mes
  • remaining_tokens: BIGINT - Tokens restantes
  • reset_date: TIMESTAMPTZ - Fecha del próximo reset

get_user_usage_stats(user_id, months)

Obtiene estadísticas históricas de uso.

SELECT * FROM get_user_usage_stats(
    'user-uuid'::UUID,
    3  -- Últimos 3 meses
);

Retorna:

  • month_start: DATE - Inicio del mes
  • total_tokens: BIGINT - Tokens totales
  • input_tokens: BIGINT - Tokens de entrada
  • output_tokens: BIGINT - Tokens de salida
  • total_requests: BIGINT - Número de peticiones
  • total_cost_usd: NUMERIC - Costo estimado
  • monthly_limit: INTEGER - Límite del mes
  • percentage_used: NUMERIC - Porcentaje usado

API Endpoints

1. Establecer Límite Mensual

PUT /api/admin/users/{user_id}/token-limit
Authorization: Bearer {admin_token}
Content-Type: application/json

{
  "monthly_token_limit": 50000,
  "token_limit_reset_day": 15
}

Parámetros:

  • monthly_token_limit (integer): Límite mensual (0 = ilimitado)
  • token_limit_reset_day (integer, opcional): Día de reset (1-28, default: 1)

Respuesta: 200 OK


2. Ver Uso de Tokens de Usuario

GET /api/admin/users/{user_id}/token-usage
Authorization: Bearer {admin_token}

Respuesta:

{
  "user_id": "uuid",
  "email": "user@example.com",
  "full_name": "Nombre Usuario",
  "monthly_token_limit": 100000,
  "token_limit_reset_day": 1,
  "used_tokens": 45678,
  "total_requests": 234,
  "total_cost_usd": 0.05,
  "last_used": "2026-03-23T10:30:00Z"
}

3. Verificar Límite Disponible

GET /api/admin/users/{user_id}/token-limit/check
Authorization: Bearer {admin_token}

Respuesta:

{
  "has_available_tokens": true,
  "monthly_limit": 100000,
  "used_tokens": 45678,
  "remaining_tokens": 54322,
  "reset_date": "2026-04-01T00:00:00Z"
}

Ejemplos de Uso

Ejemplo 1: Establecer Límite de 50K Tokens

curl -X PUT "http://localhost:3001/api/admin/users/{user-id}/token-limit" \
  -H "Authorization: Bearer {admin-token}" \
  -H "Content-Type: application/json" \
  -d '{
    "monthly_token_limit": 50000,
    "token_limit_reset_day": 1
  }'

Ejemplo 2: Verificar Tokens Disponibles

curl "http://localhost:3001/api/admin/users/{user-id}/token-limit/check" \
  -H "Authorization: Bearer {admin-token}"

Ejemplo 3: Obtener Uso del Mes

curl "http://localhost:3001/api/admin/users/{user-id}/token-usage" \
  -H "Authorization: Bearer {admin-token}"

Ejemplo 4: SQL Directo

-- Ver uso actual de todos los usuarios
SELECT 
    u.email,
    u.full_name,
    u.monthly_token_limit,
    COALESCE(SUM(au.tokens_used), 0) as used_tokens,
    u.monthly_token_limit - COALESCE(SUM(au.tokens_used), 0) as remaining_tokens,
    CASE 
        WHEN u.monthly_token_limit = 0 THEN 'Unlimited'
        ELSE ROUND((COALESCE(SUM(au.tokens_used), 0)::NUMERIC / u.monthly_token_limit * 100)::NUMERIC, 2) || '%'
    END as usage_percentage
FROM users u
LEFT JOIN ai_usage_logs au ON u.id = au.user_id
    AND au.created_at >= DATE_TRUNC('month', NOW())
GROUP BY u.id, u.email, u.full_name, u.monthly_token_limit
ORDER BY used_tokens DESC;

Estrategias de Límites

Por Rol de Usuario

-- Estudiantes: 50K tokens/mes
UPDATE users SET monthly_token_limit = 50000 WHERE role = 'student';

-- Instructores: 200K tokens/mes
UPDATE users SET monthly_token_limit = 200000 WHERE role = 'instructor';

-- Admins: Ilimitado
UPDATE users SET monthly_token_limit = 0 WHERE role = 'admin';

Por Tipo de Plan

-- Plan Básico: 25K tokens
UPDATE users SET monthly_token_limit = 25000 WHERE plan = 'basic';

-- Plan Pro: 100K tokens
UPDATE users SET monthly_token_limit = 100000 WHERE plan = 'pro';

-- Plan Enterprise: Ilimitado
UPDATE users SET monthly_token_limit = 0 WHERE plan = 'enterprise';

Reset en Días Diferentes

-- Reset el día 15 (mitad de mes)
UPDATE users SET token_limit_reset_day = 15 WHERE organization_id = 'org-uuid';

Implementación de Enforce

Para hacer cumplir los límites a nivel de API, verifica antes de cada solicitud de IA:

// Ejemplo en handler de IA
pub async fn chat_with_tutor(...) -> Result<...> {
    // 1. Verificar límite de tokens
    let limit_check: TokenLimitCheck = sqlx::query_as(
        "SELECT * FROM check_token_limit($1, 1000)"  // 1000 tokens estimados
    )
    .bind(claims.sub)
    .fetch_one(&pool)
    .await?;
    
    if !limit_check.has_available_tokens {
        return Err((
            StatusCode::TOO_MANY_REQUESTS,
            format!(
                "Monthly token limit exceeded. Reset date: {}",
                limit_check.reset_date
            )
        ));
    }
    
    // 2. Proceder con solicitud de IA
    // ...
    
    // 3. Loguear uso (ya implementado)
    sqlx::query("SELECT log_ai_usage(...)").execute(&pool).await?;
    
    Ok(response)
}

Monitoreo y Alertas

Dashboard de Uso

-- Usuarios que han usado > 80% de su límite
SELECT 
    u.email,
    u.full_name,
    u.monthly_token_limit,
    SUM(au.tokens_used) as used_tokens,
    ROUND((SUM(au.tokens_used)::NUMERIC / NULLIF(u.monthly_token_limit, 0) * 100)::NUMERIC, 2) as percentage_used
FROM users u
JOIN ai_usage_logs au ON u.id = au.user_id
WHERE au.created_at >= DATE_TRUNC('month', NOW())
  AND u.monthly_token_limit > 0
GROUP BY u.id, u.email, u.full_name, u.monthly_token_limit
HAVING SUM(au.tokens_used)::NUMERIC / NULLIF(u.monthly_token_limit, 0) > 0.8
ORDER BY percentage_used DESC;

Notificación de Límite Alcanzado

Configura webhooks o emails cuando un usuario alcance el 80%, 90% y 100% de su límite.


Troubleshooting

Usuario Reporta que No Puede Usar IA

-- Verificar límite y uso
SELECT * FROM check_token_limit('user-uuid'::UUID, 0);

-- Ver historial de uso
SELECT * FROM get_user_usage_stats('user-uuid'::UUID, 1);

-- Ver logs de errores
SELECT * FROM ai_usage_logs 
WHERE user_id = 'user-uuid' 
ORDER BY created_at DESC 
LIMIT 10;

Resetear Contador de Usuario

-- Establecer límite ilimitado temporalmente
UPDATE users SET monthly_token_limit = 0 WHERE id = 'user-uuid';

-- O aumentar límite
UPDATE users SET monthly_token_limit = 200000 WHERE id = 'user-uuid';

Referencias

  • Migración: services/cms-service/migrations/20260323000000_monthly_token_limits.sql
  • Handlers: services/cms-service/src/handlers_admin.rs
  • Endpoints: services/cms-service/src/main.rs

Fecha: 2026-03-23
Versión: OpenCCB 0.2.1