Files
bakery-ia/frontend/src/api/services/tenantService.ts

369 lines
8.8 KiB
TypeScript
Raw Normal View History

2025-07-22 17:01:12 +02:00
// src/api/services/TenantService.ts
import { apiClient } from '../base/apiClient';
import {
ApiResponse,
TenantInfo,
} from '../types/api';
export interface TenantCreate {
name: string;
email: string;
phone: string;
address: string;
latitude?: number;
longitude?: number;
business_type: 'individual_bakery' | 'central_workshop';
subscription_plan?: string;
settings?: Record<string, any>;
}
export interface TenantUpdate extends Partial<TenantCreate> {
is_active?: boolean;
}
export interface TenantSettings {
business_hours: {
monday: { open: string; close: string; closed: boolean };
tuesday: { open: string; close: string; closed: boolean };
wednesday: { open: string; close: string; closed: boolean };
thursday: { open: string; close: string; closed: boolean };
friday: { open: string; close: string; closed: boolean };
saturday: { open: string; close: string; closed: boolean };
sunday: { open: string; close: string; closed: boolean };
};
timezone: string;
currency: string;
language: string;
notification_preferences: {
email_enabled: boolean;
whatsapp_enabled: boolean;
forecast_alerts: boolean;
training_notifications: boolean;
weekly_reports: boolean;
};
forecast_preferences: {
default_forecast_days: number;
confidence_level: number;
include_weather: boolean;
include_traffic: boolean;
alert_thresholds: {
high_demand_increase: number;
low_demand_decrease: number;
};
};
data_retention_days: number;
}
export interface TenantStats {
total_users: number;
active_users: number;
total_sales_records: number;
total_forecasts: number;
total_notifications_sent: number;
storage_used_mb: number;
api_calls_this_month: number;
last_activity: string;
subscription_status: 'active' | 'inactive' | 'suspended';
subscription_expires: string;
}
export interface TenantUser {
id: string;
email: string;
full_name: string;
role: string;
is_active: boolean;
last_login: string | null;
created_at: string;
}
export interface InviteUser {
email: string;
role: 'admin' | 'manager' | 'user';
full_name?: string;
send_invitation_email?: boolean;
}
export class TenantService {
/**
* Get current tenant info
*/
async getCurrentTenant(): Promise<TenantInfo> {
const response = await apiClient.get<ApiResponse<TenantInfo>>('/tenants/current');
return response.data!;
}
/**
* Update current tenant
*/
async updateCurrentTenant(updates: TenantUpdate): Promise<TenantInfo> {
const response = await apiClient.put<ApiResponse<TenantInfo>>('/tenants/current', updates);
return response.data!;
}
/**
* Get tenant settings
*/
async getTenantSettings(): Promise<TenantSettings> {
const response = await apiClient.get<ApiResponse<TenantSettings>>('/tenants/settings');
return response.data!;
}
/**
* Update tenant settings
*/
async updateTenantSettings(settings: Partial<TenantSettings>): Promise<TenantSettings> {
const response = await apiClient.put<ApiResponse<TenantSettings>>(
'/tenants/settings',
settings
);
return response.data!;
}
/**
* Get tenant statistics
*/
async getTenantStats(): Promise<TenantStats> {
const response = await apiClient.get<ApiResponse<TenantStats>>('/tenants/stats');
return response.data!;
}
/**
* Get tenant users
*/
async getTenantUsers(params?: {
role?: string;
active?: boolean;
page?: number;
limit?: number;
}): Promise<{
users: TenantUser[];
total: number;
page: number;
pages: number;
}> {
const response = await apiClient.get<ApiResponse<any>>('/tenants/users', { params });
return response.data!;
}
/**
* Invite user to tenant
*/
async inviteUser(invitation: InviteUser): Promise<{
invitation_id: string;
email: string;
role: string;
expires_at: string;
invitation_token: string;
}> {
const response = await apiClient.post<ApiResponse<any>>('/tenants/users/invite', invitation);
return response.data!;
}
/**
* Update user role
*/
async updateUserRole(userId: string, role: string): Promise<TenantUser> {
const response = await apiClient.patch<ApiResponse<TenantUser>>(
`/tenants/users/${userId}`,
{ role }
);
return response.data!;
}
/**
* Deactivate user
*/
async deactivateUser(userId: string): Promise<TenantUser> {
const response = await apiClient.patch<ApiResponse<TenantUser>>(
`/tenants/users/${userId}`,
{ is_active: false }
);
return response.data!;
}
/**
* Reactivate user
*/
async reactivateUser(userId: string): Promise<TenantUser> {
const response = await apiClient.patch<ApiResponse<TenantUser>>(
`/tenants/users/${userId}`,
{ is_active: true }
);
return response.data!;
}
/**
* Remove user from tenant
*/
async removeUser(userId: string): Promise<void> {
await apiClient.delete(`/tenants/users/${userId}`);
}
/**
* Get pending invitations
*/
async getPendingInvitations(): Promise<{
id: string;
email: string;
role: string;
invited_at: string;
expires_at: string;
invited_by: string;
}[]> {
const response = await apiClient.get<ApiResponse<any>>('/tenants/invitations');
return response.data!;
}
/**
* Cancel invitation
*/
async cancelInvitation(invitationId: string): Promise<void> {
await apiClient.delete(`/tenants/invitations/${invitationId}`);
}
/**
* Resend invitation
*/
async resendInvitation(invitationId: string): Promise<void> {
await apiClient.post(`/tenants/invitations/${invitationId}/resend`);
}
/**
* Get tenant activity log
*/
async getActivityLog(params?: {
userId?: string;
action?: string;
startDate?: string;
endDate?: string;
page?: number;
limit?: number;
}): Promise<{
activities: {
id: string;
user_id: string;
user_name: string;
action: string;
resource: string;
resource_id: string;
details?: Record<string, any>;
ip_address?: string;
user_agent?: string;
created_at: string;
}[];
total: number;
page: number;
pages: number;
}> {
const response = await apiClient.get<ApiResponse<any>>('/tenants/activity', { params });
return response.data!;
}
/**
* Get tenant billing info
*/
async getBillingInfo(): Promise<{
subscription_plan: string;
billing_cycle: 'monthly' | 'yearly';
next_billing_date: string;
amount: number;
currency: string;
payment_method: {
type: string;
last_four: string;
expires: string;
};
usage: {
api_calls: number;
storage_mb: number;
users: number;
limits: {
api_calls_per_month: number;
storage_mb: number;
max_users: number;
};
};
}> {
const response = await apiClient.get<ApiResponse<any>>('/tenants/billing');
return response.data!;
}
/**
* Update billing info
*/
async updateBillingInfo(billingData: {
payment_method_token?: string;
billing_address?: {
street: string;
city: string;
state: string;
zip: string;
country: string;
};
}): Promise<void> {
await apiClient.put('/tenants/billing', billingData);
}
/**
* Change subscription plan
*/
async changeSubscriptionPlan(
planId: string,
billingCycle: 'monthly' | 'yearly'
): Promise<{
subscription_id: string;
plan: string;
billing_cycle: string;
next_billing_date: string;
proration_amount?: number;
}> {
const response = await apiClient.post<ApiResponse<any>>('/tenants/subscription/change', {
plan_id: planId,
billing_cycle: billingCycle,
});
return response.data!;
}
/**
* Cancel subscription
*/
async cancelSubscription(cancelAt: 'immediately' | 'end_of_period'): Promise<{
cancelled_at: string;
will_cancel_at: string;
refund_amount?: number;
}> {
const response = await apiClient.post<ApiResponse<any>>('/tenants/subscription/cancel', {
cancel_at: cancelAt,
});
return response.data!;
}
/**
* Export tenant data
*/
async exportTenantData(dataTypes: string[], format: 'json' | 'csv'): Promise<Blob> {
const response = await apiClient.post('/tenants/export', {
data_types: dataTypes,
format,
responseType: 'blob',
});
return response as unknown as Blob;
}
/**
* Delete tenant (GDPR compliance)
*/
async deleteTenant(confirmationToken: string): Promise<{
deletion_scheduled_at: string;
data_retention_until: string;
recovery_period_days: number;
}> {
const response = await apiClient.delete<ApiResponse<any>>('/tenants/current', {
data: { confirmation_token: confirmationToken },
});
return response.data!;
}
}
export const tenantService = new TenantService();