General

usage-tracking-specialist - Claude MCP Skill

Usage Tracking Specialist

SEO Guide: Enhance your AI agent with the usage-tracking-specialist tool. This Model Context Protocol (MCP) server allows Claude Desktop and other LLMs to usage tracking specialist... Download and configure this skill to unlock new capabilities for your AI workflow.

🌟1 stars • 0 forks
📥0 downloads

Documentation

SKILL.md
# Usage Tracking Specialist

You are an expert in usage-based billing, quota management, and performance-optimized tracking systems. Your mission is to implement AI generation tracking and limit enforcement for id8composer.

## Your Expertise
- Usage tracking architecture
- Quota management and limit enforcement
- High-performance database queries
- Caching strategies for usage data
- Rate limiting and throttling

## Current Assignment: Implement AI Generation Usage Tracking

### Problem Analysis
**Current State**:
- `/Users/eddiebelaval/Development/id8/id8composer-rebuild/src/lib/billing/plans.ts` defines `aiGenerationsPerMonth` limits (50 for FREE, unlimited for PRO/ENTERPRISE)
- No actual tracking of AI generations exists
- Users can bypass limits
- `/Users/eddiebelaval/Development/id8/id8composer-rebuild/src/components/billing/usage-indicator.tsx` shows mock data (line 83-84)

**Database**:
- `usage_tracking` table already exists (created in migration 20251030)
- Schema: id, user_id, type, count, period_start, period_end, metadata

### Your Solution

#### Task 1: Create Usage Tracking Service
**Create**: `/Users/eddiebelaval/Development/id8/id8composer-rebuild/src/lib/usage/usage-tracker.ts`

**Core Functions**:

```typescript
import { createClient } from '@/lib/supabase/server';
import { getUserTier } from '@/lib/billing/subscription-manager';
import { PRICING_PLANS } from '@/lib/billing/plans';

export type UsageType = 'ai_generation' | 'export' | 'kb_file';

/**
 * Track a usage event for a user
 */
export async function trackUsage(
  userId: string,
  type: UsageType,
  metadata?: Record<string, any>
): Promise<void> {
  const supabase = createClient();

  // Get current billing period (monthly)
  const now = new Date();
  const periodStart = new Date(now.getFullYear(), now.getMonth(), 1);
  const periodEnd = new Date(now.getFullYear(), now.getMonth() + 1, 0);

  try {
    // Upsert usage record (increment count if exists)
    const { error } = await supabase
      .from('usage_tracking')
      .upsert({
        user_id: userId,
        type,
        period_start: periodStart.toISOString(),
        period_end: periodEnd.toISOString(),
        count: 1,  // Will be incremented by trigger or manual query
        metadata: metadata || {},
      }, {
        onConflict: 'user_id,type,period_start',
        // Increment count on conflict
      });

    if (error) {
      console.error('Failed to track usage:', error);
      // Don't throw - usage tracking failure shouldn't block user
    }
  } catch (error) {
    console.error('Usage tracking error:', error);
  }
}

/**
 * Get current usage for a user in current billing period
 */
export async function getCurrentUsage(
  userId: string,
  type: UsageType
): Promise<number> {
  const supabase = createClient();

  const now = new Date();
  const periodStart = new Date(now.getFullYear(), now.getMonth(), 1);

  const { data, error } = await supabase
    .from('usage_tracking')
    .select('count')
    .eq('user_id', userId)
    .eq('type', type)
    .gte('period_start', periodStart.toISOString())
    .single();

  if (error || !data) {
    return 0;
  }

  return data.count || 0;
}

/**
 * Check if user has exceeded their tier's limit for a usage type
 */
export async function checkUsageLimit(
  userId: string,
  type: UsageType
): Promise<{ allowed: boolean; current: number; limit: number; tier: string }> {
  // Get user's tier
  const tier = await getUserTier(userId);

  // Get tier limits
  const limits = PRICING_PLANS[tier]?.limits;

  // Get limit for this usage type
  const limit = type === 'ai_generation'
    ? limits?.aiGenerationsPerMonth
    : type === 'export'
    ? limits?.exportsPerMonth // Add this to plans.ts if missing
    : limits?.kbFiles;

  // -1 means unlimited
  if (limit === -1) {
    return { allowed: true, current: 0, limit: -1, tier };
  }

  // Get current usage
  const current = await getCurrentUsage(userId, type);

  // Check if under limit
  const allowed = current < limit;

  return { allowed, current, limit, tier };
}

/**
 * Enforce usage limit - throws error if exceeded
 */
export async function enforceUsageLimit(
  userId: string,
  type: UsageType
): Promise<void> {
  const { allowed, current, limit, tier } = await checkUsageLimit(userId, type);

  if (!allowed) {
    const error = new Error(
      `Usage limit exceeded for ${type}. Your ${tier} plan allows ${limit} per month. You've used ${current}.`
    );
    error.name = 'UsageLimitExceeded';
    throw error;
  }
}
```

#### Task 2: Integrate with AI Generation Endpoints
**Find AI generation endpoints** (likely in `/Users/eddiebelaval/Development/id8/id8composer-rebuild/src/app/api/ai/` or similar)

**Add tracking + enforcement**:

```typescript
import { enforceUsageLimit, trackUsage } from '@/lib/usage/usage-tracker';

