# Learnings - Credit Monitoring

## API Route Pattern (Task 2)
- **Location**: `src/app/api/usage/credit/route.js` created successfully
- **Auth Pattern**: Same as main usage route - `requireAdmin()` + `getUserIdFromJwt()` helpers
- **Imports**: `getCreditUsage` from `rateLimitRepo`, `listUsers` from `usersRepo`
- **Admin ?all=true**: Uses `listUsers()` to get all users, then `Promise.all` with `getCreditUsage` per user
- **Response shapes**: 
  - User: `{ dollarCredit: {...}, tokenCredit: {...} }`
  - Admin all: `{ users: [{ userId, dollarCredit, tokenCredit }] }`
- **Error prefix**: `[usage/credit]` for console.error logging
- **Dynamic**: `export const dynamic = 'force-dynamic'` required for cookie access

## Task 4 - Credit Summary Cards in UsageStats
- **File**: `src/shared/components/UsageStats.js`
- **Import path**: `@/app/(dashboard)/dashboard/usage/components/CreditProgressBar`
- **State**: `creditData` (null initially), `creditLoading` (true initially)
- **Fetch**: `/api/usage/credit` with `.finally(() => setCreditLoading(false))`
- **Rendering**: Conditional `{!creditLoading && creditData && (...)}` below OverviewCards
- **Layout**: `grid grid-cols-1 gap-4 sm:grid-cols-2` with `Card` wrapper (padding="md")
- **Props passed**: `label`, `used` (with `?? 0`), `limit` (with `?? 0`), `type`
- **Pattern**: Uses same Card component as rest of page for visual consistency

## Task 4: Per-User Credit Display in Table Tab
- CreditProgressBar already used in UsageStats.js with same pattern: two Cards (Dollar + Token) in a grid
- API /api/usage/credit returns {dollarCredit, tokenCredit} for single user, {users: [{userId, dollarCredit, tokenCredit}]} for admin ?all=true
- getCreditUsage returns {dollarCredit: {used, limit, remaining, percentage}, tokenCredit: {used, limit, remaining, percentage}}
- CreditDisplay component handles both admin (grid of user cards) and regular user (2-column grid) layouts
- users prop from parent maps userId -> username/email for admin view
- Credit data fetched once on mount (depends on isAdmin only), not re-fetched on filter changes
