Files
maternal-app/maternal-web/lib/api/analytics.ts
Andrei b0ac2f71df
Some checks failed
CI/CD Pipeline / Lint and Test (push) Has been cancelled
CI/CD Pipeline / E2E Tests (push) Has been cancelled
CI/CD Pipeline / Build Application (push) Has been cancelled
feat: Add advanced analytics UI components in frontend
- Add comprehensive API client methods for all advanced analytics endpoints
- Create CircadianRhythmCard component for sleep pattern visualization
- Create AnomalyAlertsPanel for anomaly detection and alerts
- Create GrowthPercentileChart with WHO/CDC percentiles
- Create CorrelationInsights for activity correlations
- Create TrendAnalysisChart with predictions
- Add advanced analytics page with all new components
- Add UI component library (shadcn/ui) setup
- Add navigation link to advanced analytics from insights page

All advanced analytics features are now accessible from the frontend UI.
2025-10-06 11:46:05 +00:00

537 lines
13 KiB
TypeScript

import { apiClient } from './client';
export interface SleepPattern {
averageDuration: number;
averageBedtime: string;
averageWakeTime: string;
nightWakings: number;
napCount: number;
consistency: number;
trend: 'improving' | 'stable' | 'declining';
}
export interface FeedingPattern {
averageInterval: number;
averageDuration: number;
totalFeedings: number;
feedingMethod: Record<string, number>;
consistency: number;
trend: 'increasing' | 'stable' | 'decreasing';
}
export interface DiaperPattern {
wetDiapersPerDay: number;
dirtyDiapersPerDay: number;
averageInterval: number;
isHealthy: boolean;
notes: string;
}
export interface GrowthSpurtDetection {
isLikelyGrowthSpurt: boolean;
confidence: number;
indicators: string[];
expectedDuration: string;
recommendations: string[];
}
export interface PatternInsights {
sleep: SleepPattern | null;
feeding: FeedingPattern | null;
diaper: DiaperPattern | null;
growthSpurt: GrowthSpurtDetection | null;
recommendations: string[];
concernsDetected: string[];
}
export interface SleepPrediction {
nextNapTime: Date | null;
nextNapConfidence: number;
nextBedtime: Date | null;
bedtimeConfidence: number;
optimalWakeWindows: number[];
reasoning: string;
}
export interface FeedingPrediction {
nextFeedingTime: Date | null;
confidence: number;
expectedInterval: number;
reasoning: string;
}
export interface PredictionInsights {
sleep: SleepPrediction;
feeding: FeedingPrediction;
generatedAt: Date;
}
export interface WeeklyReport {
childId: string;
weekStart: Date;
weekEnd: Date;
summary: {
totalFeedings: number;
averageFeedingsPerDay: number;
totalSleepHours: number;
averageSleepHoursPerDay: number;
totalDiapers: number;
averageDiapersPerDay: number;
};
dailyData: Array<{
date: Date;
feedings: number;
sleepHours: number;
diapers: number;
}>;
trends: {
feedingTrend: 'increasing' | 'stable' | 'decreasing';
sleepTrend: 'improving' | 'stable' | 'declining';
};
highlights: string[];
}
export interface MonthlyReport {
childId: string;
month: Date;
summary: {
totalFeedings: number;
totalSleepHours: number;
totalDiapers: number;
averageFeedingsPerDay: number;
averageSleepHoursPerDay: number;
averageDiapersPerDay: number;
};
weeklyData: Array<{
weekStart: Date;
feedings: number;
sleepHours: number;
diapers: number;
}>;
milestones: string[];
trends: string[];
}
// Advanced Analytics Interfaces
export interface CircadianRhythm {
sleepPhaseShift: number;
consistency: number;
optimalBedtime: string;
optimalWakeTime: string;
chronotype: 'early_bird' | 'night_owl' | 'typical';
melatoninOnset: string;
recommendedSchedule: {
wakeTime: string;
morningNap?: { start: string; duration: number };
afternoonNap?: { start: string; duration: number };
bedtime: string;
totalSleepTarget: number;
};
}
export interface AnomalyDetection {
anomalies: Array<{
activityId: string;
type: string;
timestamp: Date;
severity: 'low' | 'medium' | 'high';
description: string;
deviation: number;
}>;
alerts: Array<{
type: string;
severity: 'info' | 'warning' | 'critical';
message: string;
recommendations: string[];
}>;
confidenceScore: number;
}
export interface PatternCluster {
clusterId: string;
label: string;
activities: any[];
centroid: {
averageTime: string;
averageDuration: number;
characteristics: Record<string, any>;
};
confidence: number;
}
export interface CorrelationAnalysis {
feedingSleepCorrelation: number;
activityDiaperCorrelation: number;
sleepMoodCorrelation?: number;
insights: string[];
}
export interface TrendAnalysis {
shortTermTrend: {
direction: 'improving' | 'stable' | 'declining';
slope: number;
confidence: number;
r2Score: number;
changePercent: number;
};
mediumTermTrend: {
direction: 'improving' | 'stable' | 'declining';
slope: number;
confidence: number;
r2Score: number;
changePercent: number;
};
longTermTrend: {
direction: 'improving' | 'stable' | 'declining';
slope: number;
confidence: number;
r2Score: number;
changePercent: number;
};
seasonalPatterns?: Array<{
type: 'weekly' | 'monthly';
pattern: string;
strength: number;
}>;
prediction: {
next7Days: Array<{
date: Date;
predictedValue: number;
confidenceInterval: { lower: number; upper: number };
}>;
confidence: number;
factors: string[];
};
}
export interface GrowthPercentile {
weight?: {
value: number;
percentile: number;
zScore: number;
interpretation: string;
};
height?: {
value: number;
percentile: number;
zScore: number;
interpretation: string;
};
headCircumference?: {
value: number;
percentile: number;
zScore: number;
interpretation: string;
};
bmi?: {
value: number;
percentile: number;
zScore: number;
interpretation: string;
};
}
export interface GrowthAnalysis {
currentPercentiles: GrowthPercentile;
growthVelocity: {
weightVelocity?: {
value: number;
unit: string;
percentile: number;
};
heightVelocity?: {
value: number;
unit: string;
percentile: number;
};
interpretation: string;
concerns: string[];
};
growthCurve: {
measurements: Array<{
date: Date;
weight?: number;
height?: number;
headCircumference?: number;
}>;
percentileCurves: {
weight: Record<string, number[]>;
height: Record<string, number[]>;
headCircumference: Record<string, number[]>;
};
};
projections: {
threeMonths: GrowthPercentile;
sixMonths: GrowthPercentile;
confidence: number;
};
recommendations: string[];
alerts: Array<{
type: string;
severity: 'low' | 'medium' | 'high';
message: string;
action: string;
}>;
}
export interface AdvancedAnalyticsDashboard {
circadianRhythm: CircadianRhythm;
anomalies: AnomalyDetection;
correlations: CorrelationAnalysis;
growthAnalysis: GrowthAnalysis;
trends: Record<string, TrendAnalysis>;
clusters: Record<string, PatternCluster[]>;
}
export const analyticsApi = {
// Get pattern insights
getInsights: async (childId: string, days: number = 7): Promise<PatternInsights> => {
const response = await apiClient.get(`/api/v1/analytics/insights/${childId}`, {
params: { days },
});
return response.data.data;
},
// Get predictions
getPredictions: async (childId: string): Promise<PredictionInsights> => {
const response = await apiClient.get(`/api/v1/analytics/predictions/${childId}`);
const data = response.data.data;
// Convert date strings to Date objects
return {
...data,
generatedAt: new Date(data.generatedAt),
sleep: {
...data.sleep,
nextNapTime: data.sleep.nextNapTime ? new Date(data.sleep.nextNapTime) : null,
nextBedtime: data.sleep.nextBedtime ? new Date(data.sleep.nextBedtime) : null,
},
feeding: {
...data.feeding,
nextFeedingTime: data.feeding.nextFeedingTime ? new Date(data.feeding.nextFeedingTime) : null,
},
};
},
// Get weekly report
getWeeklyReport: async (childId: string, startDate?: Date): Promise<WeeklyReport> => {
const response = await apiClient.get(`/api/v1/analytics/reports/${childId}/weekly`, {
params: startDate ? { startDate: startDate.toISOString() } : {},
});
const data = response.data.data;
// Convert date strings
return {
...data,
weekStart: new Date(data.weekStart),
weekEnd: new Date(data.weekEnd),
dailyData: data.dailyData.map((d: any) => ({
...d,
date: new Date(d.date),
})),
};
},
// Get monthly report
getMonthlyReport: async (childId: string, month?: Date): Promise<MonthlyReport> => {
const response = await apiClient.get(`/api/v1/analytics/reports/${childId}/monthly`, {
params: month ? { month: month.toISOString() } : {},
});
const data = response.data.data;
// Convert date strings
return {
...data,
month: new Date(data.month),
weeklyData: data.weeklyData.map((w: any) => ({
...w,
weekStart: new Date(w.weekStart),
})),
};
},
// Export data
exportData: async (
childId: string,
format: 'json' | 'csv' | 'pdf',
startDate?: Date,
endDate?: Date,
): Promise<Blob> => {
const params: any = { format };
if (startDate) params.startDate = startDate.toISOString();
if (endDate) params.endDate = endDate.toISOString();
const response = await apiClient.get(`/api/v1/analytics/export/${childId}`, {
params,
responseType: format === 'json' ? 'json' : 'blob',
});
if (format === 'json') {
// Convert JSON to Blob
const jsonStr = JSON.stringify(response.data, null, 2);
return new Blob([jsonStr], { type: 'application/json' });
}
return response.data;
},
// Compare children
compareChildren: async (
childIds: string[],
metric: ComparisonMetric,
startDate: string,
endDate: string,
): Promise<any> => {
const response = await apiClient.get('/api/v1/analytics/compare', {
params: {
childIds: childIds.join(','),
metric,
startDate,
endDate,
},
});
return response.data.data;
},
// Advanced Analytics Methods
// Get circadian rhythm analysis
getCircadianRhythm: async (childId: string, days: number = 14): Promise<CircadianRhythm> => {
const response = await apiClient.get(`/api/v1/analytics/advanced/circadian/${childId}`, {
params: { days },
});
return response.data.data;
},
// Get anomaly detection
getAnomalies: async (childId: string, days: number = 30): Promise<AnomalyDetection> => {
const response = await apiClient.get(`/api/v1/analytics/advanced/anomalies/${childId}`, {
params: { days },
});
const data = response.data.data;
// Convert timestamps
return {
...data,
anomalies: data.anomalies.map((a: any) => ({
...a,
timestamp: new Date(a.timestamp),
})),
};
},
// Get activity clusters
getClusters: async (
childId: string,
activityType: string,
days: number = 30,
): Promise<PatternCluster[]> => {
const response = await apiClient.get(`/api/v1/analytics/advanced/clusters/${childId}`, {
params: { activityType, days },
});
return response.data.data;
},
// Get correlation analysis
getCorrelations: async (childId: string, days: number = 14): Promise<CorrelationAnalysis> => {
const response = await apiClient.get(`/api/v1/analytics/advanced/correlations/${childId}`, {
params: { days },
});
return response.data.data;
},
// Get trend analysis
getTrends: async (childId: string, activityType: string): Promise<TrendAnalysis> => {
const response = await apiClient.get(`/api/v1/analytics/advanced/trends/${childId}`, {
params: { activityType },
});
const data = response.data.data;
// Convert dates in predictions
return {
...data,
prediction: {
...data.prediction,
next7Days: data.prediction.next7Days.map((p: any) => ({
...p,
date: new Date(p.date),
})),
},
};
},
// Get growth percentiles
calculateGrowthPercentiles: async (
childId: string,
measurement: {
date: Date;
weight?: number;
height?: number;
headCircumference?: number;
},
): Promise<GrowthPercentile> => {
const response = await apiClient.post(
`/api/v1/analytics/growth/percentiles/${childId}`,
{
...measurement,
date: measurement.date.toISOString(),
},
);
return response.data.data;
},
// Get growth analysis
getGrowthAnalysis: async (childId: string): Promise<GrowthAnalysis> => {
const response = await apiClient.get(`/api/v1/analytics/growth/analysis/${childId}`);
const data = response.data.data;
// Convert dates in measurements
return {
...data,
growthCurve: {
...data.growthCurve,
measurements: data.growthCurve.measurements.map((m: any) => ({
...m,
date: new Date(m.date),
})),
},
};
},
// Get comprehensive analytics dashboard
getAdvancedDashboard: async (childId: string): Promise<AdvancedAnalyticsDashboard> => {
const response = await apiClient.get(`/api/v1/analytics/advanced/dashboard/${childId}`);
const data = response.data.data;
// Process all date conversions
return {
...data,
anomalies: {
...data.anomalies,
anomalies: data.anomalies.anomalies.map((a: any) => ({
...a,
timestamp: new Date(a.timestamp),
})),
},
growthAnalysis: {
...data.growthAnalysis,
growthCurve: {
...data.growthAnalysis.growthCurve,
measurements: data.growthAnalysis.growthCurve.measurements.map((m: any) => ({
...m,
date: new Date(m.date),
})),
},
},
};
},
};
export enum ComparisonMetric {
SLEEP_PATTERNS = 'sleep-patterns',
FEEDING_FREQUENCY = 'feeding-frequency',
GROWTH_CURVES = 'growth-curves',
DIAPER_CHANGES = 'diaper-changes',
ACTIVITIES = 'activities',
}