@burdenoff/microfe-billing 2026.518.3 → 2026.519.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,38 @@
1
1
  import { GetUsageRecordsQuery, GetUsageRecordsQueryVariables } from '../../../../generated/wspace-operations';
2
2
  import { AnalyticsPeriod, QuotaStatus, UsageDashboard } from '../../../shared/types';
3
3
 
4
+ export interface WorkspaceQuotaStatusItem {
5
+ workspaceId: string;
6
+ quotaName: string;
7
+ productId: string;
8
+ currentValue: number;
9
+ limit: number | null;
10
+ noLimit: boolean;
11
+ scrapedAt: string;
12
+ }
13
+ export interface WorkspaceQuotaSnapshotItem {
14
+ id: string;
15
+ workspaceId: string;
16
+ quotaName: string;
17
+ productId: string;
18
+ value: number;
19
+ limit: number | null;
20
+ noLimit: boolean;
21
+ snapshotAt: string;
22
+ }
23
+ interface UseWorkspaceQuotaStatusesResult {
24
+ statuses: WorkspaceQuotaStatusItem[];
25
+ statusMap: Map<string, WorkspaceQuotaStatusItem>;
26
+ isLoading: boolean;
27
+ error: Error | null;
28
+ }
29
+ export declare function useWorkspaceQuotaStatuses(workspaceId?: string): UseWorkspaceQuotaStatusesResult;
30
+ interface UseWorkspaceQuotaHistoryResult {
31
+ snapshots: WorkspaceQuotaSnapshotItem[];
32
+ isLoading: boolean;
33
+ error: Error | null;
34
+ }
35
+ export declare function useWorkspaceQuotaHistory(workspaceId?: string, quotaName?: string, limit?: number): UseWorkspaceQuotaHistoryResult;
4
36
  interface UseUsageDashboardParams {
5
37
  billingAccountId?: string;
6
38
  period?: AnalyticsPeriod;
@@ -183,6 +215,7 @@ export declare function useQuotaAnalytics(quotaAssignmentId: string | undefined,
183
215
  */
184
216
  interface UseEnhancedUsagePageParams {
185
217
  billingAccountId: string | undefined;
218
+ workspaceId?: string;
186
219
  period?: AnalyticsPeriod;
187
220
  searchQuery?: string;
188
221
  viewMode?: ViewMode;
@@ -201,6 +234,6 @@ interface UseEnhancedUsagePageResult {
201
234
  isLoadingMorePast: boolean;
202
235
  pastSubscriptionsCount: number;
203
236
  }
204
- export declare function useEnhancedUsagePage({ billingAccountId, period, searchQuery, viewMode, }: UseEnhancedUsagePageParams): UseEnhancedUsagePageResult;
237
+ export declare function useEnhancedUsagePage({ billingAccountId, workspaceId, period, searchQuery, viewMode, }: UseEnhancedUsagePageParams): UseEnhancedUsagePageResult;
205
238
  export {};
206
239
  //# sourceMappingURL=useUsage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useUsage.d.ts","sourceRoot":"","sources":["../../../../../src/billing/modules/usage/hooks/useUsage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useUsage.d.ts","sourceRoot":"","sources":["../../../../../src/billing/modules/usage/hooks/useUsage.ts"],"names":[],"mappings":"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"}
@@ -2,9 +2,72 @@ import { AnalyticsPeriod as e, QuotaStatus as t } from "../../../shared/types/gr
2
2
  import { useGetBillingAccountQuotasSummaryForUsageQuery as n, useGetBillingAccountsForUsageQuery as r, useGetPastSubscriptionsWithQuotasQuery as i, useGetSubscriptionsWithQuotasQuery as a, useGetUsageDashboardQuery as o } from "../../../../generated/global-operations.js";
3
3
  import { useGetUsageRecordsQuery as s } from "../../../../generated/wspace-operations.js";
4
4
  import { useCallback as c, useEffect as l, useMemo as u, useState as d } from "react";
5
- import { useGatewayClient as f } from "@burdenoff/fe-libs/shared/graphql";
5
+ import { gql as f, useGatewayClient as p, useQuery as m } from "@burdenoff/fe-libs/shared/graphql";
6
6
  //#region src/billing/modules/usage/hooks/useUsage.ts
7
- function p({ billingAccountId: t, period: n = e.LAST_30_DAYS }) {
7
+ var h = f`
8
+ query WorkspaceQuotaStatuses($workspaceId: ID!) {
9
+ workspaceQuotaStatuses(workspaceId: $workspaceId) {
10
+ workspaceId
11
+ quotaName
12
+ productId
13
+ currentValue
14
+ limit
15
+ noLimit
16
+ scrapedAt
17
+ }
18
+ }
19
+ `, g = f`
20
+ query WorkspaceQuotaHistory($workspaceId: ID!, $quotaName: String!, $limit: Int) {
21
+ workspaceQuotaHistory(workspaceId: $workspaceId, quotaName: $quotaName, limit: $limit) {
22
+ id
23
+ workspaceId
24
+ quotaName
25
+ productId
26
+ value
27
+ limit
28
+ noLimit
29
+ snapshotAt
30
+ }
31
+ }
32
+ `;
33
+ function _(e) {
34
+ let { data: t, loading: n, error: r } = m(h, {
35
+ client: p("workspace"),
36
+ variables: { workspaceId: e },
37
+ skip: !e,
38
+ fetchPolicy: "cache-and-network"
39
+ }), { statuses: i, statusMap: a } = u(() => {
40
+ let e = t?.workspaceQuotaStatuses ?? [];
41
+ return {
42
+ statuses: e,
43
+ statusMap: new Map(e.map((e) => [e.quotaName, e]))
44
+ };
45
+ }, [t]);
46
+ return {
47
+ statuses: i,
48
+ statusMap: a,
49
+ isLoading: n,
50
+ error: r ?? null
51
+ };
52
+ }
53
+ function v(e, t, n = 48) {
54
+ let { data: r, loading: i, error: a } = m(g, {
55
+ client: p("workspace"),
56
+ variables: {
57
+ workspaceId: e,
58
+ quotaName: t,
59
+ limit: n
60
+ },
61
+ skip: !e || !t,
62
+ fetchPolicy: "cache-and-network"
63
+ });
64
+ return {
65
+ snapshots: r?.workspaceQuotaHistory ?? [],
66
+ isLoading: i,
67
+ error: a ?? null
68
+ };
69
+ }
70
+ function y({ billingAccountId: t, period: n = e.LAST_30_DAYS }) {
8
71
  let { data: r, loading: i, error: a, refetch: s } = o({
9
72
  variables: {
10
73
  billingAccountId: t,
@@ -20,10 +83,25 @@ function p({ billingAccountId: t, period: n = e.LAST_30_DAYS }) {
20
83
  refetch: s
21
84
  };
22
85
  }
23
- function m(e, n) {
86
+ function b(e, n) {
24
87
  return n <= 0 ? t.EXHAUSTED : e >= 90 ? t.CRITICAL : e >= 75 ? t.WARNING : t.HEALTHY;
25
88
  }
26
- function h(e) {
89
+ function x(e, t) {
90
+ return t.size === 0 ? e : e.map((e) => {
91
+ let n = t.get(e.name);
92
+ if (!n) return e;
93
+ let r = n.currentValue, i = n.noLimit ? 0 : n.limit ?? e.totalLimit, a = i > 0 ? r / i * 100 : 0, o = Math.max(0, i - r);
94
+ return {
95
+ ...e,
96
+ totalUsed: r,
97
+ totalLimit: i,
98
+ noLimit: n.noLimit,
99
+ usagePercentage: a,
100
+ status: b(a, o)
101
+ };
102
+ });
103
+ }
104
+ function S(e) {
27
105
  let t = /* @__PURE__ */ new Map();
28
106
  for (let n of e) {
29
107
  let e = t.get(n.name) || [];
@@ -31,7 +109,7 @@ function h(e) {
31
109
  }
32
110
  let n = [];
33
111
  for (let [e, r] of t) {
34
- let t = r.reduce((e, t) => e + (t.limit || 0), 0), i = r.reduce((e, t) => e + (t.used || 0), 0), a = r.reduce((e, t) => e + (t.limitLeft || 0), 0), o = t === 0 && r.every((e) => e.noLimit || (e.limit || 0) === 0), s = o || t === 0 ? 0 : i / t * 100, c = m(s, a), l = r[0]?.reusable || !1, u = r[0]?.unit || "", d = r[0]?.context, f = typeof d?.displayName == "string" ? d.displayName : void 0, p = typeof d?.description == "string" ? d.description : void 0;
112
+ let t = r.reduce((e, t) => e + (t.limit || 0), 0), i = r.reduce((e, t) => e + (t.used || 0), 0), a = r.reduce((e, t) => e + (t.limitLeft || 0), 0), o = t === 0 && r.every((e) => e.noLimit || (e.limit || 0) === 0), s = o || t === 0 ? 0 : i / t * 100, c = b(s, a), l = r[0]?.reusable || !1, u = r[0]?.unit || "", d = r[0]?.context, f = typeof d?.displayName == "string" ? d.displayName : void 0, p = typeof d?.description == "string" ? d.description : void 0;
35
113
  n.push({
36
114
  name: e,
37
115
  displayName: f,
@@ -59,7 +137,7 @@ function h(e) {
59
137
  return n === 0 ? t.usagePercentage - e.usagePercentage : n;
60
138
  });
61
139
  }
62
- function g() {
140
+ function C() {
63
141
  let { data: e, loading: t, error: n } = r({ fetchPolicy: "cache-and-network" });
64
142
  return {
65
143
  billingAccounts: e?.getBillingAccountsByOrg ?? [],
@@ -67,7 +145,7 @@ function g() {
67
145
  error: n ?? null
68
146
  };
69
147
  }
70
- function _(e, t) {
148
+ function w(e, t) {
71
149
  let { data: r, loading: i, error: a, refetch: o } = n({
72
150
  variables: {
73
151
  billingAccountId: e,
@@ -80,32 +158,32 @@ function _(e, t) {
80
158
  pooledQuotas: u(() => {
81
159
  if (!r?.getBillingAccountQuotasSummary) return [];
82
160
  let e = r.getBillingAccountQuotasSummary;
83
- return h(e.pooledQuotas || []);
161
+ return S(e.pooledQuotas || []);
84
162
  }, [r]),
85
163
  isLoading: i,
86
164
  error: a ?? null,
87
165
  refetch: o
88
166
  };
89
167
  }
90
- var v = 10;
91
- function y(e, t = {}) {
92
- let { searchQuery: n, viewMode: r = "active" } = t, o = r === "active" || r === "all", s = r === "past" || r === "all", { data: f, loading: p, error: m, refetch: g } = a({
168
+ var T = 10;
169
+ function E(e, t = {}) {
170
+ let { searchQuery: n, viewMode: r = "active" } = t, o = r === "active" || r === "all", s = r === "past" || r === "all", { data: f, loading: p, error: m, refetch: h } = a({
93
171
  variables: {
94
172
  billingAccountId: e,
95
173
  searchQuery: n || null
96
174
  },
97
175
  skip: !e || !o,
98
176
  fetchPolicy: "cache-and-network"
99
- }), { data: _, loading: y, refetch: b, fetchMore: x } = i({
177
+ }), { data: g, loading: _, refetch: v, fetchMore: y } = i({
100
178
  variables: {
101
179
  billingAccountId: e,
102
180
  searchQuery: n || null,
103
181
  page: 1,
104
- pageSize: v
182
+ pageSize: T
105
183
  },
106
184
  skip: !e || !s,
107
185
  fetchPolicy: "cache-and-network"
108
- }), [S, C] = d(!1), [w, T] = d(1), E = c((e) => {
186
+ }), [b, x] = d(!1), [C, w] = d(1), E = c((e) => {
109
187
  let t = (e.quotas || []).map((t) => {
110
188
  let n = t.limits?.value || 0, r = t.currentUsageSum || 0, i = Math.max(0, n - r), a = n > 0 ? r / n * 100 : 0, o = t.limits?.unit || "";
111
189
  return {
@@ -130,13 +208,13 @@ function y(e, t = {}) {
130
208
  id: e.id,
131
209
  status: e.status,
132
210
  createdAt: e.createdAt,
133
- aggregatedQuotas: h(t)
211
+ aggregatedQuotas: S(t)
134
212
  };
135
- }, []), D = u(() => f?.getSubscriptionUsageOverview ? f.getSubscriptionUsageOverview.map(E) : [], [f, E]), O = u(() => _?.getSubscriptionUsageOverview ? (_.getSubscriptionUsageOverview.subscriptions || _.getSubscriptionUsageOverview).map(E) : [], [_, E]), k = u(() => {
136
- let e = _?.getSubscriptionUsageOverview;
213
+ }, []), D = u(() => f?.getSubscriptionUsageOverview ? f.getSubscriptionUsageOverview.map(E) : [], [f, E]), O = u(() => g?.getSubscriptionUsageOverview ? (g.getSubscriptionUsageOverview.subscriptions || g.getSubscriptionUsageOverview).map(E) : [], [g, E]), k = u(() => {
214
+ let e = g?.getSubscriptionUsageOverview;
137
215
  return e ? e.totalCount === void 0 ? {
138
216
  totalCount: O.length,
139
- hasMore: O.length >= v * w
217
+ hasMore: O.length >= T * C
140
218
  } : {
141
219
  totalCount: e.totalCount,
142
220
  hasMore: O.length < e.totalCount
@@ -145,61 +223,61 @@ function y(e, t = {}) {
145
223
  hasMore: !1
146
224
  };
147
225
  }, [
148
- _,
226
+ g,
149
227
  O.length,
150
- w
228
+ C
151
229
  ]);
152
230
  l(() => {
153
- T(1);
231
+ w(1);
154
232
  }, [n, r]);
155
233
  let A = c(async () => {
156
- if (!x || S || !k.hasMore) return;
157
- C(!0);
158
- let e = w + 1;
234
+ if (!y || b || !k.hasMore) return;
235
+ x(!0);
236
+ let e = C + 1;
159
237
  try {
160
- await x({
238
+ await y({
161
239
  variables: {
162
240
  page: e,
163
- pageSize: v
241
+ pageSize: T
164
242
  },
165
243
  updateQuery: (e, { fetchMoreResult: t }) => {
166
244
  if (!t) return e;
167
245
  let n = e?.getSubscriptionUsageOverview ?? [], r = t?.getSubscriptionUsageOverview ?? [];
168
246
  return { getSubscriptionUsageOverview: [...n, ...r] };
169
247
  }
170
- }), T(e);
248
+ }), w(e);
171
249
  } catch (e) {
172
250
  console.error("Failed to load more past subscriptions:", e);
173
251
  } finally {
174
- C(!1);
252
+ x(!1);
175
253
  }
176
254
  }, [
177
- x,
178
- S,
255
+ y,
256
+ b,
179
257
  k.hasMore,
180
- w
258
+ C
181
259
  ]), j = c(() => {
182
- T(1), o && g(), s && b();
260
+ w(1), o && h(), s && v();
183
261
  }, [
184
262
  o,
185
263
  s,
186
- g,
187
- b
264
+ h,
265
+ v
188
266
  ]);
189
267
  return {
190
268
  activeSubscriptions: D,
191
269
  pastSubscriptions: O,
192
270
  isLoading: o ? p : !1,
193
- isPastSubscriptionsLoading: s ? y : !1,
271
+ isPastSubscriptionsLoading: s ? _ : !1,
194
272
  error: m ?? null,
195
273
  refetch: j,
196
274
  loadMorePastSubscriptions: A,
197
275
  hasMorePastSubscriptions: k.hasMore,
198
- isLoadingMorePast: S,
276
+ isLoadingMorePast: b,
199
277
  pastSubscriptionsCount: k.totalCount
200
278
  };
201
279
  }
202
- function b(e, t, n, r) {
280
+ function D(e, t, n, r) {
203
281
  return {
204
282
  filters: {
205
283
  quotaAssignmentId: e,
@@ -211,7 +289,7 @@ function b(e, t, n, r) {
211
289
  }
212
290
  };
213
291
  }
214
- function x(e) {
292
+ function O(e) {
215
293
  return {
216
294
  id: e.id,
217
295
  amount: e.amount,
@@ -223,15 +301,15 @@ function x(e) {
223
301
  lastUpdated: e.createdAt
224
302
  };
225
303
  }
226
- function S(e, t = 20, n = null, r) {
304
+ function k(e, t = 20, n = null, r) {
227
305
  let { data: i, loading: a, error: o, refetch: c } = s({
228
- client: f("workspace"),
229
- variables: b(e, t, n, r),
306
+ client: p("workspace"),
307
+ variables: D(e, t, n, r),
230
308
  skip: !e || !r,
231
309
  fetchPolicy: "cache-and-network"
232
310
  });
233
311
  return {
234
- usages: (i?.getUsageRecords?.items ?? []).map(x),
312
+ usages: (i?.getUsageRecords?.items ?? []).map(O),
235
313
  hasNextPage: i?.getUsageRecords?.hasNextPage ?? !1,
236
314
  nextCursor: i?.getUsageRecords?.nextCursor ?? null,
237
315
  isLoading: a,
@@ -239,36 +317,42 @@ function S(e, t = 20, n = null, r) {
239
317
  refetch: c
240
318
  };
241
319
  }
242
- function C({ billingAccountId: t, period: n = e.LAST_30_DAYS, searchQuery: r, viewMode: i = "active" }) {
243
- let a = p({
320
+ function A({ billingAccountId: t, workspaceId: n, period: r = e.LAST_30_DAYS, searchQuery: i, viewMode: a = "active" }) {
321
+ let o = y({
244
322
  billingAccountId: t,
245
- period: n
246
- }), o = _(t), s = y(t, {
247
- searchQuery: r,
248
- viewMode: i
249
- }), l = c(() => {
250
- a.refetch(), o.refetch(), s.refetch();
323
+ period: r
324
+ }), s = w(t), { statusMap: l } = _(n), d = E(t, {
325
+ searchQuery: i,
326
+ viewMode: a
327
+ }), f = u(() => x(s.pooledQuotas, l), [s.pooledQuotas, l]), p = u(() => d.activeSubscriptions.map((e) => ({
328
+ ...e,
329
+ aggregatedQuotas: x(e.aggregatedQuotas, l)
330
+ })), [d.activeSubscriptions, l]), m = u(() => d.pastSubscriptions.map((e) => ({
331
+ ...e,
332
+ aggregatedQuotas: x(e.aggregatedQuotas, l)
333
+ })), [d.pastSubscriptions, l]), h = c(() => {
334
+ o.refetch(), s.refetch(), d.refetch();
251
335
  }, [
252
- a,
253
336
  o,
254
- s
337
+ s,
338
+ d
255
339
  ]);
256
340
  return {
257
- dashboard: a.dashboard,
258
- pooledQuotas: o.pooledQuotas,
259
- activeSubscriptions: s.activeSubscriptions,
260
- pastSubscriptions: s.pastSubscriptions,
261
- isLoading: a.isLoading || o.isLoading || s.isLoading,
262
- isPastSubscriptionsLoading: s.isPastSubscriptionsLoading,
263
- error: a.error || o.error || s.error,
264
- refetch: l,
265
- loadMorePastSubscriptions: s.loadMorePastSubscriptions,
266
- hasMorePastSubscriptions: s.hasMorePastSubscriptions,
267
- isLoadingMorePast: s.isLoadingMorePast,
268
- pastSubscriptionsCount: s.pastSubscriptionsCount
341
+ dashboard: o.dashboard,
342
+ pooledQuotas: f,
343
+ activeSubscriptions: p,
344
+ pastSubscriptions: m,
345
+ isLoading: o.isLoading || s.isLoading || d.isLoading,
346
+ isPastSubscriptionsLoading: d.isPastSubscriptionsLoading,
347
+ error: o.error || s.error || d.error,
348
+ refetch: h,
349
+ loadMorePastSubscriptions: d.loadMorePastSubscriptions,
350
+ hasMorePastSubscriptions: d.hasMorePastSubscriptions,
351
+ isLoadingMorePast: d.isLoadingMorePast,
352
+ pastSubscriptionsCount: d.pastSubscriptionsCount
269
353
  };
270
354
  }
271
355
  //#endregion
272
- export { _ as useBillingAccountQuotasSummary, g as useBillingAccountsForUsage, C as useEnhancedUsagePage, S as useQuotaUsageDetails, y as useSubscriptionsWithQuotas, p as useUsageDashboard };
356
+ export { w as useBillingAccountQuotasSummary, C as useBillingAccountsForUsage, A as useEnhancedUsagePage, k as useQuotaUsageDetails, E as useSubscriptionsWithQuotas, y as useUsageDashboard, v as useWorkspaceQuotaHistory };
273
357
 
274
358
  //# sourceMappingURL=useUsage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useUsage.js","names":[],"sources":["../../../../../src/billing/modules/usage/hooks/useUsage.ts"],"sourcesContent":["/**\n * Usage Module - Hooks\n * Custom hooks for usage data fetching and mutations\n */\n\nimport { useMemo, useCallback, useState, useEffect } from 'react';\nimport {\n useGetUsageDashboardQuery,\n useGetBillingAccountQuotasSummaryForUsageQuery,\n useGetSubscriptionsWithQuotasQuery,\n useGetPastSubscriptionsWithQuotasQuery,\n useGetBillingAccountsForUsageQuery,\n useGetQuotaAnalyticsForUsageQuery,\n type GetPastSubscriptionsWithQuotasQuery,\n} from '../../../../generated/global-operations';\nimport {\n useGetUsageRecordsQuery,\n type GetUsageRecordsQuery,\n type GetUsageRecordsQueryVariables,\n} from '../../../../generated/wspace-operations';\nimport { useGatewayClient } from '@burdenoff/fe-libs/shared/graphql';\nimport { AnalyticsPeriod, QuotaStatus } from '../../../shared/types';\nimport type { UsageDashboard } from '../../../shared/types';\n\n// ============================================================================\n// Dashboard Hook\n// ============================================================================\n\ninterface UseUsageDashboardParams {\n billingAccountId?: string;\n period?: AnalyticsPeriod;\n}\n\ninterface UseUsageDashboardResult {\n dashboard: UsageDashboard | null;\n isLoading: boolean;\n error: Error | null;\n refetch: () => void;\n}\n\nexport function useUsageDashboard({\n billingAccountId,\n period = AnalyticsPeriod.LAST_30_DAYS,\n}: UseUsageDashboardParams): UseUsageDashboardResult {\n const { data, loading, error, refetch } = useGetUsageDashboardQuery({\n variables: { billingAccountId: billingAccountId!, period },\n skip: !billingAccountId,\n fetchPolicy: 'cache-and-network',\n });\n\n return {\n dashboard: data?.getUsageDashboard ?? null,\n isLoading: loading,\n error: error ?? null,\n refetch,\n };\n}\n\n// ============================================================================\n// Enhanced Usage Page Hooks\n// ============================================================================\n\n/**\n * Quota assignment from the API\n */\ninterface QuotaAssignmentSummary {\n id: string;\n name: string;\n unit: string;\n quotaType: 'POOLED' | 'PRODUCT_SPECIFIC';\n reusable: boolean;\n limit: number;\n limitLeft: number;\n used: number;\n usagePercentage: number;\n noLimit: boolean;\n subscriptionId?: string;\n context?: Record<string, unknown> | null;\n recentUsages: Array<{\n id: string;\n amount: number;\n description: string;\n timestamp: string;\n tags?: Record<string, unknown>;\n }>;\n createdAt: string;\n endtime: string;\n}\n\n/**\n * Aggregated quota for display (multiple quota assignments with same name combined)\n */\nexport interface AggregatedQuota {\n name: string;\n displayName?: string;\n description?: string;\n unit: string;\n totalLimit: number;\n totalUsed: number;\n usagePercentage: number;\n status: QuotaStatus;\n quotaCount: number;\n noLimit: boolean;\n reusable: boolean;\n quotaAssignments: QuotaAssignmentSummary[];\n}\n\n/**\n * Subscription with aggregated quotas\n */\nexport interface SubscriptionWithAggregatedQuotas {\n id: string;\n status: string;\n planName?: string;\n productId?: string;\n createdAt: string;\n aggregatedQuotas: AggregatedQuota[];\n}\n\n/**\n * Helper function to calculate quota status based on usage percentage\n */\nfunction calculateQuotaStatus(usagePercentage: number, limitLeft: number): QuotaStatus {\n if (limitLeft <= 0) return QuotaStatus.EXHAUSTED;\n if (usagePercentage >= 90) return QuotaStatus.CRITICAL;\n if (usagePercentage >= 75) return QuotaStatus.WARNING;\n return QuotaStatus.HEALTHY;\n}\n\n/**\n * Helper function to aggregate quotas by name\n */\nfunction aggregateQuotasByName(quotas: QuotaAssignmentSummary[]): AggregatedQuota[] {\n const grouped = new Map<string, QuotaAssignmentSummary[]>();\n\n for (const quota of quotas) {\n const existing = grouped.get(quota.name) || [];\n existing.push(quota);\n grouped.set(quota.name, existing);\n }\n\n const aggregated: AggregatedQuota[] = [];\n\n for (const [name, assignments] of grouped) {\n // Sum up limits and usage first\n const totalLimit = assignments.reduce((sum, q) => sum + (q.limit || 0), 0);\n const totalUsed = assignments.reduce((sum, q) => sum + (q.used || 0), 0);\n const totalLimitLeft = assignments.reduce((sum, q) => sum + (q.limitLeft || 0), 0);\n\n // Check if there's actually no limit (ignore noLimit flag if there's a numeric limit)\n // Only treat as unlimited if totalLimit is 0 or all assignments explicitly have noLimit AND no numeric limit\n const hasNoLimit =\n totalLimit === 0 && assignments.every((q) => q.noLimit || (q.limit || 0) === 0);\n\n // Calculate percentage\n const usagePercentage = hasNoLimit || totalLimit === 0 ? 0 : (totalUsed / totalLimit) * 100;\n\n // Get status\n const status = calculateQuotaStatus(usagePercentage, totalLimitLeft);\n\n // Get reusable, unit, and display info from first assignment\n const reusable = assignments[0]?.reusable || false;\n const unit = assignments[0]?.unit || '';\n const ctx = assignments[0]?.context;\n const displayName = typeof ctx?.displayName === 'string' ? ctx.displayName : undefined;\n const description = typeof ctx?.description === 'string' ? ctx.description : undefined;\n\n aggregated.push({\n name,\n displayName,\n description,\n unit,\n totalLimit: hasNoLimit ? 0 : totalLimit,\n totalUsed,\n usagePercentage,\n status,\n quotaCount: assignments.length,\n noLimit: hasNoLimit,\n reusable,\n quotaAssignments: assignments,\n });\n }\n\n // Sort by status priority (critical first) then by usage percentage\n const statusPriority: Record<QuotaStatus, number> = {\n EXHAUSTED: 0,\n CRITICAL: 1,\n WARNING: 2,\n HEALTHY: 3,\n INACTIVE: 4,\n };\n\n return aggregated.sort((a, b) => {\n const priorityDiff = statusPriority[a.status] - statusPriority[b.status];\n if (priorityDiff !== 0) return priorityDiff;\n return b.usagePercentage - a.usagePercentage;\n });\n}\n\n/**\n * Hook to get billing accounts for the selector\n */\ninterface UseBillingAccountsForUsageResult {\n billingAccounts: Array<{\n id: string;\n name: string;\n email: string;\n currency: string;\n creditAmount: number;\n isActive: boolean;\n isDefault: boolean;\n }>;\n isLoading: boolean;\n error: Error | null;\n}\n\nexport function useBillingAccountsForUsage(): UseBillingAccountsForUsageResult {\n const { data, loading, error } = useGetBillingAccountsForUsageQuery({\n fetchPolicy: 'cache-and-network',\n });\n\n return {\n billingAccounts: data?.getBillingAccountsByOrg ?? [],\n isLoading: loading,\n error: error ?? null,\n };\n}\n\n/**\n * Hook to get billing account quotas summary with aggregation\n * Only returns pooled quotas - subscription quotas come from useSubscriptionsWithQuotas\n */\ninterface UseBillingAccountQuotasSummaryResult {\n pooledQuotas: AggregatedQuota[];\n isLoading: boolean;\n error: Error | null;\n refetch: () => void;\n}\n\nexport function useBillingAccountQuotasSummary(\n billingAccountId: string | undefined,\n productId?: string\n): UseBillingAccountQuotasSummaryResult {\n const { data, loading, error, refetch } = useGetBillingAccountQuotasSummaryForUsageQuery({\n variables: { billingAccountId: billingAccountId!, productId },\n skip: !billingAccountId,\n fetchPolicy: 'cache-and-network',\n });\n\n const pooledQuotas = useMemo(() => {\n if (!data?.getBillingAccountQuotasSummary) {\n return [];\n }\n\n const summary = data.getBillingAccountQuotasSummary;\n return aggregateQuotasByName(summary.pooledQuotas || []);\n }, [data]);\n\n return {\n pooledQuotas,\n isLoading: loading,\n error: error ?? null,\n refetch,\n };\n}\n\n/**\n * Subscription from the API\n */\ninterface SubscriptionQuota {\n id: string;\n name: string;\n limits: { type: string; value: number; unit?: string; originalValue?: number };\n context?: Record<string, unknown> | null;\n currentUsageSum: number;\n usageCount: number;\n createdAt: string;\n endtime: string;\n}\n\ninterface SubscriptionFromAPI {\n id: string;\n status: string;\n createdAt: string;\n quotas: SubscriptionQuota[];\n}\n\n/**\n * Hook to get subscriptions with their quotas grouped by status\n * Uses lazy loading for past subscriptions and supports backend search\n */\ntype ViewMode = 'active' | 'past' | 'all';\n\nconst PAST_SUBSCRIPTIONS_PAGE_SIZE = 10;\n\ninterface UseSubscriptionsWithQuotasOptions {\n searchQuery?: string;\n viewMode?: ViewMode;\n}\n\ninterface UseSubscriptionsWithQuotasResult {\n activeSubscriptions: SubscriptionWithAggregatedQuotas[];\n pastSubscriptions: SubscriptionWithAggregatedQuotas[];\n isLoading: boolean;\n isPastSubscriptionsLoading: boolean;\n error: Error | null;\n refetch: () => void;\n // Pagination for past subscriptions\n loadMorePastSubscriptions: () => void;\n hasMorePastSubscriptions: boolean;\n isLoadingMorePast: boolean;\n pastSubscriptionsCount: number;\n}\n\nexport function useSubscriptionsWithQuotas(\n billingAccountId: string | undefined,\n options: UseSubscriptionsWithQuotasOptions = {}\n): UseSubscriptionsWithQuotasResult {\n const { searchQuery, viewMode = 'active' } = options;\n\n // Determine which subscriptions to fetch based on viewMode\n const shouldFetchActive = viewMode === 'active' || viewMode === 'all';\n const shouldFetchPast = viewMode === 'past' || viewMode === 'all';\n\n // Query for active subscriptions\n const { data, loading, error, refetch } = useGetSubscriptionsWithQuotasQuery({\n variables: {\n billingAccountId: billingAccountId!,\n searchQuery: searchQuery || null,\n },\n skip: !billingAccountId || !shouldFetchActive,\n fetchPolicy: 'cache-and-network',\n });\n\n // Query for past subscriptions with pagination - only when viewMode is 'past' or 'all'\n const {\n data: pastData,\n loading: pastLoading,\n refetch: refetchPast,\n fetchMore: fetchMorePast,\n } = useGetPastSubscriptionsWithQuotasQuery({\n variables: {\n billingAccountId: billingAccountId!,\n searchQuery: searchQuery || null,\n page: 1,\n pageSize: PAST_SUBSCRIPTIONS_PAGE_SIZE,\n },\n skip: !billingAccountId || !shouldFetchPast,\n fetchPolicy: 'cache-and-network',\n });\n\n // Track if we're loading more past subscriptions\n const [isLoadingMorePast, setIsLoadingMorePast] = useState(false);\n const [currentPastPage, setCurrentPastPage] = useState(1);\n\n // Helper function to process subscription data\n const processSubscription = useCallback(\n (sub: SubscriptionFromAPI): SubscriptionWithAggregatedQuotas => {\n const quotaSummaries: QuotaAssignmentSummary[] = (sub.quotas || []).map((q) => {\n const limit = q.limits?.value || 0;\n const used = q.currentUsageSum || 0;\n const limitLeft = Math.max(0, limit - used);\n const usagePercentage = limit > 0 ? (used / limit) * 100 : 0;\n const unit = q.limits?.unit || '';\n\n return {\n id: q.id,\n name: q.name,\n unit,\n quotaType: 'PRODUCT_SPECIFIC' as const,\n reusable: false,\n limit,\n limitLeft,\n used,\n usagePercentage,\n noLimit: q.limits?.type !== 'number' && q.limits?.type !== 'numeric',\n subscriptionId: sub.id,\n context: q.context,\n recentUsages: [],\n createdAt: q.createdAt,\n endtime: q.endtime,\n };\n });\n\n return {\n id: sub.id,\n status: sub.status,\n createdAt: sub.createdAt,\n aggregatedQuotas: aggregateQuotasByName(quotaSummaries),\n };\n },\n []\n );\n\n // Process active subscriptions\n const activeSubscriptions = useMemo(() => {\n if (!data?.getSubscriptionUsageOverview) {\n return [];\n }\n\n const subscriptions: SubscriptionFromAPI[] = data.getSubscriptionUsageOverview;\n return subscriptions.map(processSubscription);\n }, [data, processSubscription]);\n\n // Process past subscriptions\n const pastSubscriptions = useMemo(() => {\n if (!pastData?.getSubscriptionUsageOverview) {\n return [];\n }\n\n const subscriptions: SubscriptionFromAPI[] =\n pastData.getSubscriptionUsageOverview.subscriptions || pastData.getSubscriptionUsageOverview;\n return subscriptions.map(processSubscription);\n }, [pastData, processSubscription]);\n\n // Get pagination info for past subscriptions\n const pastSubscriptionsPagination = useMemo(() => {\n const overview = pastData?.getSubscriptionUsageOverview;\n if (!overview) {\n return { totalCount: 0, hasMore: false };\n }\n // If it's the new paginated format\n if (overview.totalCount !== undefined) {\n return {\n totalCount: overview.totalCount,\n hasMore: pastSubscriptions.length < overview.totalCount,\n };\n }\n // Legacy format - assume there might be more if we got a full page\n return {\n totalCount: pastSubscriptions.length,\n hasMore: pastSubscriptions.length >= PAST_SUBSCRIPTIONS_PAGE_SIZE * currentPastPage,\n };\n }, [pastData, pastSubscriptions.length, currentPastPage]);\n\n // Reset page when search query or viewMode changes\n useEffect(() => {\n setCurrentPastPage(1);\n }, [searchQuery, viewMode]);\n\n // Load more past subscriptions\n const loadMorePastSubscriptions = useCallback(async () => {\n if (!fetchMorePast || isLoadingMorePast || !pastSubscriptionsPagination.hasMore) return;\n\n setIsLoadingMorePast(true);\n const nextPage = currentPastPage + 1;\n\n try {\n await fetchMorePast({\n variables: {\n page: nextPage,\n pageSize: PAST_SUBSCRIPTIONS_PAGE_SIZE,\n },\n updateQuery: (\n prev: GetPastSubscriptionsWithQuotasQuery,\n { fetchMoreResult }: { fetchMoreResult: GetPastSubscriptionsWithQuotasQuery }\n ) => {\n if (!fetchMoreResult) return prev;\n\n const prevSubs = prev?.getSubscriptionUsageOverview ?? [];\n const newSubs = fetchMoreResult?.getSubscriptionUsageOverview ?? [];\n\n return {\n getSubscriptionUsageOverview: [...prevSubs, ...newSubs],\n };\n },\n });\n setCurrentPastPage(nextPage);\n } catch (err) {\n console.error('Failed to load more past subscriptions:', err);\n } finally {\n setIsLoadingMorePast(false);\n }\n }, [fetchMorePast, isLoadingMorePast, pastSubscriptionsPagination.hasMore, currentPastPage]);\n\n const combinedRefetch = useCallback(() => {\n setCurrentPastPage(1);\n if (shouldFetchActive) refetch();\n if (shouldFetchPast) refetchPast();\n }, [shouldFetchActive, shouldFetchPast, refetch, refetchPast]);\n\n return {\n activeSubscriptions,\n pastSubscriptions,\n isLoading: shouldFetchActive ? loading : false,\n isPastSubscriptionsLoading: shouldFetchPast ? pastLoading : false,\n error: error ?? null,\n refetch: combinedRefetch,\n // Pagination for past subscriptions\n loadMorePastSubscriptions,\n hasMorePastSubscriptions: pastSubscriptionsPagination.hasMore,\n isLoadingMorePast,\n pastSubscriptionsCount: pastSubscriptionsPagination.totalCount,\n };\n}\n\n/**\n * Hook to get quota usage details for drill-down using cursor-based pagination.\n *\n * The activity-svc API is cursor-based (limit / cursor → items / hasNextPage / nextCursor).\n * Callers should maintain a cursor stack:\n * - push nextCursor to go forward\n * - pop to go back\n * - pass null as cursor for the first page\n */\nexport interface QuotaUsageDetail {\n id: string;\n amount: number;\n description: string;\n tags?: Record<string, unknown>;\n productId?: string;\n userId?: string;\n timestamp: string;\n lastUpdated?: string;\n}\n\ninterface UseQuotaUsageDetailsResult {\n usages: QuotaUsageDetail[];\n hasNextPage: boolean;\n nextCursor: string | null;\n isLoading: boolean;\n error: Error | null;\n refetch: () => void;\n}\n\ntype UsageRecord = GetUsageRecordsQuery['getUsageRecords']['items'][number];\n\nexport function buildUsageRecordsVariables(\n quotaAssignmentId: string | undefined,\n pageSize: number,\n cursor: string | null,\n workspaceId?: string\n): GetUsageRecordsQueryVariables {\n return {\n filters: {\n quotaAssignmentId,\n workspaceId,\n },\n pagination: {\n limit: pageSize,\n ...(cursor ? { cursor } : {}),\n },\n };\n}\n\nexport function mapUsageRecordToQuotaUsageDetail(record: UsageRecord): QuotaUsageDetail {\n return {\n id: record.id,\n amount: record.amount,\n description: record.description ?? '',\n tags: (record.metadata as Record<string, unknown>) ?? {},\n productId: record.productId,\n userId: record.userId ?? undefined,\n timestamp: record.createdAt,\n lastUpdated: record.createdAt,\n };\n}\n\nexport function useQuotaUsageDetails(\n quotaAssignmentId: string | undefined,\n pageSize: number = 20,\n cursor: string | null = null,\n workspaceId?: string\n): UseQuotaUsageDetailsResult {\n // Query workspace gateway directly — usage records live in wspace-activity-svc.\n // Uses the dedicated workspace Apollo client so it doesn't conflict with the\n // shell's global Apollo client used by all other billing queries.\n const wsClient = useGatewayClient('workspace');\n const { data, loading, error, refetch } = useGetUsageRecordsQuery({\n client: wsClient,\n variables: buildUsageRecordsVariables(quotaAssignmentId, pageSize, cursor, workspaceId),\n skip: !quotaAssignmentId || !workspaceId,\n fetchPolicy: 'cache-and-network',\n });\n\n const items: GetUsageRecordsQuery['getUsageRecords']['items'] =\n data?.getUsageRecords?.items ?? [];\n\n return {\n usages: items.map(mapUsageRecordToQuotaUsageDetail),\n hasNextPage: data?.getUsageRecords?.hasNextPage ?? false,\n nextCursor: data?.getUsageRecords?.nextCursor ?? null,\n isLoading: loading,\n error: error ?? null,\n refetch,\n };\n}\n\n/**\n * Hook to get quota analytics\n */\ninterface UseQuotaAnalyticsResult {\n analytics: {\n dailyUsage: Array<{ date: string; usage: number; count: number }>;\n usageByType: Array<{ resourceType: string; usage: number; count: number; percentage: number }>;\n trends?: {\n growthRate?: number;\n predictedUsage?: number;\n averageDailyUsage?: number;\n };\n peakUsage?: {\n maxDailyUsage: number;\n peakDate: string;\n peakHour?: number;\n };\n } | null;\n isLoading: boolean;\n error: Error | null;\n}\n\nexport function useQuotaAnalytics(\n quotaAssignmentId: string | undefined,\n period: AnalyticsPeriod = AnalyticsPeriod.LAST_30_DAYS\n): UseQuotaAnalyticsResult {\n const { data, loading, error } = useGetQuotaAnalyticsForUsageQuery({\n variables: { quotaAssignmentId: quotaAssignmentId!, period },\n skip: !quotaAssignmentId,\n fetchPolicy: 'cache-and-network',\n });\n\n return {\n analytics: data?.getQuotaAnalytics ?? null,\n isLoading: loading,\n error: error ?? null,\n };\n}\n\n/**\n * Combined hook for the enhanced usage page\n */\ninterface UseEnhancedUsagePageParams {\n billingAccountId: string | undefined;\n period?: AnalyticsPeriod;\n searchQuery?: string;\n viewMode?: ViewMode;\n}\n\ninterface UseEnhancedUsagePageResult {\n // Dashboard overview\n dashboard: UsageDashboard | null;\n\n // Pooled quotas (subscription quotas come from subscriptions directly)\n pooledQuotas: AggregatedQuota[];\n\n // Subscriptions with their quotas\n activeSubscriptions: SubscriptionWithAggregatedQuotas[];\n pastSubscriptions: SubscriptionWithAggregatedQuotas[];\n\n // Loading states\n isLoading: boolean;\n isPastSubscriptionsLoading: boolean;\n error: Error | null;\n\n // Actions\n refetch: () => void;\n\n // Pagination for past subscriptions\n loadMorePastSubscriptions: () => void;\n hasMorePastSubscriptions: boolean;\n isLoadingMorePast: boolean;\n pastSubscriptionsCount: number;\n}\n\nexport function useEnhancedUsagePage({\n billingAccountId,\n period = AnalyticsPeriod.LAST_30_DAYS,\n searchQuery,\n viewMode = 'active',\n}: UseEnhancedUsagePageParams): UseEnhancedUsagePageResult {\n // Dashboard for overview stats\n const dashboardResult = useUsageDashboard({\n billingAccountId,\n period,\n });\n\n // Quotas summary with aggregation\n const quotasSummaryResult = useBillingAccountQuotasSummary(billingAccountId);\n\n // Subscriptions with quotas - passes searchQuery and viewMode to backend\n const subscriptionsResult = useSubscriptionsWithQuotas(billingAccountId, {\n searchQuery,\n viewMode,\n });\n\n const refetch = useCallback(() => {\n dashboardResult.refetch();\n quotasSummaryResult.refetch();\n subscriptionsResult.refetch();\n }, [dashboardResult, quotasSummaryResult, subscriptionsResult]);\n\n return {\n dashboard: dashboardResult.dashboard,\n pooledQuotas: quotasSummaryResult.pooledQuotas,\n activeSubscriptions: subscriptionsResult.activeSubscriptions,\n pastSubscriptions: subscriptionsResult.pastSubscriptions,\n isLoading:\n dashboardResult.isLoading || quotasSummaryResult.isLoading || subscriptionsResult.isLoading,\n isPastSubscriptionsLoading: subscriptionsResult.isPastSubscriptionsLoading,\n error: dashboardResult.error || quotasSummaryResult.error || subscriptionsResult.error,\n refetch,\n // Pagination for past subscriptions\n loadMorePastSubscriptions: subscriptionsResult.loadMorePastSubscriptions,\n hasMorePastSubscriptions: subscriptionsResult.hasMorePastSubscriptions,\n isLoadingMorePast: subscriptionsResult.isLoadingMorePast,\n pastSubscriptionsCount: subscriptionsResult.pastSubscriptionsCount,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useUsage.js","names":[],"sources":["../../../../../src/billing/modules/usage/hooks/useUsage.ts"],"sourcesContent":["/**\n * Usage Module - Hooks\n * Custom hooks for usage data fetching and mutations\n */\n\nimport { useMemo, useCallback, useState, useEffect } from 'react';\nimport {\n useGetUsageDashboardQuery,\n useGetBillingAccountQuotasSummaryForUsageQuery,\n useGetSubscriptionsWithQuotasQuery,\n useGetPastSubscriptionsWithQuotasQuery,\n useGetBillingAccountsForUsageQuery,\n useGetQuotaAnalyticsForUsageQuery,\n type GetPastSubscriptionsWithQuotasQuery,\n} from '../../../../generated/global-operations';\nimport {\n useGetUsageRecordsQuery,\n type GetUsageRecordsQuery,\n type GetUsageRecordsQueryVariables,\n} from '../../../../generated/wspace-operations';\nimport { useGatewayClient, useQuery, gql } from '@burdenoff/fe-libs/shared/graphql';\nimport { AnalyticsPeriod, QuotaStatus } from '../../../shared/types';\nimport type { UsageDashboard } from '../../../shared/types';\n\n// ============================================================================\n// Workspace Quota Status — live values from activity-svc\n// ============================================================================\n\nconst WORKSPACE_QUOTA_STATUSES_QUERY = gql`\n query WorkspaceQuotaStatuses($workspaceId: ID!) {\n workspaceQuotaStatuses(workspaceId: $workspaceId) {\n workspaceId\n quotaName\n productId\n currentValue\n limit\n noLimit\n scrapedAt\n }\n }\n`;\n\nconst WORKSPACE_QUOTA_HISTORY_QUERY = gql`\n query WorkspaceQuotaHistory($workspaceId: ID!, $quotaName: String!, $limit: Int) {\n workspaceQuotaHistory(workspaceId: $workspaceId, quotaName: $quotaName, limit: $limit) {\n id\n workspaceId\n quotaName\n productId\n value\n limit\n noLimit\n snapshotAt\n }\n }\n`;\n\nexport interface WorkspaceQuotaStatusItem {\n workspaceId: string;\n quotaName: string;\n productId: string;\n currentValue: number;\n limit: number | null;\n noLimit: boolean;\n scrapedAt: string;\n}\n\nexport interface WorkspaceQuotaSnapshotItem {\n id: string;\n workspaceId: string;\n quotaName: string;\n productId: string;\n value: number;\n limit: number | null;\n noLimit: boolean;\n snapshotAt: string;\n}\n\ninterface UseWorkspaceQuotaStatusesResult {\n statuses: WorkspaceQuotaStatusItem[];\n statusMap: Map<string, WorkspaceQuotaStatusItem>;\n isLoading: boolean;\n error: Error | null;\n}\n\nexport function useWorkspaceQuotaStatuses(workspaceId?: string): UseWorkspaceQuotaStatusesResult {\n const wsClient = useGatewayClient('workspace');\n const { data, loading, error } = useQuery<{ workspaceQuotaStatuses: WorkspaceQuotaStatusItem[] }>(\n WORKSPACE_QUOTA_STATUSES_QUERY,\n {\n client: wsClient,\n variables: { workspaceId },\n skip: !workspaceId,\n fetchPolicy: 'cache-and-network',\n }\n );\n\n const { statuses, statusMap } = useMemo(() => {\n const list = data?.workspaceQuotaStatuses ?? [];\n return { statuses: list, statusMap: new Map(list.map((s) => [s.quotaName, s])) };\n }, [data]);\n\n return { statuses, statusMap, isLoading: loading, error: error ?? null };\n}\n\ninterface UseWorkspaceQuotaHistoryResult {\n snapshots: WorkspaceQuotaSnapshotItem[];\n isLoading: boolean;\n error: Error | null;\n}\n\nexport function useWorkspaceQuotaHistory(\n workspaceId?: string,\n quotaName?: string,\n limit: number = 48\n): UseWorkspaceQuotaHistoryResult {\n const wsClient = useGatewayClient('workspace');\n const { data, loading, error } = useQuery<{\n workspaceQuotaHistory: WorkspaceQuotaSnapshotItem[];\n }>(WORKSPACE_QUOTA_HISTORY_QUERY, {\n client: wsClient,\n variables: { workspaceId, quotaName, limit },\n skip: !workspaceId || !quotaName,\n fetchPolicy: 'cache-and-network',\n });\n\n return {\n snapshots: data?.workspaceQuotaHistory ?? [],\n isLoading: loading,\n error: error ?? null,\n };\n}\n\n// ============================================================================\n// Dashboard Hook\n// ============================================================================\n\ninterface UseUsageDashboardParams {\n billingAccountId?: string;\n period?: AnalyticsPeriod;\n}\n\ninterface UseUsageDashboardResult {\n dashboard: UsageDashboard | null;\n isLoading: boolean;\n error: Error | null;\n refetch: () => void;\n}\n\nexport function useUsageDashboard({\n billingAccountId,\n period = AnalyticsPeriod.LAST_30_DAYS,\n}: UseUsageDashboardParams): UseUsageDashboardResult {\n const { data, loading, error, refetch } = useGetUsageDashboardQuery({\n variables: { billingAccountId: billingAccountId!, period },\n skip: !billingAccountId,\n fetchPolicy: 'cache-and-network',\n });\n\n return {\n dashboard: data?.getUsageDashboard ?? null,\n isLoading: loading,\n error: error ?? null,\n refetch,\n };\n}\n\n// ============================================================================\n// Enhanced Usage Page Hooks\n// ============================================================================\n\n/**\n * Quota assignment from the API\n */\ninterface QuotaAssignmentSummary {\n id: string;\n name: string;\n unit: string;\n quotaType: 'POOLED' | 'PRODUCT_SPECIFIC';\n reusable: boolean;\n limit: number;\n limitLeft: number;\n used: number;\n usagePercentage: number;\n noLimit: boolean;\n subscriptionId?: string;\n context?: Record<string, unknown> | null;\n recentUsages: Array<{\n id: string;\n amount: number;\n description: string;\n timestamp: string;\n tags?: Record<string, unknown>;\n }>;\n createdAt: string;\n endtime: string;\n}\n\n/**\n * Aggregated quota for display (multiple quota assignments with same name combined)\n */\nexport interface AggregatedQuota {\n name: string;\n displayName?: string;\n description?: string;\n unit: string;\n totalLimit: number;\n totalUsed: number;\n usagePercentage: number;\n status: QuotaStatus;\n quotaCount: number;\n noLimit: boolean;\n reusable: boolean;\n quotaAssignments: QuotaAssignmentSummary[];\n}\n\n/**\n * Subscription with aggregated quotas\n */\nexport interface SubscriptionWithAggregatedQuotas {\n id: string;\n status: string;\n planName?: string;\n productId?: string;\n createdAt: string;\n aggregatedQuotas: AggregatedQuota[];\n}\n\n/**\n * Helper function to calculate quota status based on usage percentage\n */\nfunction calculateQuotaStatus(usagePercentage: number, limitLeft: number): QuotaStatus {\n if (limitLeft <= 0) return QuotaStatus.EXHAUSTED;\n if (usagePercentage >= 90) return QuotaStatus.CRITICAL;\n if (usagePercentage >= 75) return QuotaStatus.WARNING;\n return QuotaStatus.HEALTHY;\n}\n\n/**\n * Merges live collector values from activity-svc into a list of aggregated quotas.\n * Only overrides `totalUsed` (and derived fields) when a live value exists for that quota name.\n * Billing's `currentUsageSum` is always 0 for collector quotas, so this is the fix.\n */\nfunction mergeLiveValues(\n aggregated: AggregatedQuota[],\n statusMap: Map<string, WorkspaceQuotaStatusItem>\n): AggregatedQuota[] {\n if (statusMap.size === 0) return aggregated;\n return aggregated.map((q) => {\n const live = statusMap.get(q.name);\n if (!live) return q;\n const totalUsed = live.currentValue;\n const totalLimit = live.noLimit ? 0 : (live.limit ?? q.totalLimit);\n const usagePercentage = totalLimit > 0 ? (totalUsed / totalLimit) * 100 : 0;\n const limitLeft = Math.max(0, totalLimit - totalUsed);\n return {\n ...q,\n totalUsed,\n totalLimit,\n noLimit: live.noLimit,\n usagePercentage,\n status: calculateQuotaStatus(usagePercentage, limitLeft),\n };\n });\n}\n\n/**\n * Helper function to aggregate quotas by name\n */\nfunction aggregateQuotasByName(quotas: QuotaAssignmentSummary[]): AggregatedQuota[] {\n const grouped = new Map<string, QuotaAssignmentSummary[]>();\n\n for (const quota of quotas) {\n const existing = grouped.get(quota.name) || [];\n existing.push(quota);\n grouped.set(quota.name, existing);\n }\n\n const aggregated: AggregatedQuota[] = [];\n\n for (const [name, assignments] of grouped) {\n // Sum up limits and usage first\n const totalLimit = assignments.reduce((sum, q) => sum + (q.limit || 0), 0);\n const totalUsed = assignments.reduce((sum, q) => sum + (q.used || 0), 0);\n const totalLimitLeft = assignments.reduce((sum, q) => sum + (q.limitLeft || 0), 0);\n\n // Check if there's actually no limit (ignore noLimit flag if there's a numeric limit)\n // Only treat as unlimited if totalLimit is 0 or all assignments explicitly have noLimit AND no numeric limit\n const hasNoLimit =\n totalLimit === 0 && assignments.every((q) => q.noLimit || (q.limit || 0) === 0);\n\n // Calculate percentage\n const usagePercentage = hasNoLimit || totalLimit === 0 ? 0 : (totalUsed / totalLimit) * 100;\n\n // Get status\n const status = calculateQuotaStatus(usagePercentage, totalLimitLeft);\n\n // Get reusable, unit, and display info from first assignment\n const reusable = assignments[0]?.reusable || false;\n const unit = assignments[0]?.unit || '';\n const ctx = assignments[0]?.context;\n const displayName = typeof ctx?.displayName === 'string' ? ctx.displayName : undefined;\n const description = typeof ctx?.description === 'string' ? ctx.description : undefined;\n\n aggregated.push({\n name,\n displayName,\n description,\n unit,\n totalLimit: hasNoLimit ? 0 : totalLimit,\n totalUsed,\n usagePercentage,\n status,\n quotaCount: assignments.length,\n noLimit: hasNoLimit,\n reusable,\n quotaAssignments: assignments,\n });\n }\n\n // Sort by status priority (critical first) then by usage percentage\n const statusPriority: Record<QuotaStatus, number> = {\n EXHAUSTED: 0,\n CRITICAL: 1,\n WARNING: 2,\n HEALTHY: 3,\n INACTIVE: 4,\n };\n\n return aggregated.sort((a, b) => {\n const priorityDiff = statusPriority[a.status] - statusPriority[b.status];\n if (priorityDiff !== 0) return priorityDiff;\n return b.usagePercentage - a.usagePercentage;\n });\n}\n\n/**\n * Hook to get billing accounts for the selector\n */\ninterface UseBillingAccountsForUsageResult {\n billingAccounts: Array<{\n id: string;\n name: string;\n email: string;\n currency: string;\n creditAmount: number;\n isActive: boolean;\n isDefault: boolean;\n }>;\n isLoading: boolean;\n error: Error | null;\n}\n\nexport function useBillingAccountsForUsage(): UseBillingAccountsForUsageResult {\n const { data, loading, error } = useGetBillingAccountsForUsageQuery({\n fetchPolicy: 'cache-and-network',\n });\n\n return {\n billingAccounts: data?.getBillingAccountsByOrg ?? [],\n isLoading: loading,\n error: error ?? null,\n };\n}\n\n/**\n * Hook to get billing account quotas summary with aggregation\n * Only returns pooled quotas - subscription quotas come from useSubscriptionsWithQuotas\n */\ninterface UseBillingAccountQuotasSummaryResult {\n pooledQuotas: AggregatedQuota[];\n isLoading: boolean;\n error: Error | null;\n refetch: () => void;\n}\n\nexport function useBillingAccountQuotasSummary(\n billingAccountId: string | undefined,\n productId?: string\n): UseBillingAccountQuotasSummaryResult {\n const { data, loading, error, refetch } = useGetBillingAccountQuotasSummaryForUsageQuery({\n variables: { billingAccountId: billingAccountId!, productId },\n skip: !billingAccountId,\n fetchPolicy: 'cache-and-network',\n });\n\n const pooledQuotas = useMemo(() => {\n if (!data?.getBillingAccountQuotasSummary) {\n return [];\n }\n\n const summary = data.getBillingAccountQuotasSummary;\n return aggregateQuotasByName(summary.pooledQuotas || []);\n }, [data]);\n\n return {\n pooledQuotas,\n isLoading: loading,\n error: error ?? null,\n refetch,\n };\n}\n\n/**\n * Subscription from the API\n */\ninterface SubscriptionQuota {\n id: string;\n name: string;\n limits: { type: string; value: number; unit?: string; originalValue?: number };\n context?: Record<string, unknown> | null;\n currentUsageSum: number;\n usageCount: number;\n createdAt: string;\n endtime: string;\n}\n\ninterface SubscriptionFromAPI {\n id: string;\n status: string;\n createdAt: string;\n quotas: SubscriptionQuota[];\n}\n\n/**\n * Hook to get subscriptions with their quotas grouped by status\n * Uses lazy loading for past subscriptions and supports backend search\n */\ntype ViewMode = 'active' | 'past' | 'all';\n\nconst PAST_SUBSCRIPTIONS_PAGE_SIZE = 10;\n\ninterface UseSubscriptionsWithQuotasOptions {\n searchQuery?: string;\n viewMode?: ViewMode;\n}\n\ninterface UseSubscriptionsWithQuotasResult {\n activeSubscriptions: SubscriptionWithAggregatedQuotas[];\n pastSubscriptions: SubscriptionWithAggregatedQuotas[];\n isLoading: boolean;\n isPastSubscriptionsLoading: boolean;\n error: Error | null;\n refetch: () => void;\n // Pagination for past subscriptions\n loadMorePastSubscriptions: () => void;\n hasMorePastSubscriptions: boolean;\n isLoadingMorePast: boolean;\n pastSubscriptionsCount: number;\n}\n\nexport function useSubscriptionsWithQuotas(\n billingAccountId: string | undefined,\n options: UseSubscriptionsWithQuotasOptions = {}\n): UseSubscriptionsWithQuotasResult {\n const { searchQuery, viewMode = 'active' } = options;\n\n // Determine which subscriptions to fetch based on viewMode\n const shouldFetchActive = viewMode === 'active' || viewMode === 'all';\n const shouldFetchPast = viewMode === 'past' || viewMode === 'all';\n\n // Query for active subscriptions\n const { data, loading, error, refetch } = useGetSubscriptionsWithQuotasQuery({\n variables: {\n billingAccountId: billingAccountId!,\n searchQuery: searchQuery || null,\n },\n skip: !billingAccountId || !shouldFetchActive,\n fetchPolicy: 'cache-and-network',\n });\n\n // Query for past subscriptions with pagination - only when viewMode is 'past' or 'all'\n const {\n data: pastData,\n loading: pastLoading,\n refetch: refetchPast,\n fetchMore: fetchMorePast,\n } = useGetPastSubscriptionsWithQuotasQuery({\n variables: {\n billingAccountId: billingAccountId!,\n searchQuery: searchQuery || null,\n page: 1,\n pageSize: PAST_SUBSCRIPTIONS_PAGE_SIZE,\n },\n skip: !billingAccountId || !shouldFetchPast,\n fetchPolicy: 'cache-and-network',\n });\n\n // Track if we're loading more past subscriptions\n const [isLoadingMorePast, setIsLoadingMorePast] = useState(false);\n const [currentPastPage, setCurrentPastPage] = useState(1);\n\n // Helper function to process subscription data\n const processSubscription = useCallback(\n (sub: SubscriptionFromAPI): SubscriptionWithAggregatedQuotas => {\n const quotaSummaries: QuotaAssignmentSummary[] = (sub.quotas || []).map((q) => {\n const limit = q.limits?.value || 0;\n const used = q.currentUsageSum || 0;\n const limitLeft = Math.max(0, limit - used);\n const usagePercentage = limit > 0 ? (used / limit) * 100 : 0;\n const unit = q.limits?.unit || '';\n\n return {\n id: q.id,\n name: q.name,\n unit,\n quotaType: 'PRODUCT_SPECIFIC' as const,\n reusable: false,\n limit,\n limitLeft,\n used,\n usagePercentage,\n noLimit: q.limits?.type !== 'number' && q.limits?.type !== 'numeric',\n subscriptionId: sub.id,\n context: q.context,\n recentUsages: [],\n createdAt: q.createdAt,\n endtime: q.endtime,\n };\n });\n\n return {\n id: sub.id,\n status: sub.status,\n createdAt: sub.createdAt,\n aggregatedQuotas: aggregateQuotasByName(quotaSummaries),\n };\n },\n []\n );\n\n // Process active subscriptions\n const activeSubscriptions = useMemo(() => {\n if (!data?.getSubscriptionUsageOverview) {\n return [];\n }\n\n const subscriptions: SubscriptionFromAPI[] = data.getSubscriptionUsageOverview;\n return subscriptions.map(processSubscription);\n }, [data, processSubscription]);\n\n // Process past subscriptions\n const pastSubscriptions = useMemo(() => {\n if (!pastData?.getSubscriptionUsageOverview) {\n return [];\n }\n\n const subscriptions: SubscriptionFromAPI[] =\n pastData.getSubscriptionUsageOverview.subscriptions || pastData.getSubscriptionUsageOverview;\n return subscriptions.map(processSubscription);\n }, [pastData, processSubscription]);\n\n // Get pagination info for past subscriptions\n const pastSubscriptionsPagination = useMemo(() => {\n const overview = pastData?.getSubscriptionUsageOverview;\n if (!overview) {\n return { totalCount: 0, hasMore: false };\n }\n // If it's the new paginated format\n if (overview.totalCount !== undefined) {\n return {\n totalCount: overview.totalCount,\n hasMore: pastSubscriptions.length < overview.totalCount,\n };\n }\n // Legacy format - assume there might be more if we got a full page\n return {\n totalCount: pastSubscriptions.length,\n hasMore: pastSubscriptions.length >= PAST_SUBSCRIPTIONS_PAGE_SIZE * currentPastPage,\n };\n }, [pastData, pastSubscriptions.length, currentPastPage]);\n\n // Reset page when search query or viewMode changes\n useEffect(() => {\n setCurrentPastPage(1);\n }, [searchQuery, viewMode]);\n\n // Load more past subscriptions\n const loadMorePastSubscriptions = useCallback(async () => {\n if (!fetchMorePast || isLoadingMorePast || !pastSubscriptionsPagination.hasMore) return;\n\n setIsLoadingMorePast(true);\n const nextPage = currentPastPage + 1;\n\n try {\n await fetchMorePast({\n variables: {\n page: nextPage,\n pageSize: PAST_SUBSCRIPTIONS_PAGE_SIZE,\n },\n updateQuery: (\n prev: GetPastSubscriptionsWithQuotasQuery,\n { fetchMoreResult }: { fetchMoreResult: GetPastSubscriptionsWithQuotasQuery }\n ) => {\n if (!fetchMoreResult) return prev;\n\n const prevSubs = prev?.getSubscriptionUsageOverview ?? [];\n const newSubs = fetchMoreResult?.getSubscriptionUsageOverview ?? [];\n\n return {\n getSubscriptionUsageOverview: [...prevSubs, ...newSubs],\n };\n },\n });\n setCurrentPastPage(nextPage);\n } catch (err) {\n console.error('Failed to load more past subscriptions:', err);\n } finally {\n setIsLoadingMorePast(false);\n }\n }, [fetchMorePast, isLoadingMorePast, pastSubscriptionsPagination.hasMore, currentPastPage]);\n\n const combinedRefetch = useCallback(() => {\n setCurrentPastPage(1);\n if (shouldFetchActive) refetch();\n if (shouldFetchPast) refetchPast();\n }, [shouldFetchActive, shouldFetchPast, refetch, refetchPast]);\n\n return {\n activeSubscriptions,\n pastSubscriptions,\n isLoading: shouldFetchActive ? loading : false,\n isPastSubscriptionsLoading: shouldFetchPast ? pastLoading : false,\n error: error ?? null,\n refetch: combinedRefetch,\n // Pagination for past subscriptions\n loadMorePastSubscriptions,\n hasMorePastSubscriptions: pastSubscriptionsPagination.hasMore,\n isLoadingMorePast,\n pastSubscriptionsCount: pastSubscriptionsPagination.totalCount,\n };\n}\n\n/**\n * Hook to get quota usage details for drill-down using cursor-based pagination.\n *\n * The activity-svc API is cursor-based (limit / cursor → items / hasNextPage / nextCursor).\n * Callers should maintain a cursor stack:\n * - push nextCursor to go forward\n * - pop to go back\n * - pass null as cursor for the first page\n */\nexport interface QuotaUsageDetail {\n id: string;\n amount: number;\n description: string;\n tags?: Record<string, unknown>;\n productId?: string;\n userId?: string;\n timestamp: string;\n lastUpdated?: string;\n}\n\ninterface UseQuotaUsageDetailsResult {\n usages: QuotaUsageDetail[];\n hasNextPage: boolean;\n nextCursor: string | null;\n isLoading: boolean;\n error: Error | null;\n refetch: () => void;\n}\n\ntype UsageRecord = GetUsageRecordsQuery['getUsageRecords']['items'][number];\n\nexport function buildUsageRecordsVariables(\n quotaAssignmentId: string | undefined,\n pageSize: number,\n cursor: string | null,\n workspaceId?: string\n): GetUsageRecordsQueryVariables {\n return {\n filters: {\n quotaAssignmentId,\n workspaceId,\n },\n pagination: {\n limit: pageSize,\n ...(cursor ? { cursor } : {}),\n },\n };\n}\n\nexport function mapUsageRecordToQuotaUsageDetail(record: UsageRecord): QuotaUsageDetail {\n return {\n id: record.id,\n amount: record.amount,\n description: record.description ?? '',\n tags: (record.metadata as Record<string, unknown>) ?? {},\n productId: record.productId,\n userId: record.userId ?? undefined,\n timestamp: record.createdAt,\n lastUpdated: record.createdAt,\n };\n}\n\nexport function useQuotaUsageDetails(\n quotaAssignmentId: string | undefined,\n pageSize: number = 20,\n cursor: string | null = null,\n workspaceId?: string\n): UseQuotaUsageDetailsResult {\n // Query workspace gateway directly — usage records live in wspace-activity-svc.\n // Uses the dedicated workspace Apollo client so it doesn't conflict with the\n // shell's global Apollo client used by all other billing queries.\n const wsClient = useGatewayClient('workspace');\n const { data, loading, error, refetch } = useGetUsageRecordsQuery({\n client: wsClient,\n variables: buildUsageRecordsVariables(quotaAssignmentId, pageSize, cursor, workspaceId),\n skip: !quotaAssignmentId || !workspaceId,\n fetchPolicy: 'cache-and-network',\n });\n\n const items: GetUsageRecordsQuery['getUsageRecords']['items'] =\n data?.getUsageRecords?.items ?? [];\n\n return {\n usages: items.map(mapUsageRecordToQuotaUsageDetail),\n hasNextPage: data?.getUsageRecords?.hasNextPage ?? false,\n nextCursor: data?.getUsageRecords?.nextCursor ?? null,\n isLoading: loading,\n error: error ?? null,\n refetch,\n };\n}\n\n/**\n * Hook to get quota analytics\n */\ninterface UseQuotaAnalyticsResult {\n analytics: {\n dailyUsage: Array<{ date: string; usage: number; count: number }>;\n usageByType: Array<{ resourceType: string; usage: number; count: number; percentage: number }>;\n trends?: {\n growthRate?: number;\n predictedUsage?: number;\n averageDailyUsage?: number;\n };\n peakUsage?: {\n maxDailyUsage: number;\n peakDate: string;\n peakHour?: number;\n };\n } | null;\n isLoading: boolean;\n error: Error | null;\n}\n\nexport function useQuotaAnalytics(\n quotaAssignmentId: string | undefined,\n period: AnalyticsPeriod = AnalyticsPeriod.LAST_30_DAYS\n): UseQuotaAnalyticsResult {\n const { data, loading, error } = useGetQuotaAnalyticsForUsageQuery({\n variables: { quotaAssignmentId: quotaAssignmentId!, period },\n skip: !quotaAssignmentId,\n fetchPolicy: 'cache-and-network',\n });\n\n return {\n analytics: data?.getQuotaAnalytics ?? null,\n isLoading: loading,\n error: error ?? null,\n };\n}\n\n/**\n * Combined hook for the enhanced usage page\n */\ninterface UseEnhancedUsagePageParams {\n billingAccountId: string | undefined;\n workspaceId?: string;\n period?: AnalyticsPeriod;\n searchQuery?: string;\n viewMode?: ViewMode;\n}\n\ninterface UseEnhancedUsagePageResult {\n // Dashboard overview\n dashboard: UsageDashboard | null;\n\n // Pooled quotas (subscription quotas come from subscriptions directly)\n pooledQuotas: AggregatedQuota[];\n\n // Subscriptions with their quotas\n activeSubscriptions: SubscriptionWithAggregatedQuotas[];\n pastSubscriptions: SubscriptionWithAggregatedQuotas[];\n\n // Loading states\n isLoading: boolean;\n isPastSubscriptionsLoading: boolean;\n error: Error | null;\n\n // Actions\n refetch: () => void;\n\n // Pagination for past subscriptions\n loadMorePastSubscriptions: () => void;\n hasMorePastSubscriptions: boolean;\n isLoadingMorePast: boolean;\n pastSubscriptionsCount: number;\n}\n\nexport function useEnhancedUsagePage({\n billingAccountId,\n workspaceId,\n period = AnalyticsPeriod.LAST_30_DAYS,\n searchQuery,\n viewMode = 'active',\n}: UseEnhancedUsagePageParams): UseEnhancedUsagePageResult {\n // Dashboard for overview stats\n const dashboardResult = useUsageDashboard({\n billingAccountId,\n period,\n });\n\n // Quotas summary with aggregation\n const quotasSummaryResult = useBillingAccountQuotasSummary(billingAccountId);\n\n // Live collector values from activity-svc (source of truth for count/concurrent quotas)\n const { statusMap } = useWorkspaceQuotaStatuses(workspaceId);\n\n // Subscriptions with quotas - passes searchQuery and viewMode to backend\n const subscriptionsResult = useSubscriptionsWithQuotas(billingAccountId, {\n searchQuery,\n viewMode,\n });\n\n // Merge live values into both pooled quotas and subscription quotas\n const pooledQuotas = useMemo(\n () => mergeLiveValues(quotasSummaryResult.pooledQuotas, statusMap),\n [quotasSummaryResult.pooledQuotas, statusMap]\n );\n\n const activeSubscriptions = useMemo(\n () =>\n subscriptionsResult.activeSubscriptions.map((sub) => ({\n ...sub,\n aggregatedQuotas: mergeLiveValues(sub.aggregatedQuotas, statusMap),\n })),\n [subscriptionsResult.activeSubscriptions, statusMap]\n );\n\n const pastSubscriptions = useMemo(\n () =>\n subscriptionsResult.pastSubscriptions.map((sub) => ({\n ...sub,\n aggregatedQuotas: mergeLiveValues(sub.aggregatedQuotas, statusMap),\n })),\n [subscriptionsResult.pastSubscriptions, statusMap]\n );\n\n const refetch = useCallback(() => {\n dashboardResult.refetch();\n quotasSummaryResult.refetch();\n subscriptionsResult.refetch();\n }, [dashboardResult, quotasSummaryResult, subscriptionsResult]);\n\n return {\n dashboard: dashboardResult.dashboard,\n pooledQuotas,\n activeSubscriptions,\n pastSubscriptions,\n isLoading:\n dashboardResult.isLoading || quotasSummaryResult.isLoading || subscriptionsResult.isLoading,\n isPastSubscriptionsLoading: subscriptionsResult.isPastSubscriptionsLoading,\n error: dashboardResult.error || quotasSummaryResult.error || subscriptionsResult.error,\n refetch,\n // Pagination for past subscriptions\n loadMorePastSubscriptions: subscriptionsResult.loadMorePastSubscriptions,\n hasMorePastSubscriptions: subscriptionsResult.hasMorePastSubscriptions,\n isLoadingMorePast: subscriptionsResult.isLoadingMorePast,\n pastSubscriptionsCount: subscriptionsResult.pastSubscriptionsCount,\n };\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"UsagePage.d.ts","sourceRoot":"","sources":["../../../../../src/billing/modules/usage/pages/UsagePage.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAoD,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAwmBlF,eAAO,MAAM,SAAS,EAAE,EAmkBvB,CAAC"}
1
+ {"version":3,"file":"UsagePage.d.ts","sourceRoot":"","sources":["../../../../../src/billing/modules/usage/pages/UsagePage.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAoD,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAspBlF,eAAO,MAAM,SAAS,EAAE,EAskBvB,CAAC"}