Add API cost tracking to admin dashboard

Track estimated Anthropic API costs per request across all Claude API
call sites (recommender, analyze, artist-dive, generate-playlist, crate,
rabbit-hole, playlist-fix, timeline, compatibility). Log token usage and
estimated cost to the app logger. Aggregate costs in admin stats endpoint
and display total/today costs and token usage in the admin dashboard.
This commit is contained in:
root
2026-03-31 20:51:51 -05:00
parent 0ee8f9a144
commit f2b8dadbf8
7 changed files with 104 additions and 3 deletions

View File

@@ -1,5 +1,5 @@
import { useEffect, useState } from 'react'
import { Shield, Users, ListMusic, Sparkles, Heart, ThumbsDown, ScrollText, RefreshCw } from 'lucide-react'
import { Shield, Users, ListMusic, Sparkles, Heart, ThumbsDown, ScrollText, RefreshCw, DollarSign } from 'lucide-react'
import { useAuth } from '../lib/auth'
import { getAdminStats, getAdminLogs, type AdminStats, type LogEntry } from '../lib/api'
@@ -124,8 +124,8 @@ export default function Admin() {
</div>
</div>
{/* Middle row - 2 stat cards */}
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 mb-8">
{/* Middle row - 3 stat cards */}
<div className="grid grid-cols-1 sm:grid-cols-3 gap-4 mb-8">
<div className="bg-white rounded-2xl p-6 border border-purple-100">
<div className="flex items-center gap-3 mb-4">
<div className="w-10 h-10 rounded-xl bg-purple-100 flex items-center justify-center">
@@ -145,6 +145,20 @@ export default function Admin() {
</div>
<p className="text-4xl font-bold text-charcoal">{stats.recommendations.disliked}</p>
</div>
<div className="bg-white rounded-2xl p-6 border border-purple-100">
<div className="flex items-center gap-3 mb-4">
<div className="w-10 h-10 rounded-xl bg-purple-100 flex items-center justify-center">
<DollarSign className="w-5 h-5 text-purple" />
</div>
<h3 className="text-sm font-medium text-charcoal-muted">API Costs</h3>
</div>
<p className="text-4xl font-bold text-charcoal">${stats.api_costs.total_estimated.toFixed(4)}</p>
<div className="flex flex-wrap gap-x-4 gap-y-1 text-sm text-charcoal-muted mt-2">
<span><span className="font-semibold text-charcoal">${stats.api_costs.today_estimated.toFixed(4)}</span> today</span>
<span><span className="font-semibold text-charcoal">{(stats.api_costs.total_input_tokens + stats.api_costs.total_output_tokens).toLocaleString()}</span> tokens</span>
</div>
</div>
</div>
{/* User breakdown table */}