Skip to main content

AI Usage (Super Admin)

Operational dashboard for tracking what every Anthropic / OpenAI call across the platform costs, who's making them, and on what feature. Super-admin-only. Use it to spot a runaway integration, compare spend by school, or investigate a single user's AI footprint.

At a glance

Who can do thisSuper admins only
Where it livesAdmin panel → AI Usage & Cost Analytics
Related featuresAI Assistant (one of the consumers) · AI Tutor (the biggest student-side consumer)

What's tracked

Every backend call to a language model writes one log row. The page rolls those up and exposes:

  • Total cost in INR (with < ₹0.01 for sub-paisa fractions)
  • Total requests (how many calls)
  • Total tokens (prompt + completion)
  • Prompt tokens alone (input cost)
  • Unique users in the period
  • Average latency in ms

Plus daily trend bars (vertical bar per day, hover for tokens/requests/cost).

Filters

Pinned at the top of the page:

  • Date range — RangePicker with quick presets Today / Last 7 Days / Last 30 Days / Last 90 Days. Default is last 30 days.
  • Schools — searchable dropdown. Empty = all schools.
  • Rolessuper_admin / admin / teacher / student / independent_student / parent.
  • Featureschat, chat_title, test_generation, answer_evaluation, curriculum_generation, module_generation, embedding, embedding_batch, rag_completion, vector_search, vector_sections, student_insights, teacher_insights, teaching_plan.

Any filter change resets pagination on the Detailed Logs tab back to page 1.

Tabbed breakdowns

Below the summary cards and trend chart sit eight tabs, each a different lens on the same filtered window:

TabRows are grouped byNotable columns
Schoolsschoolrequests, total/prompt/completion tokens, users, cost; row footer shows totals
Rolesuser roleusers, requests, tokens, cost
Classes(school, class)students, requests, tokens, cost — student usage only
Sections(school, class, section)students, requests, tokens, cost
Featuresfeaturerequests, tokens (prompt/completion split), cost, users, errors, % of total (progress bar)
Usersindividual userrole, school, class, requests, tokens, cost, last active. Click a row → user drawer
Models(provider, model)requests, tokens, cost
Detailed Logsone row per calltime, user (clickable), feature, model, tokens (prompt/completion in tooltip), cost, latency, status

Cost cells throughout are styled green-bold for emphasis. Numbers are abbreviated: 1234 → 1.2K, 2_345_678 → 2.3M.

User-detail drawer

Click any user name (in the Users tab or the Detailed Logs tab) to slide in a 640-px right drawer:

  • Identity card: name, email, role, school, class, section.
  • Three statistic cards: Total Cost, Requests, Tokens.
  • Cost by Feature mini-table for that user.
  • Daily Trend bar chart for that user.
  • Recent Activity — paginated table of the user's last calls (10 rows / page) with feature, model, tokens, cost, status badge.

The drawer respects the page's date range filter — usage shown is for the same window.

How to interpret the numbers

  • Tokens vs requests — one request can be many tokens. Spikes in tokens without a matching spike in requests usually mean longer prompts (e.g. RAG completions feeding in a chunk of syllabus context).
  • embedding feature with high token count, low cost — embeddings are cheap per token but bulk vectorization runs are token-heavy. Don't confuse this with chat.
  • chat vs chat_titlechat is the conversation; chat_title is the small follow-up call that names the conversation in the sidebar. Expect roughly 1 chat_title per new conversation.
  • student_insights / teacher_insights — periodic background AI runs that summarize a user's progress; usage scales with active students/teachers.
  • Errors column on Features — non-zero indicates upstream model failures (rate limits, content policy, network). Cross-check with Detailed Logs tab status column.
  • Cost in INR — converted from USD at fetch time; small differences across reports may reflect FX drift.

Step-by-step

1. Land on the dashboard

  • Date range defaults to last 30 days. Summary cards and trend chart populate immediately.
  • Loading state shows a centered spinner with "Loading AI usage data...".

2. Narrow the window

  • Pick a smaller range or use a preset. Every tab and the trend chart re-fetch.
  • Add a school / role / feature filter to focus.

3. Pivot via tabs

  • Start on Schools to spot the highest-cost school.
  • Click Users and sort by cost desc to find the top spenders.
  • Click into a top user → drawer → see which features they use.
  • Switch to Detailed Logs to inspect individual calls (filter by error to find failures).

4. Export / share

There is no in-page CSV export today. Screenshots of the trend chart and the totals row are the usual share artifacts.

Edge cases & things to test

  • No data in window — every tab should render an empty table cleanly; the trend chart should say "No data for this period".
  • Single day range — "Today" preset should correctly bound to start-of-day → now.
  • Cost rounding — values < ₹0.01 show as < ₹0.01; values ≥ ₹1000 show as ₹1.5K. Spot-check both edges.
  • User with no school — the Users tab should render - for school, not crash.
  • Tabs with empty groupings (e.g. Sections in a window with no student usage) — empty state, not a stuck loader.
  • Sorter persistence — sorting Tokens desc and switching tabs shouldn't bleed sort state across.
  • Detailed Logs pagination — change page size to 50, paginate; the URL doesn't carry state today, so reload resets to page 1 — expected.
  • Drawer reopen — open user A, close, open user B. Confirm the previous user's data isn't briefly visible.
  • Filter combination with no rows — feature=vector_sections + role=parent is unlikely to have data; verify graceful empty state.
  • Role filter for non-existent roles — only the seven listed roles should be selectable; verify the dropdown source.
  • Non-super-admin trying to load the page — should be blocked at the route level (super-admin-only).
  • Currency assumption — confirm is the only currency; the formatter doesn't switch on locale.