fix(quotas): unifier le décompte IA (BYOK, rollback) et combler les fuites
All checks were successful
CI / Lint, Unit Tests & Build (push) Successful in 6m55s
CI / Deploy production (on server) (push) Successful in 36s

Centralise la réserve via ai-quota, corrige admin unavailable (-1), brancher les routes sans quota et le host-pays brainstorm, avec usage-meter élargi, noms de clusters, MCP et ajustements dashboard/insights.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Antigravity
2026-07-15 20:42:25 +00:00
parent 30da592ba2
commit 4fe31ebc99
75 changed files with 2949 additions and 785 deletions

View File

@@ -3,6 +3,9 @@ import { VALID_FEATURES } from './quota-utils';
export type SubscriptionTier = 'BASIC' | 'PRO' | 'BUSINESS' | 'ENTERPRISE';
/** Stored in PlanEntitlement.limitValue — feature explicitly disabled via admin. */
export const ENTITLEMENT_UNAVAILABLE = -1;
/** Hardcoded defaults — used when DB is empty or unavailable. */
export const FALLBACK_TIER_LIMITS: Record<
SubscriptionTier,
@@ -98,18 +101,24 @@ function buildLimitMapFromRows(
for (const row of rows) {
map[row.tier][row.feature] =
row.limitValue === null ? Infinity : row.limitValue;
row.limitValue === null
? Infinity
: row.limitValue === ENTITLEMENT_UNAVAILABLE
? ENTITLEMENT_UNAVAILABLE
: row.limitValue;
}
return map;
}
/** Merge DB entitlements with FALLBACK for features added after admin seeding. */
/** Merge DB entitlements with FALLBACK for features added after admin seeding.
* Does NOT override ENTITLEMENT_UNAVAILABLE (-1) or explicit limits. */
function mergeWithFallback(map: LimitMap): LimitMap {
const fallback = fallbackToLimitMap();
for (const tier of Object.keys(fallback) as SubscriptionTier[]) {
for (const [feature, limit] of Object.entries(fallback[tier])) {
if (map[tier][feature] === undefined) {
const current = map[tier][feature];
if (current === undefined) {
map[tier][feature] = limit;
}
}
@@ -157,7 +166,7 @@ export async function getLimitAsync(
): Promise<number | undefined> {
const map = await loadLimitMap();
const limit = map[tier]?.[feature];
if (limit === undefined) return undefined;
if (limit === undefined || limit === ENTITLEMENT_UNAVAILABLE) return undefined;
if (limit === Infinity) return Infinity;
return limit;
}
@@ -184,9 +193,11 @@ export async function getAllEntitlementsForAdmin(): Promise<
feature: r.feature,
limitValue: r.limitValue,
mode:
r.limitValue === null
? ('unlimited' as const)
: ('limited' as const),
r.limitValue === ENTITLEMENT_UNAVAILABLE
? ('unavailable' as const)
: r.limitValue === null
? ('unlimited' as const)
: ('limited' as const),
}));
}