387 lines
9.3 KiB
TypeScript
387 lines
9.3 KiB
TypeScript
import { ApiRequestOptions } from '../hooks/useApi';
|
|
|
|
// ============================================================================
|
|
// TYPES & INTERFACES
|
|
// ============================================================================
|
|
|
|
export type TransactionType = 'CREDIT' | 'DEBIT' | 'ADJUSTMENT';
|
|
export type ReferenceType = 'WORKFLOW' | 'PAYMENT' | 'ADMIN' | 'SYSTEM' | 'STORAGE' | 'SUBSCRIPTION';
|
|
|
|
export interface BillingBalance {
|
|
mandateId: string;
|
|
mandateName: string;
|
|
balance: number;
|
|
currency: string;
|
|
warningThreshold: number;
|
|
isWarning: boolean;
|
|
}
|
|
|
|
export interface BillingTransaction {
|
|
id: string;
|
|
accountId: string;
|
|
transactionType: TransactionType;
|
|
amount: number;
|
|
description: string;
|
|
referenceType?: ReferenceType;
|
|
workflowId?: string;
|
|
featureInstanceId?: string;
|
|
featureCode?: string;
|
|
aicoreProvider?: string;
|
|
aicoreModel?: string;
|
|
createdByUserId?: string;
|
|
createdAt?: string;
|
|
mandateId?: string;
|
|
mandateName?: string;
|
|
userId?: string;
|
|
userName?: string;
|
|
}
|
|
|
|
export interface BillingSettings {
|
|
id: string;
|
|
mandateId: string;
|
|
warningThresholdPercent: number;
|
|
notifyOnWarning: boolean;
|
|
notifyEmails: string[];
|
|
autoRechargeEnabled?: boolean;
|
|
rechargeAmountCHF?: number;
|
|
rechargeMaxPerMonth?: number;
|
|
}
|
|
|
|
export interface BillingSettingsUpdate {
|
|
warningThresholdPercent?: number;
|
|
notifyOnWarning?: boolean;
|
|
notifyEmails?: string[];
|
|
autoRechargeEnabled?: boolean;
|
|
rechargeAmountCHF?: number;
|
|
rechargeMaxPerMonth?: number;
|
|
}
|
|
|
|
export interface UsageReport {
|
|
period: string;
|
|
totalCost: number;
|
|
transactionCount: number;
|
|
costByProvider: Record<string, number>;
|
|
costByModel: Record<string, number>;
|
|
costByFeature: Record<string, number>;
|
|
}
|
|
|
|
export interface AccountSummary {
|
|
id: string;
|
|
mandateId: string;
|
|
userId?: string;
|
|
balance: number;
|
|
warningThreshold: number;
|
|
enabled: boolean;
|
|
}
|
|
|
|
export interface CreditAddRequest {
|
|
userId?: string;
|
|
amount: number;
|
|
description?: string;
|
|
}
|
|
|
|
export interface CheckoutCreateRequest {
|
|
userId?: string;
|
|
amount: number;
|
|
returnUrl: string;
|
|
}
|
|
|
|
export interface CheckoutCreateResponse {
|
|
redirectUrl: string;
|
|
}
|
|
|
|
// Type for the request function passed to API functions
|
|
export type ApiRequestFunction = (options: ApiRequestOptions<any>) => Promise<any>;
|
|
|
|
// ============================================================================
|
|
// USER API FUNCTIONS
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Fetch billing balances for all mandates the user belongs to
|
|
* Endpoint: GET /api/billing/balance
|
|
*/
|
|
export async function fetchBalances(
|
|
request: ApiRequestFunction
|
|
): Promise<BillingBalance[]> {
|
|
return await request({
|
|
url: '/api/billing/balance',
|
|
method: 'get'
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Fetch billing balance for a specific mandate
|
|
* Endpoint: GET /api/billing/balance/{mandateId}
|
|
*/
|
|
export async function fetchBalanceForMandate(
|
|
request: ApiRequestFunction,
|
|
mandateId: string
|
|
): Promise<BillingBalance> {
|
|
return await request({
|
|
url: `/api/billing/balance/${mandateId}`,
|
|
method: 'get'
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Fetch transaction history
|
|
* Endpoint: GET /api/billing/transactions
|
|
*/
|
|
export async function fetchTransactions(
|
|
request: ApiRequestFunction,
|
|
limit: number = 50,
|
|
offset: number = 0
|
|
): Promise<BillingTransaction[]> {
|
|
return await request({
|
|
url: '/api/billing/transactions',
|
|
method: 'get',
|
|
params: { limit, offset }
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Fetch usage statistics
|
|
* Endpoint: GET /api/billing/statistics/{period}
|
|
*/
|
|
export async function fetchStatistics(
|
|
request: ApiRequestFunction,
|
|
period: 'day' | 'month' | 'year',
|
|
year: number,
|
|
month?: number
|
|
): Promise<UsageReport> {
|
|
const params: Record<string, any> = { year };
|
|
if (month !== undefined) {
|
|
params.month = month;
|
|
}
|
|
|
|
return await request({
|
|
url: `/api/billing/statistics/${period}`,
|
|
method: 'get',
|
|
params
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Fetch allowed AICore providers
|
|
* Endpoint: GET /api/billing/providers
|
|
*/
|
|
export async function fetchAllowedProviders(
|
|
request: ApiRequestFunction
|
|
): Promise<string[]> {
|
|
return await request({
|
|
url: '/api/billing/providers',
|
|
method: 'get'
|
|
});
|
|
}
|
|
|
|
// ============================================================================
|
|
// ADMIN API FUNCTIONS
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Fetch billing settings for a mandate (Admin)
|
|
* Endpoint: GET /api/billing/admin/settings/{mandateId}
|
|
*/
|
|
export async function fetchSettingsAdmin(
|
|
request: ApiRequestFunction,
|
|
mandateId: string
|
|
): Promise<BillingSettings> {
|
|
return await request({
|
|
url: `/api/billing/admin/settings/${mandateId}`,
|
|
method: 'get'
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Create or update billing settings (Admin)
|
|
* Endpoint: POST /api/billing/admin/settings/{mandateId}
|
|
*/
|
|
export async function updateSettingsAdmin(
|
|
request: ApiRequestFunction,
|
|
mandateId: string,
|
|
settings: BillingSettingsUpdate
|
|
): Promise<BillingSettings> {
|
|
return await request({
|
|
url: `/api/billing/admin/settings/${mandateId}`,
|
|
method: 'post',
|
|
data: settings
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Add credit to an account (Admin)
|
|
* Endpoint: POST /api/billing/admin/credit/{mandateId}
|
|
*/
|
|
export async function addCreditAdmin(
|
|
request: ApiRequestFunction,
|
|
mandateId: string,
|
|
creditRequest: CreditAddRequest
|
|
): Promise<BillingTransaction> {
|
|
return await request({
|
|
url: `/api/billing/admin/credit/${mandateId}`,
|
|
method: 'post',
|
|
data: creditRequest
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Create Stripe Checkout Session for credit top-up
|
|
* Endpoint: POST /api/billing/checkout/create/{mandateId}
|
|
*/
|
|
export async function createCheckoutSession(
|
|
request: ApiRequestFunction,
|
|
mandateId: string,
|
|
checkoutRequest: CheckoutCreateRequest
|
|
): Promise<CheckoutCreateResponse> {
|
|
return await request({
|
|
url: `/api/billing/checkout/create/${mandateId}`,
|
|
method: 'post',
|
|
data: checkoutRequest
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Fetch all accounts for a mandate (Admin)
|
|
* Endpoint: GET /api/billing/admin/accounts/{mandateId}
|
|
*/
|
|
export async function fetchAccountsAdmin(
|
|
request: ApiRequestFunction,
|
|
mandateId: string
|
|
): Promise<AccountSummary[]> {
|
|
return await request({
|
|
url: `/api/billing/admin/accounts/${mandateId}`,
|
|
method: 'get'
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Fetch all transactions for a mandate (Admin)
|
|
* Endpoint: GET /api/billing/admin/transactions/{mandateId}
|
|
*/
|
|
export async function fetchTransactionsAdmin(
|
|
request: ApiRequestFunction,
|
|
mandateId: string,
|
|
limit: number = 100
|
|
): Promise<BillingTransaction[]> {
|
|
return await request({
|
|
url: `/api/billing/admin/transactions/${mandateId}`,
|
|
method: 'get',
|
|
params: { limit }
|
|
});
|
|
}
|
|
|
|
/**
|
|
* User summary for billing admin
|
|
*/
|
|
export interface MandateUserSummary {
|
|
id: string;
|
|
username?: string;
|
|
email?: string;
|
|
firstName?: string;
|
|
lastName?: string;
|
|
displayName?: string;
|
|
}
|
|
|
|
/**
|
|
* Fetch all users for a mandate (Admin)
|
|
* Endpoint: GET /api/billing/admin/users/{mandateId}
|
|
*/
|
|
export async function fetchUsersForMandateAdmin(
|
|
request: ApiRequestFunction,
|
|
mandateId: string
|
|
): Promise<MandateUserSummary[]> {
|
|
return await request({
|
|
url: `/api/billing/admin/users/${mandateId}`,
|
|
method: 'get'
|
|
});
|
|
}
|
|
|
|
// ============================================================================
|
|
// MANDATE VIEW TYPES & API FUNCTIONS
|
|
// ============================================================================
|
|
|
|
export interface MandateBalance {
|
|
mandateId: string;
|
|
mandateName: string;
|
|
totalBalance: number;
|
|
userCount: number;
|
|
warningThresholdPercent: number;
|
|
}
|
|
|
|
/**
|
|
* Fetch mandate-level balances (SysAdmin only)
|
|
* Endpoint: GET /api/billing/view/mandates/balances
|
|
*/
|
|
export async function fetchMandateViewBalances(
|
|
request: ApiRequestFunction
|
|
): Promise<MandateBalance[]> {
|
|
return await request({
|
|
url: '/api/billing/view/mandates/balances',
|
|
method: 'get'
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Fetch mandate-level transactions (SysAdmin only)
|
|
* Endpoint: GET /api/billing/view/mandates/transactions
|
|
*/
|
|
export async function fetchMandateViewTransactions(
|
|
request: ApiRequestFunction,
|
|
limit: number = 100
|
|
): Promise<BillingTransaction[]> {
|
|
return await request({
|
|
url: '/api/billing/view/mandates/transactions',
|
|
method: 'get',
|
|
params: { limit }
|
|
});
|
|
}
|
|
|
|
// ============================================================================
|
|
// USER VIEW TYPES & API FUNCTIONS
|
|
// ============================================================================
|
|
|
|
export interface UserBalance {
|
|
accountId: string;
|
|
mandateId: string;
|
|
mandateName: string;
|
|
userId: string;
|
|
userName: string;
|
|
balance: number;
|
|
warningThreshold: number;
|
|
isWarning: boolean;
|
|
enabled: boolean;
|
|
}
|
|
|
|
export interface UserTransaction extends BillingTransaction {
|
|
userId?: string;
|
|
userName?: string;
|
|
}
|
|
|
|
/**
|
|
* Fetch user-level balances (RBAC-based)
|
|
* Endpoint: GET /api/billing/view/users/balances
|
|
*/
|
|
export async function fetchUserViewBalances(
|
|
request: ApiRequestFunction
|
|
): Promise<UserBalance[]> {
|
|
return await request({
|
|
url: '/api/billing/view/users/balances',
|
|
method: 'get'
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Fetch user-level transactions (RBAC-based)
|
|
* Endpoint: GET /api/billing/view/users/transactions
|
|
*/
|
|
export async function fetchUserViewTransactions(
|
|
request: ApiRequestFunction,
|
|
limit: number = 100
|
|
): Promise<UserTransaction[]> {
|
|
return await request({
|
|
url: '/api/billing/view/users/transactions',
|
|
method: 'get',
|
|
params: { limit }
|
|
});
|
|
}
|