docs: Add comprehensive multi-child implementation plan
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

Added detailed implementation plan covering:
- Frontend: Dynamic UI, child selector, bulk activity logging, comparison analytics
- Backend: Bulk operations, multi-child queries, family statistics
- AI/Voice: Child name detection, context building, clarification flows
- Database: Schema enhancements, user preferences, bulk operation tracking
- State management, API enhancements, real-time sync updates
- Testing strategy: Unit, integration, and E2E tests
- Migration plan with feature flags for phased rollout
- Performance optimizations: Caching, indexes, code splitting

Also includes:
- Security fixes for multi-family data leakage in analytics pages
- ParentFlow branding updates
- Activity tracking navigation improvements
- Backend DTO and error handling fixes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-04 21:05:14 +00:00
parent f854fe6fcd
commit 95ef0e5e78
12 changed files with 2778 additions and 321 deletions

View File

@@ -44,6 +44,7 @@ import { useLocalizedDate } from '@/hooks/useLocalizedDate';
import { useTranslation } from '@/hooks/useTranslation';
import { useFormatting } from '@/hooks/useFormatting';
import { BarChart, Bar, LineChart, Line, PieChart, Pie, Cell, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts';
import { useAuth } from '@/lib/auth/AuthContext';
type DateRange = '7days' | '30days' | '3months';
@@ -100,6 +101,7 @@ const getActivityColor = (type: ActivityType) => {
export const InsightsDashboard: React.FC = () => {
const router = useRouter();
const { user } = useAuth();
const { format, formatDistanceToNow } = useLocalizedDate();
const { t } = useTranslation('insights');
const { formatNumber } = useFormatting();
@@ -110,30 +112,55 @@ export const InsightsDashboard: React.FC = () => {
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const familyId = user?.families?.[0]?.familyId;
// Fetch children on mount
useEffect(() => {
const fetchChildren = async () => {
if (!familyId) {
setError('No family found');
return;
}
try {
const childrenData = await childrenApi.getChildren();
console.log('[InsightsDashboard] Loading children for familyId:', familyId);
const childrenData = await childrenApi.getChildren(familyId);
console.log('[InsightsDashboard] Loaded children:', childrenData);
setChildren(childrenData);
if (childrenData.length > 0) {
setSelectedChild(childrenData[0].id);
// Validate selected child or pick first one
const validChild = childrenData.find(c => c.id === selectedChild);
if (!validChild) {
setSelectedChild(childrenData[0].id);
}
}
} catch (err: any) {
console.error('[InsightsDashboard] Failed to load children:', err);
setError(err.response?.data?.message || t('errors.loadChildren'));
}
};
fetchChildren();
}, []);
}, [familyId]);
// Fetch activities when child or date range changes
useEffect(() => {
if (!selectedChild) return;
if (!selectedChild || children.length === 0) return;
// Validate that selectedChild belongs to current user's children
const childExists = children.some(child => child.id === selectedChild);
if (!childExists) {
console.warn('[InsightsDashboard] Selected child not found in user\'s children, resetting');
setSelectedChild(children[0].id);
setError('Selected child not found. Showing data for your first child.');
return;
}
const fetchActivities = async () => {
setLoading(true);
setError(null);
try {
console.log('[InsightsDashboard] Fetching activities for child:', selectedChild);
const days = dateRange === '7days' ? 7 : dateRange === '30days' ? 30 : 90;
const endDate = endOfDay(new Date());
const startDate = startOfDay(subDays(new Date(), days - 1));
@@ -144,8 +171,10 @@ export const InsightsDashboard: React.FC = () => {
startDate.toISOString(),
endDate.toISOString()
);
console.log('[InsightsDashboard] Fetched activities:', activitiesData.length);
setActivities(activitiesData);
} catch (err: any) {
console.error('[InsightsDashboard] Failed to load activities:', err);
setError(err.response?.data?.message || t('errors.loadActivities'));
} finally {
setLoading(false);
@@ -153,7 +182,7 @@ export const InsightsDashboard: React.FC = () => {
};
fetchActivities();
}, [selectedChild, dateRange]);
}, [selectedChild, dateRange, children]);
// Calculate statistics
const calculateStats = () => {