Files
twenty/packages/twenty-front/src/modules/settings/billing/hooks/useGetWorkflowNodeExecutionUsage.ts
T
Félix Malfait 77d4bd9158 Add billing usage analytics dashboard with ClickHouse integration (#18592)
## Summary
This PR adds a comprehensive billing usage analytics feature that
provides detailed breakdowns of credit consumption across execution
types, users, resources, and time periods. The implementation includes a
new ClickHouse-backed analytics service, GraphQL API endpoint, and a
frontend dashboard component.

## Key Changes

### Backend
- **New BillingAnalyticsService**: Queries ClickHouse for usage
breakdowns by user, resource, execution type, and time series data
- **BillingEventWriterService**: Writes billing events to ClickHouse for
analytics while maintaining best-effort semantics (never blocks Stripe
billing)
- **ClickHouse Schema**: Added `billingEvent` table with 3-year TTL for
storing detailed billing event data
- **GraphQL Resolver**: New `getBillingAnalytics` query that aggregates
usage data for the current billing period, protected by feature flag and
billing permissions
- **Enhanced BillingUsageEvent**: Added `userWorkspaceId` field to track
per-user credit consumption
- **AI Billing Integration**: Updated AI billing service to pass
`userWorkspaceId` when recording usage events

### Frontend
- **SettingsBillingAnalyticsSection**: New component displaying:
  - Usage breakdown by execution type with progress bars
  - Daily usage time series chart (28-day view)
  - Per-user credit consumption breakdown
  - Per-resource (agent/workflow) credit consumption breakdown
- **SettingsUsage Page**: Dedicated page for viewing usage analytics
- **GraphQL Query**: `GetBillingAnalytics` query with generated hooks
- **Navigation**: Added Usage menu item in settings (feature-flagged)
- **Mock Data**: Included screenshot mock data for preview/testing

### Feature Flag
- Added `IS_USAGE_ANALYTICS_ENABLED` feature flag to control visibility
and access to analytics features

## Implementation Details
- Analytics data is queried in parallel for performance
- ClickHouse writes are non-blocking to ensure billing operations never
fail
- Progress bars use dynamic coloring from a predefined palette
- Time series visualization normalizes bar heights relative to max value
- Empty state handling when no analytics data is available
- Responsive UI with proper text truncation for long names

https://claude.ai/code/session_01Y1EqrX6PFq3EJxJq89h7DF

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-23 10:28:23 +01:00

42 lines
1.1 KiB
TypeScript

import { useQuery } from '@apollo/client/react';
import {
BillingProductKey,
GetMeteredProductsUsageDocument,
} from '~/generated-metadata/graphql';
import { findOrThrow } from 'twenty-shared/utils';
export const useGetWorkflowNodeExecutionUsage = () => {
const { data, loading, refetch } = useQuery(GetMeteredProductsUsageDocument);
const refetchMeteredProductsUsage = () => {
refetch();
};
const isGetMeteredProductsUsageQueryLoaded = () => {
return data?.getMeteredProductsUsage && !loading;
};
const getMeteredProductUsage = () => {
if (!data) {
throw new Error('getMeteredProductUsage was not loaded');
}
return data.getMeteredProductsUsage;
};
const getWorkflowNodeExecutionUsage = () => {
return findOrThrow(
getMeteredProductUsage(),
(productUsage) =>
productUsage.productKey === BillingProductKey.WORKFLOW_NODE_EXECUTION,
);
};
return {
refetchMeteredProductsUsage,
isGetMeteredProductsUsageQueryLoaded:
isGetMeteredProductsUsageQueryLoaded(),
getWorkflowNodeExecutionUsage,
};
};