File size: 2,255 Bytes
9d2d895
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import {
  getConvexApi,
  getConvexClient,
  waitForConvexAuthForUser,
} from './convex-client';
import { getCurrentClerkUser } from './clerk';
import {
  assertAccountStillCurrent,
  settleAccountOperation,
} from './account-operation';

export type ApiPlanLimitNoticeState = 'warning' | 'over_limit' | 'sustained_burst';
export type ApiPlanLimitDimension =
  | 'api_daily_requests'
  | 'api_minute_burst'
  | 'mcp_daily_calls'
  | 'mcp_minute_burst';
export type ApiPlanLimitCtaKind = 'checkout' | 'billing_portal' | 'contact_support' | 'none';

export interface ApiPlanLimitNotice {
  _id: string;
  userId: string;
  planKey: string;
  dimension: ApiPlanLimitDimension;
  state: ApiPlanLimitNoticeState;
  windowKey: string;
  usage: number;
  limit: number | null;
  usageRatio: number | null;
  upgradeTargetPlanKey?: string;
  ctaKind: ApiPlanLimitCtaKind;
  blockedReason?: string;
}

export async function listCurrentPlanLimitNotices(): Promise<ApiPlanLimitNotice[]> {
  const userId = getCurrentClerkUser()?.id;
  if (!userId) return [];
  const [client, api] = await Promise.all([getConvexClient(), getConvexApi()]);
  if (!client || !api) return [];
  if (!await waitForConvexAuthForUser(userId)) {
    assertAccountStillCurrent(userId, 'loading API plan-limit notices');
    throw new Error('Authentication unavailable while loading API plan-limit notices. Try again.');
  }
  return settleAccountOperation(
    userId,
    'loading API plan-limit notices',
    () => client.query((api as any).apiPlanLimitNotices.listCurrentForUser, {}),
  );
}

export async function acknowledgePlanLimitNotice(noticeId: string): Promise<void> {
  const userId = getCurrentClerkUser()?.id;
  if (!userId) throw new Error('Sign in to acknowledge API plan-limit notices.');
  const [client, api] = await Promise.all([getConvexClient(), getConvexApi()]);
  if (!client || !api) throw new Error('Convex unavailable');
  if (!await waitForConvexAuthForUser(userId)) {
    throw new Error('Account changed while acknowledging the API plan-limit notice. Try again.');
  }
  await settleAccountOperation(
    userId,
    'acknowledging the API plan-limit notice',
    () => client.mutation((api as any).apiPlanLimitNotices.acknowledgeNotice, { noticeId }),
  );
}