Growth Tracking and Measurements - Developer Guide
Comprehensive technical documentation for implementing and extending growth tracking features in CrittrHavens.
Architecture Overview
The measurement system follows a multi-layered architecture with clear separation between data models, business logic, and presentation components.
Core Components
Data Layer:
src/config/measurements.ts- Measurement type definitions and configurationsrc/integrations/supabase/types.ts- Database schema types for measurement logssrc/lib/measurement-utils.ts- Data formatting and aggregation utilitiessrc/lib/unit-utils.ts- Unit conversion and display logic
Business Logic:
src/hooks/useLogForm.ts- Form state management for measurement entrysrc/lib/csv-export.ts- Data export functionalitysrc/services/logService.ts- Measurement persistence and retrieval
Presentation Layer:
src/components/charts/MeasurementChart.tsx- Interactive line chartssrc/components/charts/MeasurementTimeline.tsx- Timeline visualizationsrc/components/reports/VetReport.tsx- PDF report generationsrc/components/ui/log-modal.tsx- Measurement entry interface
Measurement Configuration
Measurement Types
// src/config/measurements.ts
export interface MeasurementType {
id: string;
label: string;
unit: string;
defaultUnit: string;
availableFor: string[];
isPaid?: boolean;
}
export const MEASUREMENT_TYPES: MeasurementType[] = [
// Free measurements for crittrs
{
id: "weight",
label: "Weight",
unit: "grams",
defaultUnit: "grams",
availableFor: ["crittr"],
isPaid: false
},
{
id: "length",
label: "Length",
unit: "millimeters",
defaultUnit: "millimeters",
availableFor: ["crittr"],
isPaid: false
},
// Paid measurements for habitats
{
id: "temperature",
label: "Temperature",
unit: "°C",
defaultUnit: "°C",
availableFor: ["habitat"],
isPaid: true
}
// ... additional habitat measurements
];
Subscription-Based Feature Gates
export function getMeasurementTypesFor(itemType: string, isPaidUser: boolean = false): MeasurementType[] {
return MEASUREMENT_TYPES.filter(type =>
type.availableFor.includes(itemType) &&
(!type.isPaid || isPaidUser)
);
}
Data Flow Architecture
Measurement Entry Workflow
-
Log Modal Interaction (
src/components/ui/log-modal.tsx:270-284)- User selects "measurement" log type
- Dynamic measurement type selection based on item type and subscription
- Form validation with Zod schemas
-
Form State Management (
src/hooks/useLogForm.ts)addMeasurement(type, value, unit)- Add measurement to current logremoveMeasurement(index)- Remove measurement from logupdateMeasurement(index, updates)- Modify existing measurement
-
Data Persistence
- Measurements stored as JSON array in log records
- Each measurement contains:
{type, value, unit, timestamp} - Automatic unit standardization during storage
Chart Data Generation
Chart data filtering and processing is handled within the MeasurementChart component. The component filters measurement logs to show data matching the selected measurement type and sorts chronologically for display. The actual data transformation logic is embedded within the component's data processing flow.
Chart Implementation
Interactive Time Range Filtering
The MeasurementChart component supports multiple time range options with external control capability:
type TimeRange = '3_months' | '6_months' | '1_year' | '2_years' | 'all' | 'custom';
interface MeasurementChartProps {
title: string;
data: MeasurementData[];
unit: string;
color?: string;
onViewLogs?: () => void;
// External control for reports
controlledRange?: { type: TimeRange; from?: Date; to?: Date };
}
Responsive Design Patterns
Charts adapt to different screen sizes and data densities:
// src/components/charts/MeasurementChart.tsx (around line 135)
const getTickInterval = () => {
if (isMobile) {
// On mobile, show max 4 labels regardless of data points
if (sortedData.length <= 4) return 0;
return Math.ceil(sortedData.length / 4) - 1;
}
// Desktop: show more labels but still limit for readability
if (sortedData.length <= 8) return 0;
return Math.ceil(sortedData.length / 8) - 1;
};
Unit Display Logic
// src/lib/unit-utils.ts
const getShorthandUnit = (unit: string) => {
const unitMap: Record<string, string> = {
'grams': 'g',
'millimeters': 'mm',
'centimeters': 'cm',
// ... additional mappings
};
return unitMap[unit.toLowerCase()] || unit;
};
Export Functionality
CSV Export Implementation
// src/lib/csv-export.ts:13-30
export function exportMeasurementsToCSV(logs: any[], crittrName: string) {
// Extract all measurements from logs
const allMeasurements = logs
.filter(log => log.log_type === "measurement" && log.measurements)
.flatMap(log =>
(Array.isArray(log.measurements) ? log.measurements : []).map(m => ({
date: log.log_date || log.created_at,
type: m.type,
value: m.value,
unit: m.unit || '',
logId: log.id,
createdAt: log.created_at,
content: log.content || ''
}))
)
.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
// Group by date and merge measurements from same day
// ... data aggregation logic
}
PDF Report Generation
The VetReport component generates comprehensive PDF reports including:
- Measurement history tables
- Interactive charts (rendered as images in PDF)
- Time range filtering
- Professional formatting for veterinary use
// src/components/reports/VetReport.tsx (around line 244)
const generatePDF = async () => {
if (!html2pdf) {
html2pdf = (await import('html2pdf.js')).default;
}
const element = document.getElementById('vet-report-content');
// SVG to PNG conversion for PDF compatibility
// Chart rendering optimization
// Professional PDF formatting
};
Database Schema
Log Storage Structure
Measurements are stored as JSON within log records:
-- Simplified schema representation
logs: {
id: uuid,
log_type: 'measurement',
log_date: date,
measurements: json[], -- Array of measurement objects
content: text, -- Optional notes
crittr_id: uuid,
habitat_id: uuid (optional),
created_at: timestamp
}
-- Measurement object structure within JSON:
{
type: 'weight' | 'length' | 'temperature' | ...,
value: number,
unit: string,
timestamp?: string
}
Testing Patterns
Chart Component Testing
// Example test patterns for measurement components
describe('MeasurementChart', () => {
it('renders chart with minimum 2 data points', () => {
const data = [
{ date: '2024-01-01', value: 100, log_id: '1' },
{ date: '2024-01-15', value: 110, log_id: '2' }
];
render(<MeasurementChart title="Weight" data={data} unit="grams" />);
expect(screen.getByRole('img')).toBeInTheDocument();
});
it('filters data by time range correctly', () => {
// Time range filtering tests
});
});
Data Export Testing
describe('CSV Export', () => {
it('exports measurements with correct headers', () => {
const mockLogs = [/* measurement logs */];
exportMeasurementsToCSV(mockLogs, 'Test Crittr');
// Verify CSV structure and content
});
});
Performance Considerations
Chart Optimization
- Lazy loading for chart components in reports
- Data point limiting for large datasets
- Responsive rendering based on screen size
- Memoized calculations for chart domains
Data Loading Strategies
- Infinite scroll pagination for measurement history
- Time-based filtering at query level
- Subscription-based feature loading
- Optimistic updates for measurement entry
Extension Points
Adding New Measurement Types
-
Update Configuration (
src/config/measurements.ts){ id: "new_measurement", label: "New Measurement", unit: "custom_unit", defaultUnit: "custom_unit", availableFor: ["crittr", "habitat"], isPaid: false } -
Add Unit Conversion (
src/lib/unit-utils.ts) -
Update Form Validation (
src/lib/validations.ts) -
Extend Export Logic (
src/lib/csv-export.ts)
Custom Chart Types
The chart system supports extension through:
- Custom chart components following the
MeasurementChartinterface - Pluggable data transformation functions
- Configurable time range controls
- Theme-aware color schemes
Advanced Analytics
Framework for adding measurement analytics:
- Trend calculation utilities
- Statistical analysis functions
- Health threshold monitoring
- Predictive growth modeling
Integration Points
Third-Party Services
- Veterinary API integrations for health assessments
- IoT device data import (smart scales, environmental sensors)
- Research data sharing platforms
- Backup and sync services
Notification System
- Measurement reminder scheduling
- Growth milestone alerts
- Health threshold notifications
- Veterinary appointment triggers
See Also
- Care Center Architecture - Core care system implementation
- Task Management Architecture - Reminder and scheduling system
- Log System Architecture - Base logging implementation
Build comprehensive growth tracking that scales with your user's needs.