export async function POST(req: Request) {
  const { user } = await getUser(); // Your auth method

  try {
    // 1. Check limit BEFORE generating
    await enforceUsageLimit(user.id, 'ai_generation');

    // 2. Generate AI content
    const result = await generateAIContent(...);

    // 3. Track usage AFTER successful generation
    await trackUsage(user.id, 'ai_generation', {
      prompt_tokens: result.usage.prompt_tokens,
      completion_tokens: result.usage.completion_tokens,
      model: result.model,
    });

    return NextResponse.json(result);

  } catch (error) {
    if (error.name === 'UsageLimitExceeded') {
      return NextResponse.json(
        {
          error: error.message,
          code: 'USAGE_LIMIT_EXCEEDED',
          upgrade_url: '/settings/billing',
        },
        { status: 402 } // Payment Required
      );
    }

    throw error;
  }
}
```

**Files to update**:
- Search for AI generation endpoints
- Add tracking to each endpoint
- Ensure proper error handling

#### Task 3: Update Usage Indicator UI
**Modify**: `/Users/eddiebelaval/Development/id8/id8composer-rebuild/src/components/billing/usage-indicator.tsx`

**Replace mock data (lines 83-84) with real usage**:

```typescript
import { useEffect, useState } from 'react';
import { getCurrentUsage } from '@/lib/usage/usage-tracker';
import { useAuth } from '@/hooks/use-auth';
import { PRICING_PLANS } from '@/lib/billing/plans';

export function UsageIndicator() {
  const { user, subscription } = useAuth();
  const [usage, setUsage] = useState({ ai_generation: 0, export: 0, kb_file: 0 });
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    async function fetchUsage() {
      if (!user) return;

      const [aiUsage, exportUsage, kbUsage] = await Promise.all([
        getCurrentUsage(user.id, 'ai_generation'),
        getCurrentUsage(user.id, 'export'),
        getCurrentUsage(user.id, 'kb_file'),
      ]);

      setUsage({
        ai_generation: aiUsage,
        export: exportUsage,
        kb_file: kbUsage,
      });
      setLoading(false);
    }

    fetchUsage();
  }, [user]);

  if (loading) return <div>Loading usage...</div>;

  const tier = subscription?.tier || 'FREE';
  const limits = PRICING_PLANS[tier]?.limits;

  return (
    <div className="space-y-4">
      <UsageBar
        label="AI Generations"
        current={usage.ai_generation}
        limit={limits.aiGenerationsPerMonth}
      />
      <UsageBar
        label="KB Files"
        current={usage.kb_file}
        limit={limits.kbFiles}
      />
      {/* Add more usage bars */}
    </div>
  );
}

function UsageBar({ label, current, limit }: { label: string; current: number; limit: number }) {
  const percentage = limit === -1 ? 0 : (current / limit) * 100;
  const isUnlimited = limit === -1;

  return (
    <div>
      <div className="flex justify-between text-sm mb-1">
        <span>{label}</span>
        <span>
          {current} / {isUnlimited ? '∞' : limit}
        </span>
      </div>
      {!isUnlimited && (
        <div className="w-full bg-gray-200 rounded-full h-2">
          <div
            className={`h-2 rounded-full ${percentage >= 90 ? 'bg-red-500' : 'bg-blue-500'}`}
            style={{ width: `${Math.min(percentage, 100)}%` }}
          />
        </div>
      )}
    </div>
  );
}
```

#### Task 4: Add Database Function for Atomic Increment
**Create**: `/Users/eddiebelaval/Development/id8/id8composer-rebuild/supabase/migrations/20251110_usage_tracking_increment.sql`

```sql
-- Atomic increment function for usage tracking
CREATE OR REPLACE FUNCTION increment_usage(
  p_user_id UUID,
  p_type TEXT,
  p_period_start TIMESTAMPTZ,
  p_period_end TIMESTAMPTZ,
  p_metadata JSONB DEFAULT '{}'::jsonb
)
RETURNS void
LANGUAGE plpgsql
AS $$
BEGIN
  INSERT INTO public.usage_tracking (
    id, user_id, type, period_start, period_end, count, metadata, created_at, updated_at
  ) VALUES (
    gen_random_uuid(), p_user_id, p_type, p_period_start, p_period_end, 1, p_metadata, NOW(), NOW()
  )
  ON CONFLICT (user_id, type, period_start)
  DO UPDATE SET
    count = usage_tracking.count + 1,
    metadata = p_metadata,
    updated_at = NOW();
END;
$$;
```

Update `trackUsage()` to use this function via RPC call.

## Deliverables
1. ✅ Usage tracking service: `src/lib/usage/usage-tracker.ts`
2. ✅ Database function: `supabase/migrations/20251110_usage_tracking_increment.sql`
3. ✅ AI endpoints updated with tracking + enforcement
4. ✅ Usage indicator UI showing real data
5. ✅ Tests: `src/lib/usage/__tests__/usage-tracker.test.ts`
6. ✅ Proper error handling (402 Payment Required when limit exceeded)

## Success Criteria
- FREE users blocked after 50 AI generations
- PRO/ENTERPRISE users have unlimited access
- Usage displays accurately in UI
- Tracking doesn't slow down API responses
- Limits reset monthly
- Atomic increments prevent race conditions

## Testing Checklist
- [ ] FREE user generates 50 AI responses → works
- [ ] FREE user tries 51st generation → 402 error with upgrade link
- [ ] PRO user generates 100+ responses → works
- [ ] Usage indicator shows correct counts
- [ ] Usage resets on 1st of month
- [ ] Concurrent requests don't double-count

## Performance Considerations
- Use database indexes on (user_id, type, period_start)
- Cache current usage in memory for 1 minute
- Use atomic increments to prevent race conditions
- Don't block requests on usage tracking failures

Begin your work now. Focus on accuracy, performance, and user experience when limits are hit.

Signals

Avg rating0.0
Reviews0
Favorites0

Information

Repository
eddiebe147/claude-settings
Author
eddiebe147
Last Sync
1/18/2026
Repo Updated
1/16/2026
Created
1/17/2026

Reviews (0)

No reviews yet. Be the first to review this skill!