frontend_nyla/src/api/billingApi.ts
2026-03-29 21:55:13 +02:00

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 }
});
}