turash/bugulma/frontend/services/analytics-api.ts
Damir Mukimov 6347f42e20
Consolidate repositories: Remove nested frontend .git and merge into main repository
- Remove nested git repository from bugulma/frontend/.git
- Add all frontend files to main repository tracking
- Convert from separate frontend/backend repos to unified monorepo
- Preserve all frontend code and development history as tracked files
- Eliminate nested repository complexity for simpler development workflow

This creates a proper monorepo structure with frontend and backend
coexisting in the same repository for easier development and deployment.
2025-11-25 06:02:57 +01:00

225 lines
6.1 KiB
TypeScript

import { z } from 'zod';
import { reportError } from '@/lib/error-handling';
import { BaseService } from '@/lib/service-base';
import { SERVICE_CONFIGS } from '@/lib/service-config';
// Response schemas
const connectionStatisticsSchema = z.object({
total_connections: z.number().nonnegative(),
active_connections: z.number().nonnegative(),
potential_connections: z.number().nonnegative(),
});
const itemCountSchema = z.object({
item: z.string(),
count: z.number().nonnegative(),
});
const supplyDemandAnalysisSchema = z.object({
top_needs: z.array(itemCountSchema),
top_offers: z.array(itemCountSchema),
});
const dashboardStatisticsSchema = z.object({
total_organizations: z.number().nonnegative(),
total_sites: z.number().nonnegative(),
total_resource_flows: z.number().nonnegative(),
total_matches: z.number().nonnegative(),
active_proposals: z.number().nonnegative(),
recent_activity: z.array(z.object({
id: z.string(),
type: z.string(),
description: z.string(),
timestamp: z.string(),
})),
});
// Type exports (keeping for backward compatibility)
export interface ConnectionStatistics {
total_connections: number;
active_connections: number;
potential_connections: number;
}
export interface ItemCount {
item: string;
count: number;
}
export interface SupplyDemandAnalysis {
top_needs: ItemCount[];
top_offers: ItemCount[];
}
export interface DashboardStatistics {
total_organizations: number;
total_sites: number;
total_resource_flows: number;
total_matches: number;
active_proposals: number;
recent_activity: Array<{
id: string;
type: string;
description: string;
timestamp: string;
}>;
}
/**
* Analytics Service
* Handles all analytics-related API operations with improved reliability and type safety
*/
class AnalyticsService extends BaseService {
constructor() {
super(SERVICE_CONFIGS.ANALYTICS);
}
/**
* Get connection statistics
*/
async getConnectionStatistics(): Promise<ConnectionStatistics> {
const result = await this.get('connections', connectionStatisticsSchema, undefined, {
context: 'getConnectionStatistics',
});
if (!result.success) {
const error = reportError(
new Error(result.error?.message || 'Failed to fetch connection statistics'),
{ operation: 'getConnectionStatistics' }
);
throw error;
}
return result.data;
}
/**
* Get supply and demand analysis
*/
async getSupplyDemandAnalysis(): Promise<SupplyDemandAnalysis> {
const result = await this.get('supply-demand', supplyDemandAnalysisSchema, undefined, {
context: 'getSupplyDemandAnalysis',
});
if (!result.success) {
const error = reportError(
new Error(result.error?.message || 'Failed to fetch supply demand analysis'),
{ operation: 'getSupplyDemandAnalysis' }
);
throw error;
}
return result.data;
}
/**
* Get dashboard statistics
*/
async getDashboardStatistics(): Promise<DashboardStatistics> {
const result = await this.get('dashboard', dashboardStatisticsSchema, undefined, {
context: 'getDashboardStatistics',
});
if (!result.success) {
const error = reportError(
new Error(result.error?.message || 'Failed to fetch dashboard statistics'),
{ operation: 'getDashboardStatistics' }
);
throw error;
}
return result.data;
}
/**
* Get platform statistics
*/
async getPlatformStatistics(): Promise<any> {
const result = await this.get('platform-stats', z.any(), undefined, {
context: 'getPlatformStatistics',
});
if (!result.success) {
const error = reportError(
new Error(result.error?.message || 'Failed to fetch platform statistics'),
{ operation: 'getPlatformStatistics' }
);
throw error;
}
return result.data;
}
/**
* Get matching statistics
*/
async getMatchingStatistics(): Promise<any> {
const result = await this.get('matching-stats', z.any(), undefined, {
context: 'getMatchingStatistics',
});
if (!result.success) {
const error = reportError(
new Error(result.error?.message || 'Failed to fetch matching statistics'),
{ operation: 'getMatchingStatistics' }
);
throw error;
}
return result.data;
}
/**
* Get resource flow statistics
*/
async getResourceFlowStatistics(): Promise<any> {
const result = await this.get('resource-flow-stats', z.any(), undefined, {
context: 'getResourceFlowStatistics',
});
if (!result.success) {
const error = reportError(
new Error(result.error?.message || 'Failed to fetch resource flow statistics'),
{ operation: 'getResourceFlowStatistics' }
);
throw error;
}
return result.data;
}
/**
* Get impact metrics
*/
async getImpactMetrics(): Promise<any> {
const result = await this.get('impact-metrics', z.any(), undefined, {
context: 'getImpactMetrics',
});
if (!result.success) {
const error = reportError(
new Error(result.error?.message || 'Failed to fetch impact metrics'),
{ operation: 'getImpactMetrics' }
);
throw error;
}
return result.data;
}
}
// Create and export service instance
const analyticsService = new AnalyticsService();
// Export service instance for direct usage
export { analyticsService };
// Export service methods directly for cleaner imports
export const getConnectionStatistics = analyticsService.getConnectionStatistics.bind(analyticsService);
export const getSupplyDemandAnalysis = analyticsService.getSupplyDemandAnalysis.bind(analyticsService);
export const getDashboardStatistics = analyticsService.getDashboardStatistics.bind(analyticsService);
export const getPlatformStatistics = analyticsService.getPlatformStatistics.bind(analyticsService);
export const getMatchingStatistics = analyticsService.getMatchingStatistics.bind(analyticsService);
export const getResourceFlowStatistics = analyticsService.getResourceFlowStatistics.bind(analyticsService);
export const getImpactMetrics = analyticsService.getImpactMetrics.bind(analyticsService);