feat(admin): Add token usage and remaining balance management options
Implements both Option A and B for admin token management: - Option A (mode='remaining'): Set tokens remaining to use (calculates usage from limit) - Option B (mode='usage'): Directly set tokens consumed - Original mode='limit': Still sets token limit override The admin UI now presents 3 modes via prompt dialog, and the API endpoint handles each mode appropriately by updating the token usage bucket.
This commit is contained in:
@@ -16312,11 +16312,15 @@ async function handleAdminAccountTokensPost(req, res) {
|
||||
const body = await parseJsonBody(req);
|
||||
const userId = body.userId;
|
||||
const tokenAmount = body.tokens;
|
||||
const mode = body.mode || 'limit'; // 'limit', 'usage', or 'remaining'
|
||||
|
||||
if (!userId) return sendJson(res, 400, { error: 'User ID is required' });
|
||||
if (typeof tokenAmount !== 'number' || tokenAmount < 0 || !Number.isFinite(tokenAmount)) {
|
||||
return sendJson(res, 400, { error: 'Invalid token amount. Must be a non-negative number.' });
|
||||
}
|
||||
if (!['limit', 'usage', 'remaining'].includes(mode)) {
|
||||
return sendJson(res, 400, { error: 'Invalid mode. Must be "limit", "usage", or "remaining".' });
|
||||
}
|
||||
|
||||
const user = findUserById(userId);
|
||||
if (!user) return sendJson(res, 404, { error: 'User not found' });
|
||||
@@ -16324,16 +16328,33 @@ async function handleAdminAccountTokensPost(req, res) {
|
||||
const bucket = ensureTokenUsageBucket(userId);
|
||||
if (!bucket) return sendJson(res, 500, { error: 'Failed to access token usage data' });
|
||||
|
||||
// Set the token override
|
||||
bucket.tokenOverride = Math.floor(tokenAmount);
|
||||
let result = {};
|
||||
|
||||
if (mode === 'limit') {
|
||||
// Set the token override (original behavior)
|
||||
bucket.tokenOverride = tokenAmount === 0 ? null : Math.floor(tokenAmount);
|
||||
result = { mode: 'limit', tokenOverride: bucket.tokenOverride };
|
||||
log('Admin set user token limit override', { userId, tokens: bucket.tokenOverride, admin: ADMIN_USER });
|
||||
} else if (mode === 'usage') {
|
||||
// Set the usage directly (Option B)
|
||||
bucket.usage = Math.floor(tokenAmount);
|
||||
result = { mode: 'usage', usage: bucket.usage };
|
||||
log('Admin set user token usage', { userId, usage: bucket.usage, admin: ADMIN_USER });
|
||||
} else if (mode === 'remaining') {
|
||||
// Set remaining tokens (Option A) - calculate usage from limit
|
||||
const limit = getPlanTokenLimits(user.plan, userId);
|
||||
const newUsage = Math.max(0, limit - Math.floor(tokenAmount));
|
||||
bucket.usage = newUsage;
|
||||
result = { mode: 'remaining', remaining: Math.floor(tokenAmount), usage: newUsage, limit };
|
||||
log('Admin set user token remaining', { userId, remaining: tokenAmount, usage: newUsage, limit, admin: ADMIN_USER });
|
||||
}
|
||||
|
||||
await persistTokenUsage();
|
||||
|
||||
const accountData = await serializeAccount(user);
|
||||
log('Admin set user token override', { userId, tokens: bucket.tokenOverride, admin: ADMIN_USER });
|
||||
sendJson(res, 200, { ok: true, account: accountData, tokenOverride: bucket.tokenOverride });
|
||||
sendJson(res, 200, { ok: true, account: accountData, ...result });
|
||||
} catch (error) {
|
||||
sendJson(res, 400, { error: error.message || 'Unable to update token limit' });
|
||||
sendJson(res, 400, { error: error.message || 'Unable to update token settings' });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user