Phase 1 & 2: Authentication and Children Management

Completed Features:
- Full JWT authentication system with refresh tokens
- User registration and login with device fingerprinting
- Child profile CRUD operations with permission-based access
- Family management with roles and permissions
- Database migrations for core auth and family structure
- Comprehensive test coverage (37 unit + E2E tests)

Tech Stack:
- NestJS backend with TypeORM
- PostgreSQL database
- JWT authentication with Passport
- bcrypt password hashing
- Docker Compose for infrastructure

🤖 Generated with Claude Code
This commit is contained in:
andupetcu
2025-09-30 18:40:10 +03:00
commit 98e01ebe80
35 changed files with 9683 additions and 0 deletions

View File

@@ -0,0 +1,551 @@
# AI Context & Prompting Templates - Maternal Organization App
## LangChain Configuration
### Core Setup
```typescript
// services/ai/langchainConfig.ts
import { ChatOpenAI } from 'langchain/chat_models/openai';
import { ConversationSummaryMemory } from 'langchain/memory';
import { PromptTemplate } from 'langchain/prompts';
import { LLMChain } from 'langchain/chains';
export const initializeLangChain = () => {
const model = new ChatOpenAI({
modelName: 'gpt-4-turbo-preview',
temperature: 0.7,
maxTokens: 1000,
openAIApiKey: process.env.OPENAI_API_KEY,
callbacks: [
{
handleLLMStart: async (llm, prompts) => {
logger.info('LLM request started', { promptLength: prompts[0].length });
},
handleLLMEnd: async (output) => {
logger.info('LLM request completed', { tokensUsed: output.llmOutput?.tokenUsage });
},
},
],
});
const memory = new ConversationSummaryMemory({
memoryKey: 'chat_history',
llm: model,
maxTokenLimit: 2000,
});
return { model, memory };
};
```
### Context Window Management
```typescript
class ContextManager {
private maxContextTokens = 4000;
private priorityWeights = {
currentQuery: 1.0,
recentActivities: 0.8,
childProfile: 0.7,
historicalPatterns: 0.6,
generalGuidelines: 0.4,
};
async buildContext(
query: string,
childId: string,
userId: string
): Promise<AIContext> {
const contexts = await Promise.all([
this.getChildProfile(childId),
this.getRecentActivities(childId, 48), // Last 48 hours
this.getPatterns(childId),
this.getParentPreferences(userId),
this.getPreviousConversation(userId, childId),
]);
return this.prioritizeContext(contexts, query);
}
private prioritizeContext(
contexts: ContextPart[],
query: string
): AIContext {
// Token counting
let currentTokens = this.countTokens(query);
const prioritizedContexts: ContextPart[] = [];
// Sort by relevance and priority
const sorted = contexts
.map(ctx => ({
...ctx,
score: this.calculateRelevance(ctx, query) * this.priorityWeights[ctx.type],
}))
.sort((a, b) => b.score - a.score);
// Add contexts until token limit
for (const context of sorted) {
const tokens = this.countTokens(context.content);
if (currentTokens + tokens <= this.maxContextTokens) {
prioritizedContexts.push(context);
currentTokens += tokens;
}
}
return {
query,
contexts: prioritizedContexts,
totalTokens: currentTokens,
};
}
}
```
---
## System Prompts
### Base System Prompt
```typescript
const BASE_SYSTEM_PROMPT = `You are a knowledgeable, empathetic AI assistant helping parents care for their children aged 0-6 years.
Core Guidelines:
1. SAFETY FIRST: Never provide medical diagnoses. Always recommend consulting healthcare providers for medical concerns.
2. EVIDENCE-BASED: Provide advice based on pediatric best practices and research.
3. PARENT-SUPPORTIVE: Be encouraging and non-judgmental. Every family is different.
4. PRACTICAL: Give actionable, realistic suggestions that work for busy parents.
5. CULTURALLY AWARE: Respect diverse parenting approaches and cultural practices.
You have access to:
- The child's recent activity data (feeding, sleep, diapers)
- Developmental milestones for their age
- Pattern analysis from their historical data
- Family preferences and routines
Response Guidelines:
- Keep responses concise (under 150 words unless asked for detail)
- Use simple, clear language (avoid medical jargon)
- Provide specific, actionable suggestions
- Acknowledge parent concerns with empathy
- Include relevant safety warnings when appropriate`;
```
### Child-Specific Context Template
```typescript
const CHILD_CONTEXT_TEMPLATE = `Child Profile:
- Name: {childName}
- Age: {ageInMonths} months ({ageInYears} years)
- Developmental Stage: {developmentalStage}
- Known Conditions: {medicalConditions}
- Allergies: {allergies}
Recent Patterns (last 7 days):
- Average sleep: {avgSleepHours} hours/day
- Feeding frequency: Every {feedingInterval} hours
- Growth trajectory: {growthPercentile} percentile
Current Concerns:
{parentConcerns}
Recent Activities (last 24 hours):
{recentActivities}`;
```
---
## Prompt Templates by Scenario
### Sleep-Related Queries
```typescript
const SLEEP_PROMPT = PromptTemplate.fromTemplate(`
${BASE_SYSTEM_PROMPT}
Context:
{childContext}
Sleep-Specific Data:
- Recent bedtimes: {recentBedtimes}
- Wake windows today: {wakeWindows}
- Nap schedule: {napSchedule}
- Sleep regression risk: {regressionRisk}
Parent Question: {question}
Provide practical sleep advice considering:
1. Age-appropriate wake windows
2. Recent sleep patterns
3. Common sleep regressions at this age
4. Environmental factors
Response:
`);
```
### Feeding Queries
```typescript
const FEEDING_PROMPT = PromptTemplate.fromTemplate(`
${BASE_SYSTEM_PROMPT}
Context:
{childContext}
Feeding-Specific Data:
- Feeding type: {feedingType}
- Recent intake: {recentIntake}
- Growth trend: {growthTrend}
- Solid foods status: {solidsStatus}
Parent Question: {question}
Provide feeding guidance considering:
1. Age-appropriate feeding amounts
2. Growth patterns
3. Feeding milestones
4. Any mentioned concerns
Response:
`);
```
### Developmental Milestones
```typescript
const MILESTONE_PROMPT = PromptTemplate.fromTemplate(`
${BASE_SYSTEM_PROMPT}
Context:
{childContext}
Developmental Data:
- Expected milestones: {expectedMilestones}
- Achieved milestones: {achievedMilestones}
- Areas of focus: {developmentalFocus}
Parent Question: {question}
Provide developmental guidance:
1. What's typical for this age
2. Activities to encourage development
3. When to consult professionals
4. Celebrate achievements while avoiding comparison
Response:
`);
```
### Behavioral Concerns
```typescript
const BEHAVIOR_PROMPT = PromptTemplate.fromTemplate(`
${BASE_SYSTEM_PROMPT}
Context:
{childContext}
Behavioral Patterns:
- Recent behaviors: {recentBehaviors}
- Triggers identified: {triggers}
- Sleep/hunger status: {physiologicalState}
Parent Question: {question}
Provide behavioral guidance:
1. Age-appropriate expectations
2. Positive parenting strategies
3. Understanding underlying needs
4. Consistency and routine importance
Response:
`);
```
---
## Safety Boundaries
### Medical Disclaimer Triggers
```typescript
const MEDICAL_TRIGGERS = [
'diagnose', 'disease', 'syndrome', 'disorder',
'medication', 'dosage', 'prescription',
'emergency', 'urgent', 'bleeding', 'unconscious',
'seizure', 'fever over 104', 'difficulty breathing',
];
const MEDICAL_DISCLAIMER = `I understand you're concerned about {concern}. This seems like a medical issue that requires professional evaluation. Please contact your pediatrician or healthcare provider immediately. If this is an emergency, call your local emergency number.
For reference, here are signs requiring immediate medical attention:
- Difficulty breathing or bluish skin
- Unresponsiveness or difficulty waking
- High fever (over 104°F/40°C)
- Severe dehydration
- Head injury with vomiting or confusion`;
```
### Mental Health Support
```typescript
const MENTAL_HEALTH_PROMPT = `I hear that you're going through a difficult time. Your feelings are valid and important.
Here are some immediate resources:
- Postpartum Support International: 1-800-4-PPD-MOMS
- Crisis Text Line: Text HOME to 741741
- Local support groups: {localResources}
Please consider reaching out to:
- Your healthcare provider
- A mental health professional
- Trusted family or friends
Remember: Seeking help is a sign of strength, not weakness. Your wellbeing matters for both you and your baby.`;
```
---
## Response Formatting
### Structured Response Template
```typescript
interface AIResponse {
mainAnswer: string;
keyPoints?: string[];
actionItems?: string[];
safetyNotes?: string[];
relatedResources?: Resource[];
confidenceLevel: 'high' | 'medium' | 'low';
shouldEscalate: boolean;
}
const formatResponse = (raw: string, metadata: ResponseMetadata): AIResponse => {
return {
mainAnswer: extractMainAnswer(raw),
keyPoints: extractBulletPoints(raw),
actionItems: extractActionItems(raw),
safetyNotes: extractSafetyWarnings(raw),
relatedResources: findRelevantResources(metadata),
confidenceLevel: calculateConfidence(metadata),
shouldEscalate: checkEscalationTriggers(raw),
};
};
```
### Localized Response Generation
```typescript
const LOCALIZED_PROMPTS = {
'en-US': {
greeting: "I understand your concern about {topic}.",
transition: "Based on {childName}'s patterns,",
closing: "Remember, every baby is different.",
},
'es-ES': {
greeting: "Entiendo tu preocupación sobre {topic}.",
transition: "Basándome en los patrones de {childName},",
closing: "Recuerda, cada bebé es diferente.",
},
'fr-FR': {
greeting: "Je comprends votre inquiétude concernant {topic}.",
transition: "D'après les habitudes de {childName},",
closing: "Rappelez-vous, chaque bébé est unique.",
},
};
```
---
## Personalization Engine
### Learning from Feedback
```typescript
class PersonalizationEngine {
async updateResponsePreferences(
userId: string,
feedback: UserFeedback
) {
const preferences = await this.getUserPreferences(userId);
// Update preference weights
if (feedback.helpful) {
preferences.preferredResponseLength = feedback.responseLength;
preferences.preferredDetailLevel = feedback.detailLevel;
preferences.preferredTone = feedback.tone;
}
// Learn from negative feedback
if (!feedback.helpful && feedback.reason) {
this.adjustPromptTemplate(preferences, feedback.reason);
}
await this.saveUserPreferences(userId, preferences);
}
private adjustPromptTemplate(
preferences: UserPreferences,
reason: string
): PromptTemplate {
const adjustments = {
'too_technical': { jargonLevel: 'minimal', explanationStyle: 'simple' },
'too_general': { specificityLevel: 'high', includeExamples: true },
'too_long': { maxLength: 100, bulletPoints: true },
'not_actionable': { focusOnActions: true, includeSteps: true },
};
return this.applyAdjustments(preferences, adjustments[reason]);
}
}
```
---
## Chain of Thought for Complex Queries
### Multi-Step Reasoning
```typescript
const COMPLEX_REASONING_PROMPT = `Let me analyze this step-by-step:
Step 1: Understanding the Situation
{situationAnalysis}
Step 2: Identifying Patterns
Looking at {childName}'s recent data:
{patternAnalysis}
Step 3: Considering Age-Appropriate Norms
For a {ageInMonths}-month-old:
{developmentalNorms}
Step 4: Practical Recommendations
Based on the above:
{recommendations}
Step 5: What to Monitor
Keep track of:
{monitoringPoints}`;
```
---
## Conversation Memory Management
### Memory Summarization
```typescript
class ConversationMemory {
private maxConversationLength = 10;
async summarizeConversation(
messages: Message[],
childId: string
): Promise<string> {
if (messages.length <= 3) {
return messages.map(m => m.content).join('\n');
}
const summary = await this.llm.summarize({
messages,
focusPoints: [
'Main concerns discussed',
'Advice given',
'Action items suggested',
'Follow-up needed',
],
});
return summary;
}
async getRelevantHistory(
userId: string,
childId: string,
currentQuery: string
): Promise<string> {
const history = await this.fetchHistory(userId, childId);
// Semantic search for relevant past conversations
const relevant = await this.semanticSearch(history, currentQuery);
return this.formatHistory(relevant);
}
}
```
---
## Prompt Injection Protection
### Security Filters
```typescript
const INJECTION_PATTERNS = [
/ignore previous instructions/i,
/system:/i,
/admin mode/i,
/bypass safety/i,
/pretend you are/i,
];
const sanitizeUserInput = (input: string): string => {
// Check for injection attempts
for (const pattern of INJECTION_PATTERNS) {
if (pattern.test(input)) {
logger.warn('Potential prompt injection detected', { input });
return 'Please ask a question about childcare.';
}
}
// Escape special characters
return input
.replace(/[<>]/g, '')
.substring(0, 500); // Limit length
};
```
---
## Testing Prompt Effectiveness
### Prompt Evaluation Metrics
```typescript
interface PromptMetrics {
relevance: number; // 0-1: Response answers the question
safety: number; // 0-1: Appropriate medical disclaimers
actionability: number; // 0-1: Practical suggestions provided
empathy: number; // 0-1: Supportive tone
accuracy: number; // 0-1: Factually correct
}
const evaluatePromptResponse = async (
prompt: string,
response: string,
expectedQualities: PromptMetrics
): Promise<EvaluationResult> => {
const evaluation = await this.evaluatorLLM.evaluate({
prompt,
response,
criteria: expectedQualities,
});
return {
passed: evaluation.overall > 0.8,
metrics: evaluation,
suggestions: evaluation.improvements,
};
};
```
### Test Cases
```typescript
const promptTestCases = [
{
scenario: 'Sleep regression concern',
input: 'My 4-month-old suddenly won\'t sleep',
expectedResponse: {
containsMention: ['4-month sleep regression', 'normal', 'temporary'],
includesActions: ['consistent bedtime', 'wake windows'],
avoidsMedical: true,
},
},
{
scenario: 'Feeding amount worry',
input: 'Is 4oz enough for my 2-month-old?',
expectedResponse: {
containsMention: ['varies by baby', 'weight gain', 'wet diapers'],
includesActions: ['track intake', 'consult pediatrician'],
providesRanges: true,
},
},
];
```

View File

@@ -0,0 +1,939 @@
# API Specification Document - Maternal Organization App
## API Architecture Overview
### Base Configuration
- **Base URL**: `https://api.{domain}/api/v1`
- **GraphQL Endpoint**: `https://api.{domain}/graphql`
- **WebSocket**: `wss://api.{domain}/ws`
- **API Style**: Hybrid (REST for CRUD, GraphQL for complex queries)
- **Versioning**: URL path versioning (`/api/v1/`)
- **Rate Limiting**: 100 requests/minute per user
- **Pagination**: Cursor-based with consistent structure
### Standard Headers
```http
Content-Type: application/json
Accept: application/json
Accept-Language: en-US,en;q=0.9
X-Client-Version: 1.0.0
X-Device-ID: uuid-device-fingerprint
X-Timezone: America/New_York
Authorization: Bearer {access_token}
X-Refresh-Token: {refresh_token}
```
### Device Fingerprinting
```json
{
"deviceId": "uuid",
"platform": "ios|android",
"model": "iPhone14,2",
"osVersion": "16.5",
"appVersion": "1.0.0",
"pushToken": "fcm_or_apns_token"
}
```
---
## Authentication Endpoints
### POST `/api/v1/auth/register`
Create new user account with family setup.
**Request Body:**
```json
{
"email": "user@example.com",
"password": "SecurePass123!",
"phone": "+1234567890",
"name": "Jane Doe",
"locale": "en-US",
"timezone": "America/New_York",
"deviceInfo": {
"deviceId": "uuid",
"platform": "ios",
"model": "iPhone14,2",
"osVersion": "16.5"
}
}
```
**Response 201:**
```json
{
"success": true,
"data": {
"user": {
"id": "usr_2n4k8m9p",
"email": "user@example.com",
"name": "Jane Doe",
"locale": "en-US",
"emailVerified": false
},
"family": {
"id": "fam_7h3j9k2m",
"shareCode": "ABC123",
"role": "parent"
},
"tokens": {
"accessToken": "eyJhbGc...",
"refreshToken": "eyJhbGc...",
"expiresIn": 3600
},
"deviceRegistered": true
}
}
```
### POST `/api/v1/auth/login`
Authenticate existing user with device registration.
**Request Body:**
```json
{
"email": "user@example.com",
"password": "SecurePass123!",
"deviceInfo": {
"deviceId": "uuid",
"platform": "ios",
"model": "iPhone14,2",
"osVersion": "16.5"
}
}
```
**Response 200:**
```json
{
"success": true,
"data": {
"user": {
"id": "usr_2n4k8m9p",
"email": "user@example.com",
"families": ["fam_7h3j9k2m"]
},
"tokens": {
"accessToken": "eyJhbGc...",
"refreshToken": "eyJhbGc...",
"expiresIn": 3600
},
"requiresMFA": false,
"deviceTrusted": true
}
}
```
### POST `/api/v1/auth/refresh`
Refresh access token using refresh token.
**Request Body:**
```json
{
"refreshToken": "eyJhbGc...",
"deviceId": "uuid"
}
```
**Response 200:**
```json
{
"success": true,
"data": {
"accessToken": "eyJhbGc...",
"refreshToken": "eyJhbGc...",
"expiresIn": 3600
}
}
```
### POST `/api/v1/auth/logout`
Logout and revoke tokens for specific device.
**Request Body:**
```json
{
"deviceId": "uuid",
"allDevices": false
}
```
**Response 200:**
```json
{
"success": true,
"message": "Successfully logged out"
}
```
---
## Family Management Endpoints
### POST `/api/v1/families/invite`
Generate invitation for family member.
**Request Body:**
```json
{
"email": "partner@example.com",
"role": "parent|caregiver|viewer",
"permissions": {
"canAddChildren": true,
"canEditChildren": true,
"canLogActivities": true,
"canViewReports": true
},
"message": "Join our family on the app!"
}
```
**Response 201:**
```json
{
"success": true,
"data": {
"invitationId": "inv_8k3m9n2p",
"shareCode": "XYZ789",
"expiresAt": "2024-01-15T00:00:00Z",
"invitationUrl": "app://join/XYZ789"
}
}
```
### POST `/api/v1/families/join`
Join family using share code.
**Request Body:**
```json
{
"shareCode": "XYZ789"
}
```
**Response 200:**
```json
{
"success": true,
"data": {
"familyId": "fam_7h3j9k2m",
"familyName": "The Doe Family",
"role": "parent",
"members": [
{
"id": "usr_2n4k8m9p",
"name": "Jane Doe",
"role": "parent"
}
],
"children": []
}
}
```
### GET `/api/v1/families/{familyId}/members`
Get all family members with their permissions.
**Response 200:**
```json
{
"success": true,
"data": {
"members": [
{
"id": "usr_2n4k8m9p",
"name": "Jane Doe",
"email": "jane@example.com",
"role": "parent",
"permissions": {
"canAddChildren": true,
"canEditChildren": true,
"canLogActivities": true,
"canViewReports": true
},
"joinedAt": "2024-01-01T00:00:00Z",
"lastActive": "2024-01-10T15:30:00Z"
}
]
}
}
```
---
## Children Management Endpoints
### POST `/api/v1/children`
Add a new child to the family.
**Request Body:**
```json
{
"familyId": "fam_7h3j9k2m",
"name": "Emma",
"birthDate": "2023-06-15",
"gender": "female",
"bloodType": "O+",
"allergies": ["peanuts", "dairy"],
"medicalConditions": ["eczema"],
"pediatrician": {
"name": "Dr. Smith",
"phone": "+1234567890"
},
"photo": "base64_encoded_image"
}
```
**Response 201:**
```json
{
"success": true,
"data": {
"id": "chd_9m2k4n8p",
"familyId": "fam_7h3j9k2m",
"name": "Emma",
"birthDate": "2023-06-15",
"ageInMonths": 7,
"developmentalStage": "infant",
"photoUrl": "https://storage.api/photos/chd_9m2k4n8p.jpg"
}
}
```
### GET `/api/v1/children/{childId}`
Get child details with calculated metrics.
**Response 200:**
```json
{
"success": true,
"data": {
"id": "chd_9m2k4n8p",
"name": "Emma",
"birthDate": "2023-06-15",
"ageInMonths": 7,
"developmentalStage": "infant",
"currentWeight": {
"value": 8.2,
"unit": "kg",
"percentile": 75,
"recordedAt": "2024-01-10T10:00:00Z"
},
"currentHeight": {
"value": 68,
"unit": "cm",
"percentile": 80,
"recordedAt": "2024-01-10T10:00:00Z"
},
"todaySummary": {
"feedings": 5,
"sleepHours": 14.5,
"diapers": 6,
"lastFeedingAt": "2024-01-10T14:30:00Z",
"lastSleepAt": "2024-01-10T13:00:00Z"
}
}
}
```
---
## Activity Tracking Endpoints (REST)
### POST `/api/v1/activities/feeding`
Log a feeding activity.
**Request Body:**
```json
{
"childId": "chd_9m2k4n8p",
"type": "breast|bottle|solid",
"startTime": "2024-01-10T14:30:00Z",
"endTime": "2024-01-10T14:45:00Z",
"details": {
"breastSide": "left|right|both",
"amount": 120,
"unit": "ml|oz",
"foodType": "formula|breastmilk|puree"
},
"notes": "Good feeding session",
"mood": "happy|fussy|sleepy"
}
```
**Response 201:**
```json
{
"success": true,
"data": {
"id": "act_3k9n2m4p",
"childId": "chd_9m2k4n8p",
"type": "feeding",
"timestamp": "2024-01-10T14:30:00Z",
"duration": 15,
"createdBy": "usr_2n4k8m9p",
"syncedToFamily": true
}
}
```
### POST `/api/v1/activities/sleep`
Log sleep activity.
**Request Body:**
```json
{
"childId": "chd_9m2k4n8p",
"startTime": "2024-01-10T13:00:00Z",
"endTime": "2024-01-10T14:30:00Z",
"type": "nap|night",
"location": "crib|stroller|car|bed",
"quality": "good|restless|interrupted",
"notes": "Went down easily"
}
```
### POST `/api/v1/activities/diaper`
Log diaper change.
**Request Body:**
```json
{
"childId": "chd_9m2k4n8p",
"timestamp": "2024-01-10T15:00:00Z",
"type": "wet|dirty|both",
"consistency": "normal|loose|hard",
"color": "normal|green|yellow",
"hasRash": false,
"notes": "Applied diaper cream"
}
```
### GET `/api/v1/activities`
Get activities with cursor pagination.
**Query Parameters:**
- `childId`: Filter by child (required)
- `type`: Filter by activity type
- `startDate`: ISO date string
- `endDate`: ISO date string
- `cursor`: Pagination cursor
- `limit`: Items per page (default: 20, max: 100)
**Response 200:**
```json
{
"success": true,
"data": {
"activities": [
{
"id": "act_3k9n2m4p",
"childId": "chd_9m2k4n8p",
"type": "feeding",
"timestamp": "2024-01-10T14:30:00Z",
"details": {},
"createdBy": "usr_2n4k8m9p"
}
],
"cursor": {
"next": "eyJpZCI6ImFjdF8za...",
"hasMore": true,
"total": 150
}
}
}
```
---
## AI Assistant Endpoints
### POST `/api/v1/ai/chat`
Send message to AI assistant.
**Request Body:**
```json
{
"message": "Why won't my baby sleep?",
"childId": "chd_9m2k4n8p",
"conversationId": "conv_8n2k4m9p",
"context": {
"includeRecentActivities": true,
"includeSleepPatterns": true,
"includeDevelopmentalInfo": true
},
"locale": "en-US"
}
```
**Response 200:**
```json
{
"success": true,
"data": {
"conversationId": "conv_8n2k4m9p",
"messageId": "msg_7k3n9m2p",
"response": "Based on Emma's recent sleep patterns...",
"suggestions": [
"Try starting bedtime routine 15 minutes earlier",
"Check room temperature (ideal: 68-72°F)"
],
"relatedArticles": [
{
"title": "7-Month Sleep Regression",
"url": "/resources/sleep-regression-7-months"
}
],
"confidenceScore": 0.92
}
}
```
### POST `/api/v1/ai/voice`
Process voice command.
**Request Body (multipart/form-data):**
```
audio: [audio file - wav/mp3]
childId: chd_9m2k4n8p
locale: en-US
```
**Response 200:**
```json
{
"success": true,
"data": {
"transcription": "Baby fed 4 ounces at 3pm",
"interpretation": {
"action": "log_feeding",
"childId": "chd_9m2k4n8p",
"parameters": {
"amount": 4,
"unit": "oz",
"time": "15:00"
}
},
"executed": true,
"activityId": "act_9k2m4n3p"
}
}
```
---
## Analytics & Insights Endpoints
### GET `/api/v1/insights/{childId}/patterns`
Get AI-detected patterns for a child.
**Response 200:**
```json
{
"success": true,
"data": {
"sleepPatterns": {
"averageNightSleep": 10.5,
"averageDaySleep": 3.5,
"optimalBedtime": "19:30",
"wakeWindows": [90, 120, 150, 180],
"trend": "improving",
"insights": [
"Emma sleeps 45 minutes longer when put down before 7:30 PM",
"Morning wake time is consistently between 6:30-7:00 AM"
]
},
"feedingPatterns": {
"averageIntake": 28,
"feedingIntervals": [2.5, 3, 3, 4],
"preferredSide": "left",
"insights": [
"Feeding intervals increasing - may be ready for longer stretches"
]
}
}
}
```
### GET `/api/v1/insights/{childId}/predictions`
Get predictive suggestions.
**Response 200:**
```json
{
"success": true,
"data": {
"nextNapTime": {
"predicted": "2024-01-10T16:30:00Z",
"confidence": 0.85,
"wakeWindow": 120
},
"nextFeedingTime": {
"predicted": "2024-01-10T17:30:00Z",
"confidence": 0.78
},
"growthSpurt": {
"likelihood": 0.72,
"expectedIn": "5-7 days",
"symptoms": ["increased feeding", "fussiness", "disrupted sleep"]
}
}
}
```
---
## GraphQL Queries for Complex Data
### GraphQL Endpoint
`POST https://api.{domain}/graphql`
### Family Dashboard Query
```graphql
query FamilyDashboard($familyId: ID!, $date: Date!) {
family(id: $familyId) {
id
name
children {
id
name
age
todaySummary(date: $date) {
feedings {
count
totalAmount
lastAt
}
sleep {
totalHours
naps
nightSleep
currentStatus
}
diapers {
count
lastAt
}
}
upcomingEvents {
type
scheduledFor
description
}
aiInsights {
message
priority
actionable
}
}
members {
id
name
lastActive
recentActivities(limit: 5) {
type
childName
timestamp
}
}
}
}
```
### Weekly Report Query
```graphql
query WeeklyReport($childId: ID!, $startDate: Date!, $endDate: Date!) {
child(id: $childId) {
weeklyReport(startDate: $startDate, endDate: $endDate) {
sleep {
dailyAverages {
date
nightHours
napHours
totalHours
}
patterns {
consistentBedtime
averageWakeTime
longestStretch
}
}
feeding {
dailyTotals {
date
numberOfFeedings
totalVolume
}
trends {
direction
averageInterval
}
}
growth {
measurements {
date
weight
height
percentiles
}
}
milestones {
achieved {
name
achievedAt
}
upcoming {
name
expectedBy
}
}
}
}
}
```
---
## WebSocket Events
### Connection
```javascript
// Client connects with auth
ws.connect('wss://api.{domain}/ws', {
headers: {
'Authorization': 'Bearer {access_token}',
'X-Device-ID': 'uuid'
}
});
```
### Family Room Events
```javascript
// Join family room
ws.emit('join-family', { familyId: 'fam_7h3j9k2m' });
// Activity logged by family member
ws.on('activity-logged', {
activityId: 'act_3k9n2m4p',
childId: 'chd_9m2k4n8p',
type: 'feeding',
loggedBy: 'usr_2n4k8m9p',
timestamp: '2024-01-10T14:30:00Z'
});
// Real-time timer sync
ws.on('timer-started', {
timerId: 'tmr_8k3m9n2p',
type: 'feeding',
childId: 'chd_9m2k4n8p',
startedBy: 'usr_2n4k8m9p',
startTime: '2024-01-10T14:30:00Z'
});
// AI insight generated
ws.on('insight-available', {
childId: 'chd_9m2k4n8p',
type: 'pattern_detected',
message: 'New sleep pattern identified',
priority: 'medium'
});
```
---
## Error Responses
### Standard Error Format
```json
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid input data",
"details": {
"field": "email",
"reason": "Invalid email format"
},
"timestamp": "2024-01-10T15:30:00Z",
"traceId": "trace_8k3m9n2p"
}
}
```
### Error Codes
| Code | HTTP Status | Description |
|------|------------|-------------|
| `UNAUTHORIZED` | 401 | Invalid or expired token |
| `FORBIDDEN` | 403 | Insufficient permissions |
| `NOT_FOUND` | 404 | Resource not found |
| `VALIDATION_ERROR` | 400 | Invalid input data |
| `RATE_LIMITED` | 429 | Too many requests |
| `FAMILY_FULL` | 400 | Family member limit reached |
| `CHILD_LIMIT` | 400 | Free tier child limit reached |
| `AI_QUOTA_EXCEEDED` | 429 | AI query limit reached |
| `SYNC_CONFLICT` | 409 | Data sync conflict |
| `SERVER_ERROR` | 500 | Internal server error |
### Rate Limit Headers
```http
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1704903000
Retry-After: 3600
```
---
## Localization
### Supported Locales
- `en-US` - English (United States)
- `es-ES` - Spanish (Spain)
- `es-MX` - Spanish (Mexico)
- `fr-FR` - French (France)
- `fr-CA` - French (Canada)
- `pt-BR` - Portuguese (Brazil)
- `zh-CN` - Chinese (Simplified)
### Locale-Specific Responses
All error messages, AI responses, and notifications are returned in the user's selected locale based on the `Accept-Language` header or user profile setting.
### Date/Time Formatting
Dates are returned in ISO 8601 format but should be displayed according to user's locale:
- US: MM/DD/YYYY, 12-hour clock
- EU: DD/MM/YYYY, 24-hour clock
- Time zones always included in responses
### Measurement Units
```json
{
"measurement": {
"value": 8.2,
"unit": "kg",
"display": "8.2 kg",
"imperial": {
"value": 18.08,
"unit": "lbs",
"display": "18 lbs 1 oz"
}
}
}
```
---
## Security Considerations
### Authentication Flow
1. User provides credentials + device fingerprint
2. Server validates and issues access token (1 hour) + refresh token (30 days)
3. Device fingerprint stored and validated on each request
4. Refresh token rotation on use
5. All tokens revoked on suspicious activity
### Data Encryption
- All API communication over HTTPS/TLS 1.3
- Sensitive fields encrypted at rest (AES-256)
- PII data anonymized in logs
- No sensitive data in URL parameters
### COPPA/GDPR Compliance
- Parental consent required for child profiles
- Data minimization enforced
- Right to deletion implemented
- Data portability via export endpoints
- Audit logs for all data access
### Request Signing (Optional Enhanced Security)
```http
X-Signature: HMAC-SHA256(request-body + timestamp + nonce)
X-Timestamp: 1704903000
X-Nonce: unique-request-id
```
---
## Testing Endpoints
### Health Check
`GET /api/v1/health`
**Response 200:**
```json
{
"status": "healthy",
"version": "1.0.0",
"timestamp": "2024-01-10T15:30:00Z",
"services": {
"database": "connected",
"redis": "connected",
"ai": "operational"
}
}
```
### Test Notifications
`POST /api/v1/test/notification`
**Request Body:**
```json
{
"type": "test",
"deviceId": "uuid"
}
```
---
## SDK Usage Examples
### JavaScript/TypeScript
```typescript
import { MaternalAPI } from '@maternal/sdk';
const api = new MaternalAPI({
baseUrl: 'https://api.maternal.app',
version: 'v1'
});
// Authentication
const { tokens, user } = await api.auth.login({
email: 'user@example.com',
password: 'password',
deviceInfo: getDeviceInfo()
});
// Set tokens for subsequent requests
api.setTokens(tokens);
// Log activity
const activity = await api.activities.logFeeding({
childId: 'chd_9m2k4n8p',
type: 'bottle',
amount: 120,
unit: 'ml'
});
// Subscribe to real-time updates
api.websocket.on('activity-logged', (data) => {
console.log('New activity:', data);
});
```
### React Native
```typescript
import { useMaternalAPI } from '@maternal/react-native';
function FeedingScreen() {
const { logFeeding, isLoading } = useMaternalAPI();
const handleLogFeeding = async () => {
await logFeeding({
childId: currentChild.id,
type: 'breast',
duration: 15
});
};
}
```

View File

@@ -0,0 +1,207 @@
================================================================================
MATERNAL APP MVP - DATA FLOW ARCHITECTURE
================================================================================
┌─────────────────────────────────────────────────────────────────────────────┐
│ USER INTERFACE LAYER │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Parent 1 │ │ Parent 2 │ │ Caregiver │ │ Voice Input │ │
│ │ (Mobile) │ │ (Mobile) │ │ (Mobile) │ │ (Whisper) │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │ │ │
│ └──────────────────┴──────────────────┴──────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────┐ │
│ │ API Gateway (REST) │ │
│ │ Authentication │ │
│ │ Rate Limiting │ │
│ │ i18n Routing │ │
│ └───────────┬───────────┘ │
│ │ │
└──────────────────────────────────────┼──────────────────────────────────────┘
================================================================================
REAL-TIME SYNC LAYER
================================================================================
┌────────────▼────────────┐
│ WebSocket Server │
│ (Socket.io) │
│ ┌──────────────────┐ │
│ │ Event Publisher │ │
│ └──────────────────┘ │
│ ┌──────────────────┐ │
│ │ Family Rooms │ │
│ └──────────────────┘ │
└────────────┬────────────┘
┌─────────────────┼─────────────────┐
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Redis │ │ Redis │ │ Redis │
│ Channel 1│ │ Channel 2│ │ Channel 3│
│ (Family) │ │ (Family) │ │ (Family) │
└──────────┘ └──────────┘ └──────────┘
│ │ │
└─────────────────┼─────────────────┘
================================================================================
APPLICATION SERVICE LAYER
================================================================================
┌──────────────────────────────┼──────────────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Tracking │ │ AI Assistant │ │ Analytics │
│ Service │ │ Service │ │ Service │
│ │ │ │ │ │
│ • Feeding │ │ • Chat Handler │ │ • Pattern │
│ • Sleep │ │ • Context Mgr │ │ Detection │
│ • Diaper │◄─────────┤ • LLM Gateway │◄─────────┤ • Predictions │
│ • Growth │ │ • Response Gen │ │ • Insights │
│ • Voice Process │ │ │ │ • Reports │
└────────┬────────┘ └────────┬────────┘ └────────┬────────┘
│ │ │
│ ▼ │
│ ┌───────────────────────┐ │
│ │ LLM API Gateway │ │
│ │ ┌────────────────┐ │ │
│ │ │ OpenAI/Claude │ │ │
│ │ └────────────────┘ │ │
│ │ ┌────────────────┐ │ │
│ │ │ Context Cache │ │ │
│ │ └────────────────┘ │ │
│ └───────────────────────┘ │
│ │
└──────────────────────┬──────────────────────────────────┘
================================================================================
DATA PERSISTENCE LAYER
================================================================================
┌───────────▼───────────┐
│ Database Router │
└───────────┬───────────┘
┌───────────────────────┼───────────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ PostgreSQL │ │ MongoDB │ │ Redis │
│ (Primary) │ │ (Documents) │ │ (Cache) │
├──────────────┤ ├──────────────┤ ├──────────────┤
│ • Users │ │ • AI Chats │ │ • Sessions │
│ • Children │ │ • Reports │ │ • Real-time │
│ • Activities │ │ • Analytics │ │ • Predictions│
│ • Families │ │ • Logs │ │ • Temp Data │
│ • Settings │ │ │ │ │
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘
│ │ │
└──────────────────────┼───────────────────────┘
================================================================================
BACKGROUND JOBS LAYER
================================================================================
┌─────────▼─────────┐
│ Message Queue │
│ (Bull) │
└─────────┬─────────┘
┌─────────────────────┼─────────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Notification │ │ ML/AI │ │ Data │
│ Worker │ │ Worker │ │ Export │
├──────────────┤ ├──────────────┤ ├──────────────┤
│ • Push │ │ • Training │ │ • PDF Gen │
│ • Email │ │ • Prediction │ │ • CSV Export │
│ • SMS │ │ • Analysis │ │ • Backup │
└──────────────┘ └──────────────┘ └──────────────┘
================================================================================
DATA FLOW PATTERNS
================================================================================
1. ACTIVITY LOGGING FLOW:
User → Mobile App → API Gateway → Tracking Service → PostgreSQL
WebSocket Server → Redis Pub/Sub → All Family Devices
2. AI ASSISTANT FLOW:
User Query → Voice/Text Input → AI Service → Context Fetch (PostgreSQL)
LLM API → Response Generation
MongoDB (Chat History) → User
3. PATTERN RECOGNITION FLOW:
PostgreSQL Data → Analytics Service → ML Worker → Pattern Detection
Redis Cache → Predictions
Push Notification
4. REAL-TIME SYNC FLOW:
Device A → WebSocket → Redis Channel → WebSocket → Device B
PostgreSQL (Persistence)
5. OFFLINE SYNC FLOW:
Mobile SQLite → Queue Actions → Network Available → Sync Service
PostgreSQL
Conflict Resolution
Update All Devices
================================================================================
SECURITY BOUNDARIES
================================================================================
┌─────────────────────────────────────────────────────────────────────────┐
│ ENCRYPTED AT REST │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ END-TO-END ENCRYPTED │ │
│ │ ┌─────────────────────────────────────────────────────────────┐ │ │
│ │ │ SENSITIVE USER DATA │ │ │
│ │ │ • Child Health Records │ │ │
│ │ │ • Personal Identifiable Information │ │ │
│ │ │ • Location Data │ │ │
│ │ └─────────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ ENCRYPTED IN TRANSIT │ │
│ └───────────────────────────────────────────────────────────────────┘ │
│ │
│ AUDIT LOGGING │
└─────────────────────────────────────────────────────────────────────────┘
================================================================================
SCALABILITY NOTES
================================================================================
• Horizontal Scaling Points:
- API Gateway (Load Balancer)
- WebSocket Servers (Sticky Sessions)
- Service Layer (Kubernetes Pods)
- Redis (Cluster Mode)
- PostgreSQL (Read Replicas)
• Bottleneck Mitigation:
- LLM API: Response caching, rate limiting
- Database: Connection pooling, query optimization
- Real-time: Redis pub/sub for fan-out
- Storage: CDN for static assets
• Performance Targets:
- API Response: <200ms (p95)
- Real-time Sync: <100ms
- AI Response: <3s
- Offline Support: 7 days of data

View File

@@ -0,0 +1,412 @@
# Database Migration Scripts - Maternal Organization App
## Migration Strategy
### Naming Convention
- Format: `V{version}_{timestamp}_{description}.sql`
- Example: `V001_20240110120000_create_users_table.sql`
- Rollback: `R001_20240110120000_create_users_table.sql`
### Execution Order
Migrations must run sequentially. Each migration is recorded in a `schema_migrations` table to prevent re-execution.
---
## Migration V001: Core Authentication Tables
### Up Migration
```sql
-- V001_20240110120000_create_core_auth.sql
CREATE TABLE users (
id VARCHAR(20) PRIMARY KEY DEFAULT ('usr_' || nanoid()),
email VARCHAR(255) UNIQUE NOT NULL,
phone VARCHAR(20),
password_hash VARCHAR(255) NOT NULL,
name VARCHAR(100) NOT NULL,
locale VARCHAR(10) DEFAULT 'en-US',
timezone VARCHAR(50) DEFAULT 'UTC',
email_verified BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE device_registry (
id VARCHAR(20) PRIMARY KEY DEFAULT ('dev_' || nanoid()),
user_id VARCHAR(20) NOT NULL REFERENCES users(id) ON DELETE CASCADE,
device_fingerprint VARCHAR(255) NOT NULL,
platform VARCHAR(20) NOT NULL,
trusted BOOLEAN DEFAULT FALSE,
last_seen TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(user_id, device_fingerprint)
);
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_devices_user ON device_registry(user_id);
```
### Down Migration
```sql
-- R001_20240110120000_create_core_auth.sql
DROP TABLE device_registry;
DROP TABLE users;
```
---
## Migration V002: Family Structure
### Up Migration
```sql
-- V002_20240110130000_create_family_structure.sql
CREATE TABLE families (
id VARCHAR(20) PRIMARY KEY DEFAULT ('fam_' || nanoid()),
name VARCHAR(100),
share_code VARCHAR(10) UNIQUE DEFAULT upper(substr(md5(random()::text), 1, 6)),
created_by VARCHAR(20) REFERENCES users(id),
subscription_tier VARCHAR(20) DEFAULT 'free',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE family_members (
user_id VARCHAR(20) REFERENCES users(id) ON DELETE CASCADE,
family_id VARCHAR(20) REFERENCES families(id) ON DELETE CASCADE,
role VARCHAR(20) NOT NULL CHECK (role IN ('parent', 'caregiver', 'viewer')),
permissions JSONB DEFAULT '{"canAddChildren": false, "canEditChildren": false, "canLogActivities": true, "canViewReports": true}'::jsonb,
joined_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (user_id, family_id)
);
CREATE TABLE children (
id VARCHAR(20) PRIMARY KEY DEFAULT ('chd_' || nanoid()),
family_id VARCHAR(20) NOT NULL REFERENCES families(id) ON DELETE CASCADE,
name VARCHAR(100) NOT NULL,
birth_date DATE NOT NULL,
gender VARCHAR(20),
photo_url TEXT,
medical_info JSONB DEFAULT '{}'::jsonb,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP
);
CREATE INDEX idx_families_share_code ON families(share_code);
CREATE INDEX idx_family_members_family ON family_members(family_id);
CREATE INDEX idx_children_family ON children(family_id);
CREATE INDEX idx_children_active ON children(deleted_at) WHERE deleted_at IS NULL;
```
---
## Migration V003: Activity Tracking Tables
### Up Migration
```sql
-- V003_20240110140000_create_activity_tracking.sql
CREATE TABLE activities (
id VARCHAR(20) PRIMARY KEY DEFAULT ('act_' || nanoid()),
child_id VARCHAR(20) NOT NULL REFERENCES children(id) ON DELETE CASCADE,
type VARCHAR(20) NOT NULL CHECK (type IN ('feeding', 'sleep', 'diaper', 'growth', 'medication', 'temperature')),
started_at TIMESTAMP NOT NULL,
ended_at TIMESTAMP,
logged_by VARCHAR(20) NOT NULL REFERENCES users(id),
notes TEXT,
metadata JSONB DEFAULT '{}'::jsonb,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Partitioned by month for scalability
CREATE TABLE activities_2024_01 PARTITION OF activities
FOR VALUES FROM ('2024-01-01') TO ('2024-02-01');
CREATE INDEX idx_activities_child_time ON activities(child_id, started_at DESC);
CREATE INDEX idx_activities_type ON activities(type, started_at DESC);
CREATE INDEX idx_activities_metadata ON activities USING gin(metadata);
```
---
## Migration V004: AI and Analytics Tables
### Up Migration
```sql
-- V004_20240110150000_create_ai_analytics.sql
CREATE TABLE conversations (
id VARCHAR(20) PRIMARY KEY DEFAULT ('conv_' || nanoid()),
user_id VARCHAR(20) NOT NULL REFERENCES users(id) ON DELETE CASCADE,
child_id VARCHAR(20) REFERENCES children(id) ON DELETE CASCADE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
last_message_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE messages (
id VARCHAR(20) PRIMARY KEY DEFAULT ('msg_' || nanoid()),
conversation_id VARCHAR(20) NOT NULL REFERENCES conversations(id) ON DELETE CASCADE,
role VARCHAR(20) NOT NULL CHECK (role IN ('user', 'assistant')),
content TEXT NOT NULL,
metadata JSONB DEFAULT '{}'::jsonb,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE patterns (
id VARCHAR(20) PRIMARY KEY DEFAULT ('pat_' || nanoid()),
child_id VARCHAR(20) NOT NULL REFERENCES children(id) ON DELETE CASCADE,
type VARCHAR(50) NOT NULL,
pattern_data JSONB NOT NULL,
confidence DECIMAL(3,2),
detected_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
expires_at TIMESTAMP
);
CREATE TABLE predictions (
id VARCHAR(20) PRIMARY KEY DEFAULT ('prd_' || nanoid()),
child_id VARCHAR(20) NOT NULL REFERENCES children(id) ON DELETE CASCADE,
type VARCHAR(50) NOT NULL,
predicted_time TIMESTAMP NOT NULL,
confidence DECIMAL(3,2),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
outcome VARCHAR(20) -- 'correct', 'incorrect', 'pending'
);
CREATE INDEX idx_conversations_user ON conversations(user_id);
CREATE INDEX idx_messages_conversation ON messages(conversation_id);
CREATE INDEX idx_patterns_child_type ON patterns(child_id, type);
CREATE INDEX idx_predictions_child_time ON predictions(child_id, predicted_time);
```
---
## Migration V005: Performance Optimization Indexes
### Up Migration
```sql
-- V005_20240110160000_add_performance_indexes.sql
-- Composite indexes for common queries
CREATE INDEX idx_activities_daily_summary
ON activities(child_id, type, started_at)
WHERE ended_at IS NOT NULL;
CREATE INDEX idx_patterns_active
ON patterns(child_id, type, confidence)
WHERE expires_at > CURRENT_TIMESTAMP;
-- Text search for notes
CREATE INDEX idx_activities_notes_search
ON activities USING gin(to_tsvector('english', notes));
-- Covering index for dashboard query
CREATE INDEX idx_children_dashboard
ON children(family_id, id, name, birth_date)
WHERE deleted_at IS NULL;
```
---
## Migration V006: Notification System
### Up Migration
```sql
-- V006_20240110170000_create_notifications.sql
CREATE TABLE notification_preferences (
user_id VARCHAR(20) PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE,
push_enabled BOOLEAN DEFAULT true,
email_enabled BOOLEAN DEFAULT true,
quiet_hours_start TIME,
quiet_hours_end TIME,
preferences JSONB DEFAULT '{}'::jsonb
);
CREATE TABLE scheduled_notifications (
id VARCHAR(20) PRIMARY KEY DEFAULT ('ntf_' || nanoid()),
user_id VARCHAR(20) NOT NULL REFERENCES users(id) ON DELETE CASCADE,
child_id VARCHAR(20) REFERENCES children(id) ON DELETE CASCADE,
type VARCHAR(50) NOT NULL,
scheduled_for TIMESTAMP NOT NULL,
payload JSONB NOT NULL,
sent_at TIMESTAMP,
status VARCHAR(20) DEFAULT 'pending'
);
CREATE INDEX idx_notifications_pending
ON scheduled_notifications(scheduled_for, status)
WHERE status = 'pending';
```
---
## Migration V007: Audit and Compliance
### Up Migration
```sql
-- V007_20240110180000_create_audit_compliance.sql
CREATE TABLE audit_log (
id BIGSERIAL PRIMARY KEY,
user_id VARCHAR(20),
action VARCHAR(50) NOT NULL,
entity_type VARCHAR(50),
entity_id VARCHAR(20),
changes JSONB,
ip_address INET,
user_agent TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE data_deletion_requests (
id VARCHAR(20) PRIMARY KEY DEFAULT ('del_' || nanoid()),
user_id VARCHAR(20) NOT NULL REFERENCES users(id),
requested_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
scheduled_for TIMESTAMP NOT NULL DEFAULT (CURRENT_TIMESTAMP + INTERVAL '30 days'),
completed_at TIMESTAMP,
status VARCHAR(20) DEFAULT 'pending'
);
-- Partition audit_log by month for retention management
CREATE TABLE audit_log_2024_01 PARTITION OF audit_log
FOR VALUES FROM ('2024-01-01') TO ('2024-02-01');
CREATE INDEX idx_audit_user_action ON audit_log(user_id, action, created_at DESC);
```
---
## Seed Data Script
```sql
-- seed_development_data.sql
-- Test users
INSERT INTO users (id, email, password_hash, name, locale) VALUES
('usr_test1', 'test1@example.com', '$2b$10$...', 'Test Parent 1', 'en-US'),
('usr_test2', 'test2@example.com', '$2b$10$...', 'Test Parent 2', 'es-ES');
-- Test family
INSERT INTO families (id, name, created_by, share_code) VALUES
('fam_test', 'Test Family', 'usr_test1', 'TEST01');
-- Family members
INSERT INTO family_members (user_id, family_id, role, permissions) VALUES
('usr_test1', 'fam_test', 'parent', '{"canAddChildren": true, "canEditChildren": true, "canLogActivities": true, "canViewReports": true}'::jsonb),
('usr_test2', 'fam_test', 'parent', '{"canAddChildren": true, "canEditChildren": true, "canLogActivities": true, "canViewReports": true}'::jsonb);
-- Test children
INSERT INTO children (id, family_id, name, birth_date, gender) VALUES
('chd_test1', 'fam_test', 'Emma', '2023-06-15', 'female'),
('chd_test2', 'fam_test', 'Liam', '2021-03-22', 'male');
```
---
## Migration Runner Configuration
### TypeORM Configuration
```typescript
// ormconfig.ts
export default {
type: 'postgres',
host: process.env.DB_HOST,
port: 5432,
database: process.env.DB_NAME,
migrations: ['src/migrations/*.sql'],
cli: {
migrationsDir: 'src/migrations'
}
};
```
### Knex Configuration
```javascript
// knexfile.js
module.exports = {
development: {
client: 'postgresql',
connection: process.env.DATABASE_URL,
migrations: {
directory: './migrations',
tableName: 'schema_migrations'
}
}
};
```
---
## Database Maintenance Scripts
### Weekly Vacuum
```sql
-- maintenance/weekly_vacuum.sql
VACUUM ANALYZE activities;
VACUUM ANALYZE patterns;
VACUUM ANALYZE predictions;
```
### Monthly Partition Creation
```sql
-- maintenance/create_next_month_partition.sql
CREATE TABLE IF NOT EXISTS activities_2024_02
PARTITION OF activities
FOR VALUES FROM ('2024-02-01') TO ('2024-03-01');
```
### Archive Old Data
```sql
-- maintenance/archive_old_activities.sql
INSERT INTO activities_archive
SELECT * FROM activities
WHERE started_at < CURRENT_DATE - INTERVAL '1 year';
DELETE FROM activities
WHERE started_at < CURRENT_DATE - INTERVAL '1 year';
```
---
## Rollback Procedures
### Full Rollback Script
```bash
#!/bin/bash
# rollback.sh
VERSION=$1
psql $DATABASE_URL -f "migrations/rollback/R${VERSION}.sql"
DELETE FROM schema_migrations WHERE version = $VERSION;
```
### Emergency Recovery
```sql
-- emergency_recovery.sql
-- Point-in-time recovery to specific timestamp
SELECT pg_restore_point('before_migration');
-- Restore from backup if catastrophic failure
```
---
## Performance Considerations
### Index Strategy
- Primary indexes on foreign keys
- Composite indexes for common query patterns
- Partial indexes for active records
- GIN indexes for JSONB search
- Covering indexes for dashboard queries
### Partitioning Strategy
- Activities table partitioned by month
- Audit log partitioned by month
- Automatic partition creation via cron job
### Connection Pooling
```sql
-- Recommended PostgreSQL settings
max_connections = 200
shared_buffers = 256MB
effective_cache_size = 1GB
work_mem = 4MB
```

View File

@@ -0,0 +1,586 @@
# UI/UX Design System - Maternal Organization App
## Design Philosophy
### Core Principles
- **Calm Clarity**: Modern minimalist approach reducing cognitive load
- **Warm Touch**: Nurturing colors and gentle interactions providing emotional comfort
- **One-Handed First**: All critical actions accessible within thumb reach
- **Interruption-Resilient**: Every interaction can be abandoned and resumed
- **Inclusive by Default**: WCAG AA/AAA compliance throughout
---
## Color System
### Primary Palette
```css
/* Warm Nurturing Colors */
--primary-peach: #FFB5A0;
--primary-coral: #FF8B7D;
--primary-rose: #FFD4CC;
--primary-blush: #FFF0ED;
/* Semantic Colors */
--success-sage: #7FB069;
--warning-amber: #F4A259;
--error-soft: #E07A5F;
--info-sky: #81C3D7;
/* Neutral Scale */
--neutral-900: #1A1A1A; /* Primary text */
--neutral-700: #404040; /* Secondary text */
--neutral-500: #737373; /* Disabled text */
--neutral-300: #D4D4D4; /* Borders */
--neutral-100: #F5F5F5; /* Backgrounds */
--neutral-50: #FAFAFA; /* Surface */
--white: #FFFFFF;
```
### Dark Mode Palette
```css
/* Dark Mode Adjustments */
--dark-surface: #1E1E1E;
--dark-elevated: #2A2A2A;
--dark-primary: #FFB5A0; /* Same warm colors */
--dark-text-primary: #F5F5F5;
--dark-text-secondary: #B8B8B8;
--dark-border: #404040;
```
### Color Usage Guidelines
- **Primary actions**: `--primary-coral`
- **Secondary actions**: `--primary-peach`
- **Backgrounds**: `--primary-blush` (10% opacity overlays)
- **Success states**: `--success-sage`
- **Warnings**: `--warning-amber`
- **Errors**: `--error-soft` (gentler than harsh red)
---
## Typography
### Font Families
```css
/* Sans-serif for UI elements */
--font-ui: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
/* Serif for content and insights */
--font-content: 'Crimson Pro', 'Georgia', serif;
/* Monospace for data */
--font-mono: 'JetBrains Mono', 'SF Mono', monospace;
```
### Type Scale (Material Design)
```css
/* Headlines */
--headline-1: 96px, light, -1.5px; /* Not used in mobile */
--headline-2: 60px, light, -0.5px; /* Not used in mobile */
--headline-3: 48px, regular, 0px; /* Not used in mobile */
--headline-4: 34px, regular, 0.25px; /* Screen titles */
--headline-5: 24px, regular, 0px; /* Section headers */
--headline-6: 20px, medium, 0.15px; /* Card titles */
/* Body Text */
--body-1: 16px, regular, 0.5px, 1.5 line-height; /* Main content */
--body-2: 14px, regular, 0.25px, 1.43 line-height; /* Secondary content */
/* Supporting Text */
--subtitle-1: 16px, medium, 0.15px; /* List items */
--subtitle-2: 14px, medium, 0.1px; /* Sub-headers */
--button: 14px, medium, 1.25px, uppercase;
--caption: 12px, regular, 0.4px; /* Timestamps, labels */
--overline: 10px, regular, 1.5px, uppercase;
```
### Mobile-Optimized Sizes
```css
/* Minimum touch target: 44x44px (iOS) / 48x48dp (Android) */
--text-minimum: 14px; /* Never smaller */
--text-comfortable: 16px; /* Default body */
--text-large: 18px; /* Easy reading */
```
---
## Spacing System
### Base Unit: 8px Grid
```css
--space-0: 0px;
--space-1: 8px;
--space-2: 16px;
--space-3: 24px;
--space-4: 32px;
--space-5: 40px;
--space-6: 48px;
--space-8: 64px;
--space-10: 80px;
```
### Component Spacing
```css
/* Padding */
--padding-button: 16px 24px;
--padding-card: 16px;
--padding-screen: 16px;
--padding-input: 12px 16px;
/* Margins */
--margin-section: 32px;
--margin-element: 16px;
--margin-text: 8px;
```
---
## Layout Grid
### Mobile Layout
```css
/* Screen Breakpoints */
--screen-small: 320px; /* iPhone SE */
--screen-medium: 375px; /* iPhone 12/13 */
--screen-large: 414px; /* iPhone Plus/Pro Max */
--screen-tablet: 768px; /* iPad */
/* Content Zones */
.safe-area {
padding-top: env(safe-area-inset-top);
padding-bottom: env(safe-area-inset-bottom);
}
.thumb-zone {
/* Bottom 60% of screen */
position: fixed;
bottom: 0;
height: 60vh;
}
```
### One-Handed Reachability Map
```
┌─────────────────────┐
│ Hard to reach │ 20%
├─────────────────────┤
│ Moderate reach │ 20%
├─────────────────────┤
│ Easy reach │ 30%
├─────────────────────┤
│ Natural reach │ 30%
│ (Thumb zone) │
└─────────────────────┘
```
---
## Component Specifications
### Buttons
#### Primary Button
```css
.button-primary {
background: var(--primary-coral);
color: white;
border-radius: 24px; /* Pill shape */
padding: 16px 32px;
min-height: 48px; /* Touch target */
font: var(--button);
box-shadow: 0 4px 8px rgba(255, 139, 125, 0.3);
}
```
#### Floating Action Button (FAB)
```css
.fab {
position: fixed;
bottom: 80px; /* Above navigation */
right: 16px;
width: 56px;
height: 56px;
border-radius: 28px;
background: var(--primary-coral);
box-shadow: 0 6px 12px rgba(0,0,0,0.15);
}
```
### Cards (Material Design)
```css
.card {
background: var(--white);
border-radius: 16px; /* Softer than Material default */
padding: var(--padding-card);
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
margin-bottom: var(--space-2);
}
.card-dark {
background: var(--dark-elevated);
box-shadow: 0 2px 8px rgba(0,0,0,0.3);
}
```
### Input Fields
```css
.input-field {
background: var(--neutral-50);
border: 2px solid transparent;
border-radius: 12px;
padding: var(--padding-input);
font-size: 16px; /* Prevents zoom on iOS */
min-height: 48px;
transition: all 0.2s ease;
}
.input-field:focus {
border-color: var(--primary-peach);
background: var(--white);
}
```
### Bottom Navigation
```css
.bottom-nav {
position: fixed;
bottom: 0;
width: 100%;
height: 64px;
background: var(--white);
box-shadow: 0 -2px 8px rgba(0,0,0,0.1);
display: flex;
justify-content: space-around;
padding-bottom: env(safe-area-inset-bottom);
}
.nav-item {
min-width: 64px;
display: flex;
flex-direction: column;
align-items: center;
padding: 8px;
}
```
---
## Icon System
### Icon Library: Material Icons Outlined
```css
/* Sizes */
--icon-small: 20px;
--icon-medium: 24px; /* Default */
--icon-large: 32px;
--icon-xlarge: 48px;
/* Styles */
.icon {
stroke-width: 1.5px;
color: var(--neutral-700);
}
.icon-primary {
color: var(--primary-coral);
}
```
### Core Icon Set
```
Navigation:
- home_outlined
- calendar_month_outlined
- insights_outlined
- chat_bubble_outline
- person_outline
Actions:
- add_circle_outline
- mic_outlined
- camera_outlined
- timer_outlined
- check_circle_outline
Tracking:
- baby_changing_station_outlined
- bed_outlined
- restaurant_outlined
- straighten_outlined (growth)
- medical_services_outlined
```
---
## Interaction Patterns
### Touch Targets
```css
/* Minimum touch target size */
.touchable {
min-width: 44px; /* iOS HIG */
min-height: 44px;
padding: 12px; /* Extends touch area */
}
```
### Gesture Support
```javascript
/* Swipe Actions */
- Swipe left: Delete/Archive
- Swipe right: Edit/Complete
- Pull down: Refresh
- Long press: Context menu
- Pinch: Zoom charts
```
### Loading States
```css
/* Skeleton Screens */
.skeleton {
background: linear-gradient(
90deg,
var(--neutral-100) 25%,
var(--neutral-50) 50%,
var(--neutral-100) 75%
);
background-size: 200% 100%;
animation: loading 1.5s infinite;
}
/* Spinner for actions */
.spinner {
width: 24px;
height: 24px;
border: 3px solid var(--primary-rose);
border-top-color: var(--primary-coral);
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
```
### Micro-Animations
```css
/* Gentle transitions */
* {
transition-duration: 0.2s;
transition-timing-function: ease-out;
}
/* Success feedback */
@keyframes success-pulse {
0% { transform: scale(1); }
50% { transform: scale(1.05); }
100% { transform: scale(1); }
}
```
---
## Accessibility Specifications
### WCAG Compliance
```css
/* Contrast Ratios */
--contrast-normal: 4.5:1; /* AA standard */
--contrast-large: 3:1; /* AA for large text */
--contrast-enhanced: 7:1; /* AAA standard */
/* Focus Indicators */
:focus-visible {
outline: 3px solid var(--primary-coral);
outline-offset: 2px;
}
```
### Screen Reader Support
```html
<!-- Proper ARIA labels -->
<button aria-label="Log feeding" aria-pressed="false">
<icon name="restaurant_outlined" aria-hidden="true" />
</button>
<!-- Live regions for updates -->
<div role="status" aria-live="polite" aria-atomic="true">
Activity logged successfully
</div>
```
### Reduced Motion
```css
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
```
---
## Platform-Specific Adaptations
### Material You (Android 12+)
```kotlin
// Dynamic color extraction
MaterialTheme(
colorScheme = dynamicColorScheme ?: customColorScheme,
typography = AppTypography,
content = content
)
```
### iOS Adaptations
```swift
// Haptic feedback
UIImpactFeedbackGenerator(style: .light).impactOccurred()
// Safe area handling
.edgesIgnoringSafeArea(.bottom)
```
---
## Dark Mode Implementation
### Automatic Switching
```javascript
// React Native
import { useColorScheme } from 'react-native';
const ColorScheme = {
light: {
background: '#FFFFFF',
text: '#1A1A1A',
primary: '#FF8B7D'
},
dark: {
background: '#1E1E1E',
text: '#F5F5F5',
primary: '#FFB5A0'
}
};
```
### Theme Provider
```typescript
// Material-UI Theme
const theme = createTheme({
palette: {
mode: systemPreference,
primary: {
main: '#FF8B7D',
},
background: {
default: mode === 'dark' ? '#1E1E1E' : '#FFFFFF',
},
},
typography: {
fontFamily: ['Inter', 'sans-serif'].join(','),
},
shape: {
borderRadius: 12,
},
});
```
---
## Component States
### Interactive States
```css
/* Default */
.button { opacity: 1; }
/* Hover (web) */
.button:hover { opacity: 0.9; }
/* Active/Pressed */
.button:active { transform: scale(0.98); }
/* Disabled */
.button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
/* Loading */
.button.loading {
pointer-events: none;
color: transparent;
}
```
### Form Validation States
```css
.input-success {
border-color: var(--success-sage);
}
.input-error {
border-color: var(--error-soft);
background-color: rgba(224, 122, 95, 0.05);
}
.helper-text {
font-size: 12px;
color: var(--neutral-700);
margin-top: 4px;
}
```
---
## Quick Action Design
### Bottom Sheet Actions
```css
.quick-actions {
position: fixed;
bottom: 80px; /* Above nav */
left: 50%;
transform: translateX(-50%);
display: flex;
gap: 16px;
padding: 16px;
background: var(--white);
border-radius: 24px;
box-shadow: 0 8px 24px rgba(0,0,0,0.15);
}
.quick-action-button {
width: 64px;
height: 64px;
border-radius: 32px;
display: flex;
align-items: center;
justify-content: center;
background: var(--primary-blush);
}
```
---
## Performance Guidelines
### Image Optimization
- Maximum image size: 200KB
- Lazy loading for all images
- WebP format with JPG fallback
- Thumbnail generation for avatars
### Animation Performance
- Use transform and opacity only
- 60fps target for all animations
- GPU acceleration for transitions
- Avoid animating during scroll
### Font Loading
```css
@font-face {
font-family: 'Inter';
font-display: swap; /* Show fallback immediately */
src: url('/fonts/Inter.woff2') format('woff2');
}
```

View File

@@ -0,0 +1,507 @@
# Environment Configuration Guide - Maternal Organization App
## Environment Structure
### Environment Types
- **Development** (`dev`): Local development with hot reload
- **Staging** (`staging`): Pre-production testing environment
- **Production** (`prod`): Live application environment
- **Testing** (`test`): Automated testing environment
---
## Backend Environment Variables (.env)
### Core Configuration
```bash
# Application
NODE_ENV=development
APP_NAME=MaternalApp
APP_VERSION=1.0.0
API_VERSION=v1
PORT=3000
HOST=localhost
# URLs
BACKEND_URL=http://localhost:3000
FRONTEND_URL=http://localhost:8081
WEBSOCKET_URL=ws://localhost:3000
```
### Database Configuration
```bash
# PostgreSQL Primary
DATABASE_URL=postgresql://user:password@localhost:5432/maternal_app
DB_HOST=localhost
DB_PORT=5432
DB_NAME=maternal_app
DB_USER=maternal_user
DB_PASSWORD=secure_password_here
DB_SSL=false
DB_POOL_MIN=2
DB_POOL_MAX=10
# MongoDB (AI Chat History)
MONGODB_URI=mongodb://localhost:27017/maternal_ai
MONGODB_DB=maternal_ai
# Redis
REDIS_URL=redis://localhost:6379
REDIS_PASSWORD=
REDIS_DB=0
REDIS_CACHE_TTL=3600
```
### Authentication & Security
```bash
# JWT Configuration
JWT_SECRET=your-256-bit-secret-key-here
JWT_REFRESH_SECRET=different-256-bit-secret-key-here
JWT_EXPIRES_IN=1h
JWT_REFRESH_EXPIRES_IN=30d
# Encryption
ENCRYPTION_KEY=32-character-encryption-key-here
ENCRYPTION_IV=16-character-iv-here
# Device Fingerprinting
FINGERPRINT_SECRET=device-fingerprint-secret-key
# Rate Limiting
RATE_LIMIT_WINDOW_MS=60000
RATE_LIMIT_MAX_REQUESTS=100
```
### AI Services
```bash
# OpenAI
OPENAI_API_KEY=sk-your-openai-api-key
OPENAI_MODEL=gpt-4
OPENAI_TEMPERATURE=0.7
OPENAI_MAX_TOKENS=1000
# Anthropic Claude (Alternative)
ANTHROPIC_API_KEY=sk-ant-your-anthropic-key
ANTHROPIC_MODEL=claude-3-opus-20240229
# Whisper (Voice Recognition)
WHISPER_API_KEY=your-whisper-api-key
WHISPER_MODEL=whisper-1
# LangChain
LANGCHAIN_TRACING_V2=true
LANGCHAIN_API_KEY=your-langchain-api-key
LANGCHAIN_PROJECT=maternal-app
```
### External Services
```bash
# Email Service (SendGrid)
SENDGRID_API_KEY=SG.your-sendgrid-api-key
SENDGRID_FROM_EMAIL=support@maternalapp.com
SENDGRID_FROM_NAME=Maternal App
# Push Notifications
FCM_SERVER_KEY=your-firebase-server-key
FCM_PROJECT_ID=maternal-app-prod
APNS_KEY_ID=your-apple-key-id
APNS_TEAM_ID=your-apple-team-id
# File Storage (MinIO/S3)
S3_ENDPOINT=http://localhost:9000
S3_ACCESS_KEY=minioadmin
S3_SECRET_KEY=minioadmin
S3_BUCKET=maternal-uploads
S3_REGION=us-east-1
S3_USE_SSL=false
# Monitoring
SENTRY_DSN=https://your-sentry-dsn@sentry.io/project-id
SENTRY_ENVIRONMENT=development
SENTRY_TRACES_SAMPLE_RATE=0.1
```
### Compliance & Analytics
```bash
# COPPA/GDPR
COPPA_VERIFICATION_REQUIRED=true
GDPR_ENABLED=true
DATA_RETENTION_DAYS=365
AUDIT_LOG_ENABLED=true
# Analytics
MIXPANEL_TOKEN=your-mixpanel-token
GA_TRACKING_ID=G-XXXXXXXXXX
POSTHOG_API_KEY=your-posthog-key
POSTHOG_HOST=https://app.posthog.com
```
---
## Frontend Environment Variables (.env)
### React Native Configuration
```bash
# API Configuration
REACT_APP_API_BASE_URL=http://localhost:3000/api/v1
REACT_APP_GRAPHQL_URL=http://localhost:3000/graphql
REACT_APP_WS_URL=ws://localhost:3000/ws
# Feature Flags
REACT_APP_ENABLE_VOICE=true
REACT_APP_ENABLE_AI_CHAT=true
REACT_APP_ENABLE_DARK_MODE=true
REACT_APP_ENABLE_OFFLINE=true
REACT_APP_MAX_CHILDREN_FREE=2
REACT_APP_AI_QUERIES_FREE=10
# App Configuration
REACT_APP_NAME=Maternal
REACT_APP_VERSION=1.0.0
REACT_APP_BUILD_NUMBER=1
REACT_APP_BUNDLE_ID=com.maternalapp.app
```
### Platform-Specific (iOS)
```bash
# iOS Configuration
IOS_APP_ID=1234567890
IOS_TEAM_ID=XXXXXXXXXX
IOS_PROVISIONING_PROFILE=maternal-app-dev
APPLE_SIGN_IN_SERVICE_ID=com.maternalapp.signin
```
### Platform-Specific (Android)
```bash
# Android Configuration
ANDROID_PACKAGE_NAME=com.maternalapp.app
ANDROID_KEYSTORE_PATH=./android/app/maternal.keystore
ANDROID_KEY_ALIAS=maternal-key
ANDROID_KEYSTORE_PASSWORD=keystore-password
ANDROID_KEY_PASSWORD=key-password
```
---
## Docker Environment Configuration
### docker-compose.yml
```yaml
version: '3.8'
services:
postgres:
image: postgres:15-alpine
environment:
POSTGRES_DB: ${DB_NAME}
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
redis:
image: redis:7-alpine
command: redis-server --requirepass ${REDIS_PASSWORD}
ports:
- "6379:6379"
mongodb:
image: mongo:6
environment:
MONGO_INITDB_DATABASE: maternal_ai
volumes:
- mongo_data:/data/db
ports:
- "27017:27017"
minio:
image: minio/minio
command: server /data --console-address ":9001"
environment:
MINIO_ROOT_USER: ${S3_ACCESS_KEY}
MINIO_ROOT_PASSWORD: ${S3_SECRET_KEY}
volumes:
- minio_data:/data
ports:
- "9000:9000"
- "9001:9001"
volumes:
postgres_data:
mongo_data:
minio_data:
```
---
## Secret Management
### Development Secrets (.env.local)
```bash
# Never commit this file
# Copy from .env.example and fill with real values
cp .env.example .env.local
```
### Production Secrets (AWS Secrets Manager)
```bash
# Store production secrets in AWS Secrets Manager
aws secretsmanager create-secret \
--name maternal-app/production \
--secret-string file://secrets.json
# Retrieve secrets in application
aws secretsmanager get-secret-value \
--secret-id maternal-app/production
```
### Kubernetes Secrets
```yaml
apiVersion: v1
kind: Secret
metadata:
name: maternal-app-secrets
type: Opaque
data:
jwt-secret: <base64-encoded-secret>
database-url: <base64-encoded-url>
openai-api-key: <base64-encoded-key>
```
---
## Environment File Templates
### .env.example (Commit to repo)
```bash
# Copy this file to .env.local and fill in values
NODE_ENV=development
PORT=3000
# Database
DATABASE_URL=postgresql://user:password@localhost:5432/maternal_app
# Add all variables with placeholder values...
JWT_SECRET=change-this-to-random-256-bit-key
OPENAI_API_KEY=sk-your-api-key-here
```
### .env.test (Testing)
```bash
NODE_ENV=test
DATABASE_URL=postgresql://test:test@localhost:5432/maternal_test
REDIS_URL=redis://localhost:6380
JWT_SECRET=test-jwt-secret-not-for-production
```
---
## Platform-Specific Configuration
### iOS Info.plist Additions
```xml
<key>API_BASE_URL</key>
<string>$(API_BASE_URL)</string>
<key>NSMicrophoneUsageDescription</key>
<string>Voice input for hands-free logging</string>
<key>NSCameraUsageDescription</key>
<string>Take photos of your child</string>
```
### Android gradle.properties
```properties
API_BASE_URL=http://10.0.2.2:3000/api/v1
ENABLE_VOICE_INPUT=true
ENABLE_PROGUARD=false
```
---
## Configuration Loading Order
### Backend (Node.js)
```javascript
// config/index.ts
import dotenv from 'dotenv';
// Load in order of precedence
dotenv.config({ path: '.env.local' }); // Local overrides
dotenv.config({ path: `.env.${NODE_ENV}` }); // Environment specific
dotenv.config(); // Default values
export const config = {
app: {
name: process.env.APP_NAME || 'MaternalApp',
version: process.env.APP_VERSION || '1.0.0',
env: process.env.NODE_ENV || 'development',
},
// ... rest of config
};
```
### Frontend (React Native)
```javascript
// config/env.js
import Config from 'react-native-config';
export const ENV = {
dev: {
API_URL: 'http://localhost:3000/api/v1',
WS_URL: 'ws://localhost:3000/ws',
},
staging: {
API_URL: 'https://staging-api.maternalapp.com/api/v1',
WS_URL: 'wss://staging-api.maternalapp.com/ws',
},
prod: {
API_URL: 'https://api.maternalapp.com/api/v1',
WS_URL: 'wss://api.maternalapp.com/ws',
},
}[Config.ENV || 'dev'];
```
---
## Security Best Practices
### Secret Rotation Schedule
- **JWT Secrets**: Every 90 days
- **API Keys**: Every 180 days
- **Database Passwords**: Every 60 days
- **Encryption Keys**: Every year
### Environment Variable Validation
```typescript
// validateEnv.ts
import { cleanEnv, str, port, url, bool, num } from 'envalid';
export const env = cleanEnv(process.env, {
NODE_ENV: str({ choices: ['development', 'test', 'staging', 'production'] }),
PORT: port(),
DATABASE_URL: url(),
JWT_SECRET: str({ minLength: 32 }),
OPENAI_API_KEY: str(),
RATE_LIMIT_MAX_REQUESTS: num({ default: 100 }),
});
```
### Git Security
```bash
# .gitignore
.env
.env.*
!.env.example
secrets/
*.key
*.pem
*.p12
```
---
## Deployment Configuration
### Heroku
```json
// app.json
{
"env": {
"NODE_ENV": {
"value": "production"
},
"DATABASE_URL": {
"required": true
},
"JWT_SECRET": {
"generator": "secret"
}
}
}
```
### Docker Build Args
```dockerfile
ARG NODE_ENV=production
ARG API_VERSION=v1
ENV NODE_ENV=${NODE_ENV}
ENV API_VERSION=${API_VERSION}
```
### CI/CD Variables (GitHub Actions)
```yaml
env:
NODE_ENV: production
DATABASE_URL: ${{ secrets.DATABASE_URL }}
JWT_SECRET: ${{ secrets.JWT_SECRET }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
```
---
## Monitoring & Debugging
### Debug Configuration
```bash
# Development debugging
DEBUG=maternal:*
LOG_LEVEL=debug
PRETTY_LOGS=true
# Production
LOG_LEVEL=info
LOG_FORMAT=json
```
### Health Check Variables
```bash
HEALTH_CHECK_INTERVAL=30000
HEALTH_CHECK_TIMEOUT=3000
HEALTH_CHECK_PATH=/health
```
---
## Quick Start Commands
### Local Development Setup
```bash
# 1. Copy environment template
cp .env.example .env.local
# 2. Start Docker services
docker-compose up -d
# 3. Run migrations
npm run migrate:up
# 4. Seed development data
npm run seed:dev
# 5. Start development server
npm run dev
```
### Environment Verification
```bash
# Check all required variables are set
npm run env:validate
# Display current configuration (masked)
npm run env:debug
```
---
## Troubleshooting
### Common Issues
1. **Missing API Keys**: Ensure all AI service keys are valid
2. **Database Connection**: Check DATABASE_URL format and credentials
3. **Redis Connection**: Verify Redis is running and accessible
4. **CORS Issues**: Confirm FRONTEND_URL is correctly set
5. **WebSocket Failures**: Check WS_URL matches backend configuration

View File

@@ -0,0 +1,588 @@
# Error Handling & Logging Standards - Maternal Organization App
## Error Philosophy
### Core Principles
- **Parent-Friendly Messages**: Never show technical jargon to users
- **Graceful Degradation**: App remains usable even with errors
- **Recovery Guidance**: Always suggest next steps
- **Preserve User Work**: Never lose unsaved data due to errors
- **Privacy First**: Never log sensitive data (PII, health info)
---
## Error Code Hierarchy
### Error Code Structure
Format: `[CATEGORY]_[SPECIFIC_ERROR]`
### Categories
```typescript
enum ErrorCategory {
AUTH = 'AUTH', // Authentication/Authorization
VALIDATION = 'VAL', // Input validation
SYNC = 'SYNC', // Synchronization issues
NETWORK = 'NET', // Network/connectivity
DATA = 'DATA', // Database/storage
AI = 'AI', // AI service errors
LIMIT = 'LIMIT', // Rate limiting/quotas
PAYMENT = 'PAY', // Subscription/payment
SYSTEM = 'SYS', // System/internal errors
COMPLIANCE = 'COMP' // COPPA/GDPR compliance
}
```
### Complete Error Code Registry
```typescript
export const ErrorCodes = {
// Authentication
AUTH_INVALID_CREDENTIALS: 'AUTH_001',
AUTH_TOKEN_EXPIRED: 'AUTH_002',
AUTH_TOKEN_INVALID: 'AUTH_003',
AUTH_DEVICE_NOT_TRUSTED: 'AUTH_004',
AUTH_MFA_REQUIRED: 'AUTH_005',
AUTH_ACCOUNT_LOCKED: 'AUTH_006',
// Validation
VAL_REQUIRED_FIELD: 'VAL_001',
VAL_INVALID_EMAIL: 'VAL_002',
VAL_WEAK_PASSWORD: 'VAL_003',
VAL_INVALID_DATE: 'VAL_004',
VAL_FUTURE_BIRTHDATE: 'VAL_005',
VAL_INVALID_AMOUNT: 'VAL_006',
// Sync
SYNC_CONFLICT: 'SYNC_001',
SYNC_OFFLINE_QUEUE_FULL: 'SYNC_002',
SYNC_VERSION_MISMATCH: 'SYNC_003',
SYNC_FAMILY_UPDATE_FAILED: 'SYNC_004',
// Network
NET_OFFLINE: 'NET_001',
NET_TIMEOUT: 'NET_002',
NET_SERVER_ERROR: 'NET_003',
NET_SLOW_CONNECTION: 'NET_004',
// AI
AI_SERVICE_UNAVAILABLE: 'AI_001',
AI_QUOTA_EXCEEDED: 'AI_002',
AI_INAPPROPRIATE_REQUEST: 'AI_003',
AI_CONTEXT_TOO_LARGE: 'AI_004',
// Limits
LIMIT_RATE_EXCEEDED: 'LIMIT_001',
LIMIT_CHILDREN_EXCEEDED: 'LIMIT_002',
LIMIT_FAMILY_SIZE_EXCEEDED: 'LIMIT_003',
LIMIT_STORAGE_EXCEEDED: 'LIMIT_004',
// Compliance
COMP_PARENTAL_CONSENT_REQUIRED: 'COMP_001',
COMP_AGE_VERIFICATION_FAILED: 'COMP_002',
COMP_DATA_RETENTION_EXPIRED: 'COMP_003'
};
```
---
## User-Facing Error Messages
### Message Structure
```typescript
interface UserErrorMessage {
title: string; // Brief, clear title
message: string; // Detailed explanation
action?: string; // What user should do
retryable: boolean; // Can user retry?
severity: 'info' | 'warning' | 'error';
}
```
### Localized Error Messages
```typescript
// errors/locales/en-US.json
{
"AUTH_001": {
"title": "Sign in failed",
"message": "The email or password you entered doesn't match our records.",
"action": "Please check your credentials and try again.",
"retryable": true
},
"SYNC_001": {
"title": "Update conflict",
"message": "This activity was updated by another family member.",
"action": "We've merged the changes. Please review.",
"retryable": false
},
"AI_002": {
"title": "AI assistant limit reached",
"message": "You've used all 10 free AI questions today.",
"action": "Upgrade to Premium for unlimited questions.",
"retryable": false
},
"NET_001": {
"title": "You're offline",
"message": "Don't worry! Your activities are saved locally.",
"action": "They'll sync when you're back online.",
"retryable": true
}
}
```
### Localization for Other Languages
```typescript
// errors/locales/es-ES.json
{
"AUTH_001": {
"title": "Error al iniciar sesión",
"message": "El correo o contraseña no coinciden con nuestros registros.",
"action": "Por favor verifica tus credenciales e intenta nuevamente.",
"retryable": true
}
}
// errors/locales/fr-FR.json
{
"AUTH_001": {
"title": "Échec de connexion",
"message": "L'email ou le mot de passe ne correspond pas.",
"action": "Veuillez vérifier vos identifiants et réessayer.",
"retryable": true
}
}
```
---
## Logging Strategy
### Log Levels
```typescript
enum LogLevel {
DEBUG = 0, // Development only
INFO = 1, // General information
WARN = 2, // Warning conditions
ERROR = 3, // Error conditions
FATAL = 4 // System is unusable
}
// Environment-based levels
const LOG_LEVELS = {
development: LogLevel.DEBUG,
staging: LogLevel.INFO,
production: LogLevel.WARN
};
```
### Structured Logging Format
```typescript
interface LogEntry {
timestamp: string;
level: LogLevel;
service: string;
userId?: string; // Hashed for privacy
familyId?: string; // For family-related issues
deviceId?: string; // Device fingerprint
errorCode?: string;
message: string;
context?: Record<string, any>;
stack?: string;
duration?: number; // For performance logs
correlationId: string; // Trace requests
}
// Example log entry
{
"timestamp": "2024-01-10T14:30:00.123Z",
"level": "ERROR",
"service": "ActivityService",
"userId": "hash_2n4k8m9p",
"errorCode": "SYNC_001",
"message": "Sync conflict detected",
"context": {
"activityId": "act_123",
"conflictType": "simultaneous_edit"
},
"correlationId": "req_8k3m9n2p"
}
```
### Logger Implementation
```typescript
// logger/index.ts
import winston from 'winston';
const logger = winston.createLogger({
level: process.env.LOG_LEVEL || 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.errors({ stack: true }),
winston.format.json()
),
defaultMeta: {
service: process.env.SERVICE_NAME,
version: process.env.APP_VERSION
},
transports: [
new winston.transports.Console({
format: winston.format.simple(),
silent: process.env.NODE_ENV === 'test'
}),
new winston.transports.File({
filename: 'error.log',
level: 'error'
})
]
});
// Privacy wrapper
export const log = {
info: (message: string, meta?: any) => {
logger.info(message, sanitizePII(meta));
},
error: (message: string, error: Error, meta?: any) => {
logger.error(message, {
...sanitizePII(meta),
errorMessage: error.message,
stack: error.stack
});
}
};
```
---
## Sentry Configuration
### Sentry Setup
```typescript
// sentry.config.ts
import * as Sentry from '@sentry/node';
Sentry.init({
dsn: process.env.SENTRY_DSN,
environment: process.env.NODE_ENV,
integrations: [
new Sentry.Integrations.Http({ tracing: true }),
new Sentry.Integrations.Express({ app }),
],
tracesSampleRate: process.env.NODE_ENV === 'production' ? 0.1 : 1.0,
beforeSend(event, hint) {
// Remove sensitive data
if (event.request) {
delete event.request.cookies;
delete event.request.headers?.authorization;
}
// Filter out user-caused errors
if (event.exception?.values?.[0]?.type === 'ValidationError') {
return null; // Don't send to Sentry
}
return sanitizeEvent(event);
},
ignoreErrors: [
'NetworkError',
'Request aborted',
'Non-Error promise rejection'
]
});
```
### React Native Sentry
```typescript
// Mobile sentry config
import * as Sentry from '@sentry/react-native';
Sentry.init({
dsn: process.env.SENTRY_DSN,
debug: __DEV__,
environment: __DEV__ ? 'development' : 'production',
attachScreenshot: true,
attachViewHierarchy: true,
beforeSend: (event) => {
// Don't send events in dev
if (__DEV__) return null;
// Remove sensitive context
delete event.user?.email;
delete event.contexts?.app?.device_name;
return event;
}
});
```
---
## Error Recovery Procedures
### Automatic Recovery
```typescript
// services/errorRecovery.ts
class ErrorRecoveryService {
async handleError(error: AppError): Promise<RecoveryAction> {
switch (error.code) {
case 'NET_OFFLINE':
return this.queueForOfflineSync(error.context);
case 'AUTH_TOKEN_EXPIRED':
return this.refreshToken();
case 'SYNC_CONFLICT':
return this.resolveConflict(error.context);
case 'AI_SERVICE_UNAVAILABLE':
return this.fallbackToOfflineAI();
default:
return this.defaultRecovery(error);
}
}
private async queueForOfflineSync(context: any) {
await offlineQueue.add(context);
return {
recovered: true,
message: 'Saved locally, will sync when online'
};
}
}
```
### User-Guided Recovery
```typescript
// components/ErrorBoundary.tsx
class ErrorBoundary extends React.Component {
componentDidCatch(error: Error, errorInfo: ErrorInfo) {
// Log to Sentry
Sentry.captureException(error, { contexts: { react: errorInfo } });
// Show recovery UI
this.setState({
hasError: true,
error,
recovery: this.getRecoveryOptions(error)
});
}
render() {
if (this.state.hasError) {
return (
<ErrorRecoveryScreen
title={i18n.t('error.something_went_wrong')}
message={i18n.t('error.we_are_sorry')}
actions={[
{ label: 'Try Again', onPress: this.retry },
{ label: 'Go to Dashboard', onPress: this.reset },
{ label: 'Contact Support', onPress: this.support }
]}
/>
);
}
return this.props.children;
}
}
```
---
## Audit Logging
### COPPA/GDPR Compliance Logging
```typescript
interface AuditLog {
timestamp: string;
userId: string;
action: AuditAction;
entityType: string;
entityId: string;
changes?: Record<string, any>;
ipAddress: string;
userAgent: string;
result: 'success' | 'failure';
reason?: string;
}
enum AuditAction {
// Data access
VIEW_CHILD_DATA = 'VIEW_CHILD_DATA',
EXPORT_DATA = 'EXPORT_DATA',
// Data modification
CREATE_CHILD_PROFILE = 'CREATE_CHILD_PROFILE',
UPDATE_CHILD_DATA = 'UPDATE_CHILD_DATA',
DELETE_CHILD_DATA = 'DELETE_CHILD_DATA',
// Consent
GRANT_CONSENT = 'GRANT_CONSENT',
REVOKE_CONSENT = 'REVOKE_CONSENT',
// Account
DELETE_ACCOUNT = 'DELETE_ACCOUNT',
CHANGE_PASSWORD = 'CHANGE_PASSWORD'
}
```
### Audit Log Implementation
```sql
-- Audit log table with partitioning
CREATE TABLE audit_logs (
id BIGSERIAL,
timestamp TIMESTAMP NOT NULL,
user_id VARCHAR(20),
action VARCHAR(50) NOT NULL,
entity_type VARCHAR(50),
entity_id VARCHAR(20),
changes JSONB,
ip_address INET,
user_agent TEXT,
result VARCHAR(20),
PRIMARY KEY (id, timestamp)
) PARTITION BY RANGE (timestamp);
```
---
## Performance Monitoring
### Response Time Logging
```typescript
// middleware/performanceLogger.ts
export const performanceLogger = (req: Request, res: Response, next: Next) => {
const start = Date.now();
res.on('finish', () => {
const duration = Date.now() - start;
if (duration > 1000) { // Log slow requests
logger.warn('Slow request detected', {
method: req.method,
path: req.path,
duration,
statusCode: res.statusCode
});
// Send to monitoring
metrics.histogram('request.duration', duration, {
path: req.path,
method: req.method
});
}
});
next();
};
```
---
## Alert Configuration
### Critical Alerts
```yaml
# alerts/critical.yml
alerts:
- name: high_error_rate
condition: error_rate > 5%
duration: 5m
action: page_on_call
- name: auth_failures_spike
condition: auth_failures > 100
duration: 1m
action: security_team_alert
- name: ai_service_down
condition: ai_availability < 99%
duration: 2m
action: notify_team
- name: database_connection_pool_exhausted
condition: available_connections < 5
action: scale_database
```
---
## Client-Side Error Tracking
### React Native Global Handler
```typescript
// errorHandler.ts
import { setJSExceptionHandler } from 'react-native-exception-handler';
setJSExceptionHandler((error, isFatal) => {
if (isFatal) {
logger.fatal('Fatal JS error', { error });
Alert.alert(
'Unexpected error occurred',
'The app needs to restart. Your data has been saved.',
[{ text: 'Restart', onPress: () => RNRestart.Restart() }]
);
} else {
logger.error('Non-fatal JS error', { error });
// Show toast notification
Toast.show({
type: 'error',
text1: 'Something went wrong',
text2: 'Please try again'
});
}
}, true); // Allow in production
```
---
## Error Analytics Dashboard
### Key Metrics
```typescript
interface ErrorMetrics {
errorRate: number; // Errors per 1000 requests
errorTypes: Record<string, number>; // Count by error code
affectedUsers: number; // Unique users with errors
recoveryRate: number; // % of errors recovered
meanTimeToRecovery: number; // Seconds
criticalErrors: ErrorEvent[]; // P0 errors
}
// Monitoring queries
const getErrorMetrics = async (timeRange: TimeRange): Promise<ErrorMetrics> => {
const errors = await db.query(`
SELECT
COUNT(*) as total_errors,
COUNT(DISTINCT user_id) as affected_users,
AVG(recovery_time) as mttr,
error_code,
COUNT(*) as count
FROM error_logs
WHERE timestamp > $1
GROUP BY error_code
`, [timeRange.start]);
return processMetrics(errors);
};
```
---
## Development Error Tools
### Debug Mode Enhancements
```typescript
// Development only error overlay
if (__DEV__) {
// Show detailed error information
ErrorUtils.setGlobalHandler((error, isFatal) => {
console.group('🔴 Error Details');
console.error('Error:', error.message);
console.error('Stack:', error.stack);
console.error('Component Stack:', error.componentStack);
console.error('Fatal:', isFatal);
console.groupEnd();
});
// Network request inspector
global.XMLHttpRequest = decorateXHR(global.XMLHttpRequest);
}
```

View File

@@ -0,0 +1,782 @@
# Implementation Plan - AI-Powered Maternal Organization App
## AI Coding Assistant Role Guide
### How to Use This Document with AI
Each phase specifies a role for the AI assistant to adopt, ensuring appropriate expertise and focus. When starting a new phase, instruct the AI with the specified role prompt to get optimal results.
**Example Usage:**
```
"For this phase, act as a Senior Backend Architect with expertise in NestJS and PostgreSQL. Focus on security, scalability, and proper architectural patterns."
```
-----
## Phase 0: Development Environment Setup (Week 0)
### 🤖 AI Role: Senior DevOps Engineer & System Architect
```
"Act as a Senior DevOps Engineer with expertise in Docker, PostgreSQL, Redis, and cloud infrastructure. Focus on creating a robust, scalable development environment with proper security configurations."
```
### Infrastructure Setup
```bash
# Required installations - See Technical Stack document for complete list
- Node.js 18+ LTS
- React Native CLI
- Expo CLI
- Docker & Docker Compose
- PostgreSQL 15+
- Redis 7+
- MongoDB 6+ (for AI chat history)
- MinIO (for file storage)
- Git
```
### Project Initialization
```bash
# Frontend setup - Reference Technical Stack document
npx create-expo-app maternal-app --template
cd maternal-app
npm install react-navigation react-native-paper redux-toolkit
# Additional packages from Technical Stack document
# Backend setup
nest new maternal-app-backend
cd maternal-app-backend
npm install @nestjs/websockets @nestjs/typeorm @nestjs/jwt
```
### Development Tools Configuration
- Set up ESLint, Prettier, Husky
- Configure VS Code with recommended extensions
- Initialize Git repositories with .gitignore
- **Configure environment variables** - See Environment Configuration Guide for complete .env setup
- Configure Docker Compose - Use docker-compose.yml from Environment Configuration Guide
### AI Service Setup
- **Configure AI services** - See Environment Configuration Guide for API keys
- **LangChain setup** - See AI Context & Prompting Templates document
- Rate limiting configuration (100 requests/minute per user)
-----
## Phase 1: Foundation & Authentication (Week 1-2)
### 🤖 AI Role: Senior Backend Developer & Security Expert
```
"Act as a Senior Backend Developer specializing in NestJS, PostgreSQL, and JWT authentication. Focus on security best practices, OWASP compliance, and building a scalable authentication system with device fingerprinting."
```
### 1.1 Database Schema Design
```sql
-- Use complete schema from Database Migration Scripts document
-- Run migrations V001 through V007 in sequence
-- See Database Migration Scripts for rollback procedures
```
### 1.2 Authentication System
```typescript
// Backend: NestJS Auth Module
// Complete implementation in API Specification Document - Authentication Endpoints section
@Module({
imports: [
JwtModule.register({
secret: process.env.JWT_SECRET,
signOptions: { expiresIn: '1h' }, // Access token
// Refresh token handled separately - see API Specification
}),
PassportModule,
],
providers: [AuthService, JwtStrategy, LocalStrategy],
controllers: [AuthController],
})
export class AuthModule {}
// Implement endpoints from API Specification Document:
POST /api/v1/auth/register (with device fingerprinting)
POST /api/v1/auth/login
POST /api/v1/auth/refresh
POST /api/v1/auth/logout
```
### 1.3 Mobile Authentication UI
```typescript
// React Native Screens - Follow UI/UX Design System document
// Use Material Design components and warm color palette
- SplashScreen.tsx
- OnboardingScreen.tsx
- LoginScreen.tsx (implement design from UI/UX Design System)
- RegisterScreen.tsx
- ForgotPasswordScreen.tsx
// Key components with Material Design
- BiometricLogin component
- SocialLoginButtons (Google/Apple)
- SecureTextInput component (min-height: 48px for touch targets)
```
### 1.4 Internationalization Setup
```javascript
// i18n configuration - 5 languages from MVP Features document
// See Error Handling & Logging Standards for localized error messages
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
// Language files structure
/locales
/en-US
/es-ES
/fr-FR
/pt-BR
/zh-CN
```
### Deliverables Week 1-2
- [ ] Working authentication flow with JWT + Refresh tokens
- [ ] Device fingerprinting (see API Specification)
- [ ] Secure password storage with bcrypt
- [ ] Email verification system
- [ ] Multi-language support (5 languages)
- [ ] Material Design UI components
-----
## Phase 2: Child Profiles & Family Management (Week 2-3)
### 🤖 AI Role: Full-Stack Developer with Real-time Systems Experience
```
"Act as a Full-Stack Developer with expertise in React Native, NestJS, WebSockets, and Redis. Focus on building real-time synchronization, family data management, and responsive mobile UI with Material Design."
```
### 2.1 Child Profile CRUD Operations
```typescript
// API Endpoints - Full specifications in API Specification Document
// See "Children Management Endpoints" section for complete schemas
POST /api/v1/children
GET /api/v1/children/:id
PUT /api/v1/children/:id
DELETE /api/v1/children/:id
// Use State Management Schema for Redux structure
// Children slice with normalized state shape
```
### 2.2 Family Invitation System
```typescript
// Complete flow in API Specification Document - "Family Management Endpoints"
POST /api/v1/families/invite
POST /api/v1/families/join/:shareCode
// Error handling from Error Handling & Logging Standards
// Use error codes: LIMIT_FAMILY_SIZE_EXCEEDED, AUTH_DEVICE_NOT_TRUSTED
```
### 2.3 Real-time Family Sync Setup
```typescript
// WebSocket implementation - See API Specification Document "WebSocket Events"
// State sync via State Management Schema - Sync Slice
@WebSocketGateway()
export class FamilyGateway {
// Implementation details in API Specification
// Use sync middleware from State Management Schema
}
```
### 2.4 Mobile Family Management UI
```typescript
// Screens following UI/UX Design System
// Material Design with warm color palette (peach, coral, rose)
// Minimum touch targets: 44x44px
- FamilyDashboard.tsx (use card components from Design System)
- AddChildScreen.tsx (spacious layout for one-handed use)
- ChildProfileScreen.tsx
- InviteFamilyMember.tsx
- FamilySettings.tsx
```
-----
## Phase 3: Core Tracking Features (Week 3-4)
### 🤖 AI Role: Mobile Developer & Offline-First Systems Expert
```
"Act as a Senior Mobile Developer specializing in React Native, offline-first architecture, and voice interfaces. Focus on building intuitive tracking features with voice input, offline support, and seamless sync using Redux and SQLite."
```
### 3.1 Database Schema for Activities
```sql
-- Use Migration V003 from Database Migration Scripts document
-- Includes partitioned tables for scalability
-- Run performance optimization indexes from Migration V005
```
### 3.2 Activity Tracking Services
```typescript
// Backend services - See API Specification "Activity Tracking Endpoints"
// Implement all REST endpoints with proper error codes
@Injectable()
export class TrackingService {
// Use error codes from Error Handling & Logging Standards
// Implement offline queue from State Management Schema
async logFeeding(data: FeedingDto) {
// Follow API schema from specification
// Emit WebSocket events per API Specification
// Update Redux state per State Management Schema
}
}
```
### 3.3 Voice Input Integration
```typescript
// Complete implementation in Voice Input Processing Guide
// Multi-language patterns for all 5 MVP languages
// Whisper API configuration from Environment Configuration Guide
import { WhisperService } from './services/whisperService';
// Use natural language patterns from Voice Input Processing Guide
// Implement error recovery and clarification prompts
```
### 3.4 Tracking UI Components
```typescript
// Follow UI/UX Design System specifications
// Material Design components with warm palette
// One-handed operation optimization (bottom 60% of screen)
- QuickActionButtons.tsx (FAB positioning from Design System)
- FeedingTimer.tsx
- SleepTracker.tsx
- DiaperLogger.tsx
- ActivityTimeline.tsx (use skeleton screens for loading)
```
### 3.5 Offline Support Implementation
```typescript
// Complete offline architecture in State Management Schema
// See Offline Slice and middleware configuration
// Sync queue implementation from Sync Slice
```
-----
## Phase 4: AI Assistant Integration (Week 4-5)
### 🤖 AI Role: AI/ML Engineer & LLM Integration Specialist
```
"Act as an AI/ML Engineer with expertise in LangChain, OpenAI APIs, prompt engineering, and safety systems. Focus on building a helpful, safe, and contextually aware AI assistant with proper token management and response quality."
```
### Context Review:
```
"Also review as a Child Safety Expert to ensure all AI responses are appropriate for parenting contexts and include proper medical disclaimers."
```
### 4.1 LLM Service Setup
```typescript
// Complete LangChain configuration in AI Context & Prompting Templates document
// Use system prompts and safety boundaries from the document
import { initializeLangChain } from './config/langchain';
// See AI Context & Prompting Templates for:
// - Context window management (4000 tokens)
// - Safety boundaries and medical disclaimers
// - Personalization engine
```
### 4.2 Context Management System
```typescript
// Full implementation in AI Context & Prompting Templates
// Priority weighting system for context selection
class AIContextBuilder {
// Use ContextManager from AI Context & Prompting Templates
// Implements token counting and prioritization
// Child-specific context templates
}
```
### 4.3 Chat Interface Implementation
```typescript
// React Native Chat UI
// Follow UI/UX Design System for chat bubbles
// Implement localized responses from AI Context & Prompting Templates
const AIAssistantScreen = () => {
// Use conversation memory management from AI Context document
// Implement prompt injection protection
// Apply response formatting templates
};
```
### 4.4 Smart Notifications System
```typescript
// Use patterns from API Specification - Analytics & Insights Endpoints
// Schedule based on predictions from AI
class SmartNotificationService {
// Reference notification preferences from Database Migration V006
// Use push notification setup from Environment Configuration Guide
}
```
-----
## Phase 5: Pattern Recognition & Analytics (Week 5-6)
### 🤖 AI Role: Data Scientist & Analytics Engineer
```
"Act as a Data Scientist with expertise in time-series analysis, pattern recognition, and data visualization. Focus on building accurate prediction algorithms, meaningful insights extraction, and clear data presentation using React Native charts."
```
### Context Review:
```
"Review predictions as a Pediatric Data Analyst to ensure all insights are age-appropriate and medically sound."
```
### 5.1 Pattern Analysis Engine
```typescript
// Pattern detection algorithms referenced in API Specification
// See "Analytics & Insights Endpoints" for complete schemas
@Injectable()
export class PatternAnalysisService {
// GraphQL queries from API Specification for complex data
// Use AI Context & Prompting Templates for pattern insights
async analyzeSleepPatterns(childId: string) {
// Implement sleep prediction from Voice Input Processing Guide
// Store predictions in State Management Schema - AI Slice
}
}
```
### 5.2 Predictive Algorithms
```typescript
// Sleep prediction using patterns from API Specification
// Response format from "GET /api/v1/insights/{childId}/predictions"
class SleepPredictor {
// Algorithm matches Huckleberry's SweetSpot® approach
// 85% confidence target from API Specification
}
```
### 5.3 Analytics Dashboard
```typescript
// Dashboard Components using UI/UX Design System
// Material Design cards and charts
// Victory Native from Technical Stack document
- WeeklySleepChart.tsx (use warm color palette)
- FeedingFrequencyGraph.tsx
- GrowthCurve.tsx (WHO percentiles)
- PatternInsights.tsx
- ExportReport.tsx
```
### 5.4 Report Generation
```typescript
// PDF generation using libraries from Technical Stack
// GraphQL WeeklyReport query from API Specification
class ReportGenerator {
// Use report formatting from UI/UX Design System
// Include localized content for all 5 languages
}
```
-----
## Phase 6: Testing & Optimization (Week 6-7)
### 🤖 AI Role: QA Engineer & Performance Specialist
```
"Act as a Senior QA Engineer with expertise in Jest, Detox, performance testing, and accessibility compliance. Focus on comprehensive test coverage, performance optimization, and ensuring WCAG compliance."
```
### Context Reviews:
```
1. "Review as a Security Auditor for vulnerability assessment"
2. "Review as an Accessibility Expert for WCAG AA/AAA compliance"
3. "Review as a Performance Engineer for optimization opportunities"
```
### 6.1 Unit Testing Implementation
```typescript
// Complete testing strategy in Testing Strategy Document
// 80% code coverage requirement
// Use mock data structures from Testing Strategy Document
describe('TrackingService', () => {
// Test examples from Testing Strategy Document
// Use error codes from Error Handling & Logging Standards
});
describe('SleepPredictor', () => {
// Performance benchmarks from Testing Strategy Document
// 85% accuracy target for predictions
});
```
### 6.2 Integration Testing
```typescript
// E2E tests with Detox - See Testing Strategy Document
// Critical user journeys and offline sync testing
describe('Complete tracking flow', () => {
// Test WebSocket sync from API Specification
// Verify offline queue from State Management Schema
});
```
### 6.3 Performance Optimization
```typescript
// React Native optimizations from UI/UX Design System
// - 60fps scrolling requirement
// - 2-second max load time
// - Skeleton screens for loading states
// Backend optimizations from Database Migration Scripts
// - Partitioned tables for activities
// - Performance indexes from Migration V005
// - Redis caching from Environment Configuration
```
### 6.4 Security Audit
```bash
# Security checklist from multiple documents:
# - API Specification: Request signing, rate limiting
# - Environment Configuration: Secret rotation schedule
# - Database Migrations: COPPA/GDPR compliance tables
# - Error Handling: Audit logging implementation
```
-----
## Phase 7: Beta Testing & Launch Preparation (Week 7-8)
### 🤖 AI Role: DevOps Engineer & Mobile Deployment Specialist
```
"Act as a DevOps Engineer with expertise in CI/CD, mobile app deployment, TestFlight, Google Play Console, and production infrastructure. Focus on automated deployment pipelines, monitoring setup, and app store compliance."
```
### Context Review:
```
"Review as a Compliance Officer for COPPA/GDPR requirements and app store policies"
```
### 7.1 Beta Testing Program
```markdown
# Beta Testing Plan from Testing Strategy Document
- Recruit 50 diverse families (language/geography diversity)
- Testing groups from Mobile Build & Deployment Guide
- Use TestFlight/Play Console setup from Mobile Build & Deployment Guide
- Feedback collection via Testing Strategy Document metrics
```
### 7.2 App Store Preparation
```markdown
# Complete requirements from Mobile Build & Deployment Guide
# iOS App Store - see "TestFlight Configuration" section
# Google Play Store - see "Google Play Console Configuration" section
# Store assets using UI/UX Design System guidelines:
- Screenshots with warm color palette
- App icon with peach/coral branding
- Localized descriptions for 5 languages
```
### 7.3 Monitoring Setup
```typescript
// Sentry configuration from Environment Configuration Guide
// Error tracking setup from Error Handling & Logging Standards
import * as Sentry from '@sentry/react-native';
// Use Sentry DSN from Environment Configuration
// Implement error filtering from Error Handling document
// Analytics from Technical Stack document (PostHog/Matomo)
```
### 7.4 Production Infrastructure
```yaml
# Use docker-compose.yml from Environment Configuration Guide
# Add production settings from Mobile Build & Deployment Guide
# Include all services from Technical Stack:
# - PostgreSQL, MongoDB, Redis, MinIO
```
-----
## Phase 8: Launch & Post-Launch (Week 8+)
### 🤖 AI Role: Product Manager & Growth Engineer
```
"Act as a Product Manager with expertise in user analytics, growth strategies, and iterative development. Focus on monitoring key metrics, user feedback analysis, and rapid iteration based on real-world usage."
```
### Context Reviews:
```
1. "Analyze as a Data Analyst for user behavior patterns"
2. "Review as a Customer Success Manager for support improvements"
3. "Evaluate as a Growth Hacker for retention optimization"
```
### 8.1 Launch Checklist
```markdown
## Technical - Reference Mobile Build & Deployment Guide
- [ ] Production environment live (Environment Configuration Guide)
- [ ] SSL certificates configured
- [ ] CDN configured (Technical Stack - performance section)
- [ ] Backup systems tested (Database Migration Scripts - maintenance)
- [ ] Monitoring dashboards active (Error Handling & Logging Standards)
- [ ] Error tracking enabled (Sentry setup)
- [ ] Analytics tracking verified (PostHog/Matomo)
## Legal
- [ ] Privacy policy published (COPPA/GDPR from Database Migrations)
- [ ] Terms of service published
- [ ] Compliance verified (Audit tables from Migration V007)
## Support
- [ ] Help documentation complete
- [ ] Multi-language support ready (5 languages)
- [ ] Error messages localized (Error Handling document)
```
### 8.2 Post-Launch Monitoring
```typescript
// Key metrics from Testing Strategy Document
// Success criteria: 60% DAU, <2% crash rate, 4.0+ rating
const metrics = {
// Track via analytics setup from Environment Configuration
// Use error monitoring from Error Handling & Logging Standards
// Performance metrics from API Specification (p95 < 3s)
};
```
### 8.3 Rapid Iteration Plan
```markdown
# Use CodePush from Mobile Build & Deployment Guide for OTA updates
# Follow staged rollout strategy from Mobile Build & Deployment Guide
# Week 1-2: Monitor error codes from Error Handling document
# Week 3-4: UI improvements based on Design System principles
# Month 2: Premium features from MVP Features document
```
-----
## Development Best Practices
### Code Organization
```
/maternal-app
/src
/components
/common
/tracking
/ai
/screens
/services
/hooks
/utils
/redux
/slices
/actions
/locales
/navigation
/types
/maternal-app-backend
/src
/modules
/auth
/users
/families
/tracking
/ai
/common
/guards
/interceptors
/filters
/database
/entities
/migrations
```
### Git Workflow
```bash
# Branch naming
feature/track-feeding
bugfix/sync-issue
hotfix/crash-on-login
# Commit messages
feat: add voice input for feeding tracker
fix: resolve timezone sync issue
docs: update API documentation
test: add unit tests for sleep predictor
```
### CI/CD Pipeline
```yaml
# GitHub Actions example
name: CI/CD Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: npm install
- run: npm test
- run: npm run lint
build:
needs: test
runs-on: ubuntu-latest
steps:
- run: npm run build
- run: docker build
deploy:
needs: build
if: github.ref == 'refs/heads/main'
steps:
- run: ./deploy.sh
```
-----
## Risk Mitigation Strategies
### Technical Risks
1. **LLM API Downtime**
- Implement fallback to cached responses
- Queue queries for retry
- Basic rule-based responses as backup
1. **Scalability Issues**
- Start with vertical scaling capability
- Design for horizontal scaling from day 1
- Implement caching aggressively
1. **Data Loss**
- Automated backups every 6 hours
- Point-in-time recovery capability
- Multi-region backup storage
### Business Risks
1. **Low User Adoption**
- Quick onboarding (< 2 minutes)
- Immediate value demonstration
- Strong referral incentives
1. **High Churn Rate**
- Weekly engagement emails
- Push notification optimization
- Feature discovery prompts
1. **Competitive Pressure**
- Rapid feature iteration
- Strong AI differentiation
- Community building
-----
## Success Criteria
### MVP Launch Success
- 1,000 downloads in first month
- 60% day-7 retention
- 4.0+ app store rating
- <2% crash rate
- 5+ activities logged per day per active user
- 70% of users trying AI assistant
### 3-Month Goals
- 10,000 active users
- 500 premium subscribers
- 50% month-over-month growth
- 4.5+ app store rating
- 3 major feature updates
- 2 partnership agreements
### 6-Month Vision
- 50,000 active users
- 2,500 premium subscribers
- Break-even on operational costs
- International expansion (10+ countries)
- Integration ecosystem launched
- Series A fundraising ready

View File

@@ -0,0 +1,590 @@
# Mobile Build & Deployment Guide - Maternal Organization App
## Build Environment Setup
### Prerequisites
```bash
# Required tools
node >= 18.0.0
npm >= 9.0.0
react-native-cli >= 2.0.1
expo-cli >= 6.0.0
cocoapods >= 1.12.0 (iOS)
java 11 (Android)
android-studio (Android)
xcode >= 14.0 (iOS)
```
### Project Initialization
```bash
# Create project with Expo
npx create-expo-app maternal-app --template
# Install core dependencies
cd maternal-app
npm install react-native-reanimated react-native-gesture-handler
npm install react-native-safe-area-context react-native-screens
npm install @react-navigation/native @react-navigation/bottom-tabs
```
---
## iOS Configuration
### Bundle Identifier & Provisioning
```xml
<!-- ios/MaternalApp/Info.plist -->
<key>CFBundleIdentifier</key>
<string>com.maternalapp.ios</string>
<key>CFBundleDisplayName</key>
<string>Maternal</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleVersion</key>
<string>1</string>
```
### App Capabilities
```xml
<!-- ios/MaternalApp/MaternalApp.entitlements -->
<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
<key>aps-environment</key>
<string>production</string>
<key>com.apple.developer.healthkit</key>
<true/>
<key>com.apple.developer.healthkit.background-delivery</key>
<true/>
<key>com.apple.security.application-groups</key>
<array>
<string>group.com.maternalapp.shared</string>
</array>
</dict>
</plist>
```
### Permissions
```xml
<!-- ios/MaternalApp/Info.plist -->
<key>NSCameraUsageDescription</key>
<string>Take photos of your child for memories and milestone tracking</string>
<key>NSMicrophoneUsageDescription</key>
<string>Enable voice input for hands-free activity logging</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Select photos for your child's profile and milestones</string>
<key>NSSpeechRecognitionUsageDescription</key>
<string>Convert your voice to text for quick logging</string>
<key>NSHealthShareUsageDescription</key>
<string>Read health data to track your child's growth</string>
<key>NSHealthUpdateUsageDescription</key>
<string>Save growth measurements to Health app</string>
```
### Code Signing Configuration
```ruby
# ios/fastlane/Fastfile
platform :ios do
desc "Build and deploy to TestFlight"
lane :beta do
increment_build_number
match(
type: "appstore",
app_identifier: "com.maternalapp.ios",
git_url: "git@github.com:maternal-app/certificates.git"
)
gym(
scheme: "MaternalApp",
configuration: "Release",
export_method: "app-store",
output_directory: "./build",
output_name: "MaternalApp.ipa"
)
pilot(
ipa: "./build/MaternalApp.ipa",
skip_waiting_for_build_processing: true,
changelog: "Bug fixes and performance improvements"
)
end
end
```
---
## Android Configuration
### Package Name & Versioning
```gradle
// android/app/build.gradle
android {
compileSdkVersion 34
buildToolsVersion "34.0.0"
defaultConfig {
applicationId "com.maternalapp.android"
minSdkVersion 23 // Android 6.0
targetSdkVersion 34
versionCode 1
versionName "1.0.0"
multiDexEnabled true
}
signingConfigs {
release {
storeFile file(MATERNAL_RELEASE_STORE_FILE)
storePassword MATERNAL_RELEASE_STORE_PASSWORD
keyAlias MATERNAL_RELEASE_KEY_ALIAS
keyPassword MATERNAL_RELEASE_KEY_PASSWORD
}
}
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
```
### Permissions
```xml
<!-- android/app/src/main/AndroidManifest.xml -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!-- Google Play Services -->
<uses-permission android:name="com.google.android.gms.permission.AD_ID" tools:node="remove" />
```
### ProGuard Rules
```pro
# android/app/proguard-rules.pro
-keep class com.maternalapp.** { *; }
-keep class com.facebook.react.** { *; }
-keep class com.swmansion.** { *; }
# React Native
-keep,allowobfuscation @interface com.facebook.proguard.annotations.DoNotStrip
-keep,allowobfuscation @interface com.facebook.proguard.annotations.KeepGettersAndSetters
# Firebase
-keep class com.google.firebase.** { *; }
-keep class com.google.android.gms.** { *; }
```
---
## Environment-Specific Builds
### Build Configurations
```javascript
// app.config.js
export default ({ config }) => {
const buildType = process.env.BUILD_TYPE || 'development';
const configs = {
development: {
name: 'Maternal (Dev)',
bundleIdentifier: 'com.maternalapp.dev',
apiUrl: 'https://dev-api.maternalapp.com',
icon: './assets/icon-dev.png',
},
staging: {
name: 'Maternal (Staging)',
bundleIdentifier: 'com.maternalapp.staging',
apiUrl: 'https://staging-api.maternalapp.com',
icon: './assets/icon-staging.png',
},
production: {
name: 'Maternal',
bundleIdentifier: 'com.maternalapp.ios',
apiUrl: 'https://api.maternalapp.com',
icon: './assets/icon.png',
},
};
return {
...config,
...configs[buildType],
ios: {
...config.ios,
bundleIdentifier: configs[buildType].bundleIdentifier,
buildNumber: '1',
},
android: {
...config.android,
package: configs[buildType].bundleIdentifier.replace('ios', 'android'),
versionCode: 1,
},
};
};
```
### Environment Variables
```bash
# .env.production
API_URL=https://api.maternalapp.com
SENTRY_DSN=https://prod-sentry.maternalapp.com
ANALYTICS_ENABLED=true
CRASH_REPORTING=true
# .env.staging
API_URL=https://staging-api.maternalapp.com
SENTRY_DSN=https://staging-sentry.maternalapp.com
ANALYTICS_ENABLED=true
CRASH_REPORTING=true
# .env.development
API_URL=http://localhost:3000
SENTRY_DSN=
ANALYTICS_ENABLED=false
CRASH_REPORTING=false
```
---
## CI/CD Pipeline
### GitHub Actions Workflow
```yaml
# .github/workflows/mobile-deploy.yml
name: Mobile Build & Deploy
on:
push:
branches: [main, staging]
tags: ['v*']
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
- run: npm ci
- run: npm test
- run: npm run lint
build-ios:
needs: test
runs-on: macos-latest
if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')
steps:
- uses: actions/checkout@v3
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: |
npm ci
cd ios && pod install
- name: Setup certificates
env:
CERTIFICATE_BASE64: ${{ secrets.IOS_CERTIFICATE_BASE64 }}
PROVISION_PROFILE_BASE64: ${{ secrets.IOS_PROVISION_PROFILE_BASE64 }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
run: |
# Create keychain
security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
# Import certificate
echo "$CERTIFICATE_BASE64" | base64 --decode > certificate.p12
security import certificate.p12 -k build.keychain -P "${{ secrets.CERTIFICATE_PASSWORD }}" -T /usr/bin/codesign
# Import provisioning profile
echo "$PROVISION_PROFILE_BASE64" | base64 --decode > profile.mobileprovision
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
cp profile.mobileprovision ~/Library/MobileDevice/Provisioning\ Profiles/
- name: Build IPA
run: |
cd ios
xcodebuild -workspace MaternalApp.xcworkspace \
-scheme MaternalApp \
-configuration Release \
-archivePath $PWD/build/MaternalApp.xcarchive \
archive
xcodebuild -exportArchive \
-archivePath $PWD/build/MaternalApp.xcarchive \
-exportPath $PWD/build \
-exportOptionsPlist ExportOptions.plist
- name: Upload to TestFlight
env:
APP_STORE_CONNECT_API_KEY: ${{ secrets.APP_STORE_CONNECT_API_KEY }}
run: |
xcrun altool --upload-app \
--type ios \
--file ios/build/MaternalApp.ipa \
--apiKey "${{ secrets.API_KEY_ID }}" \
--apiIssuer "${{ secrets.API_ISSUER_ID }}"
build-android:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')
steps:
- uses: actions/checkout@v3
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Setup Java
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '11'
- name: Install dependencies
run: npm ci
- name: Setup keystore
env:
KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
run: |
echo "$KEYSTORE_BASE64" | base64 --decode > android/app/release.keystore
echo "MATERNAL_RELEASE_STORE_FILE=release.keystore" >> android/gradle.properties
echo "MATERNAL_RELEASE_KEY_ALIAS=${{ secrets.ANDROID_KEY_ALIAS }}" >> android/gradle.properties
echo "MATERNAL_RELEASE_STORE_PASSWORD=${{ secrets.ANDROID_STORE_PASSWORD }}" >> android/gradle.properties
echo "MATERNAL_RELEASE_KEY_PASSWORD=${{ secrets.ANDROID_KEY_PASSWORD }}" >> android/gradle.properties
- name: Build APK
run: |
cd android
./gradlew assembleRelease
- name: Build AAB
run: |
cd android
./gradlew bundleRelease
- name: Upload to Play Store
uses: r0adkll/upload-google-play@v1
with:
serviceAccountJsonPlainText: ${{ secrets.PLAY_SERVICE_ACCOUNT_JSON }}
packageName: com.maternalapp.android
releaseFiles: android/app/build/outputs/bundle/release/app-release.aab
track: internal
status: draft
```
---
## TestFlight Configuration
### App Store Connect Setup
```javascript
// ios/fastlane/metadata/en-US/description.txt
Maternal is your AI-powered parenting companion, designed to reduce mental load and bring confidence to your parenting journey.
Key Features:
Smart activity tracking with voice input
AI assistant available 24/7 for parenting questions
Real-time family synchronization
Sleep predictions based on your baby's patterns
Growth tracking with WHO percentiles
// ios/fastlane/metadata/en-US/keywords.txt
parenting,baby tracker,sleep tracking,feeding log,AI assistant,family app,childcare
```
### Beta Testing Groups
```yaml
# TestFlight Groups
internal_testing:
name: "Internal Team"
members: 10
builds: all
beta_families:
name: "Beta Families"
members: 50
builds: stable
feedback: enabled
early_access:
name: "Early Access"
members: 500
builds: release_candidate
```
---
## Google Play Console Configuration
### Store Listing
```yaml
# Play Console Setup
app_details:
title: "Maternal - AI Parenting Assistant"
short_description: "Smart parenting companion with AI support"
full_description: |
Complete description...
category: "Parenting"
content_rating: "Everyone"
graphics:
icon: 512x512px
feature_graphic: 1024x500px
screenshots:
phone: [6 images minimum]
tablet: [optional]
```
### Release Tracks
```yaml
internal_testing:
testers: "internal-testers@maternalapp.com"
release_frequency: "daily"
closed_testing:
testers: 100
release_frequency: "weekly"
open_testing:
countries: ["US", "CA", "GB", "AU"]
release_frequency: "bi-weekly"
production:
rollout_percentage: 10 # Start with 10%
staged_rollout: true
```
---
## Over-the-Air Updates
### CodePush Setup
```bash
# Install CodePush
npm install react-native-code-push
# iOS setup
cd ios && pod install
# Register app with CodePush
code-push app add Maternal-iOS ios react-native
code-push app add Maternal-Android android react-native
```
### Update Configuration
```javascript
// App.js
import CodePush from 'react-native-code-push';
const codePushOptions = {
checkFrequency: CodePush.CheckFrequency.ON_APP_RESUME,
installMode: CodePush.InstallMode.ON_NEXT_RESTART,
mandatoryInstallMode: CodePush.InstallMode.IMMEDIATE,
updateDialog: {
title: 'Update Available',
mandatoryUpdateMessage: 'An important update is available.',
optionalUpdateMessage: 'An update is available. Would you like to install it?',
},
};
export default CodePush(codePushOptions)(App);
```
### Deployment Commands
```bash
# Deploy update to staging
code-push release-react Maternal-iOS ios -d Staging
code-push release-react Maternal-Android android -d Staging
# Promote to production
code-push promote Maternal-iOS Staging Production -r 10%
code-push promote Maternal-Android Staging Production -r 10%
```
---
## Performance Monitoring
### Build Size Optimization
```javascript
// metro.config.js
module.exports = {
transformer: {
minifierConfig: {
keep_fnames: true,
mangle: {
keep_fnames: true,
},
},
},
};
```
### Bundle Analysis
```bash
# Analyze bundle size
npx react-native-bundle-visualizer
# iOS specific
npx react-native bundle --platform ios --dev false --entry-file index.js --bundle-output ios/main.jsbundle --assets-dest ios
# Android specific
cd android && ./gradlew bundleRelease --scan
```
---
## Pre-Launch Checklist
### iOS Submission
- [ ] TestFlight build approved
- [ ] App Store screenshots (6.5", 5.5")
- [ ] App preview video (optional)
- [ ] Privacy policy URL
- [ ] Support URL
- [ ] Marketing URL
- [ ] Age rating questionnaire
- [ ] Export compliance
- [ ] App Review notes
### Android Submission
- [ ] Signed AAB uploaded
- [ ] Store listing complete
- [ ] Content rating questionnaire
- [ ] Target audience declaration
- [ ] Data safety form
- [ ] Privacy policy URL
- [ ] App category selected
- [ ] Closed testing feedback addressed
### General Requirements
- [ ] COPPA compliance verified
- [ ] GDPR compliance documented
- [ ] Terms of service updated
- [ ] Support system ready
- [ ] Analytics tracking verified
- [ ] Crash reporting active
- [ ] Performance benchmarks met
- [ ] Accessibility tested

346
docs/maternal-app-mvp.md Normal file
View File

@@ -0,0 +1,346 @@
# MVP Features List - AI-Powered Maternal Organization App
## 🎯 MVP Goal
Launch a functional app that solves the most acute pain points for mothers with children 0-6 years old, focusing on reducing mental load through intelligent tracking and AI-powered support.
## 📱 Core User Experience (Week 1-2 Priority)
### User Onboarding & Account Setup
- **Quick Registration**
- Email/phone signup with verification
- Google/Apple social login
- Basic profile creation (name, timezone)
- COPPA/GDPR consent flow
- **Child Profile Setup**
- Add child (name, birthdate, gender optional)
- Support for 1-2 children (free tier)
- Basic medical info (allergies, conditions)
- Profile photo upload
- **Family Access**
- Invite one partner/caregiver
- Simple permission model (view/edit)
- Share code for quick partner setup
## 🍼 Essential Tracking Features (Week 2-4 Priority)
### Feeding Tracker
- **Quick Log Options**
- Breast (left/right/both) with timer
- Bottle (amount in oz/ml)
- Start/stop timer functionality
- Previous feeding quick-repeat
- **Voice Input**
- "Baby fed 4 ounces at 3pm"
- "Started nursing left side"
- Natural language processing
### Sleep Tracker
- **Simple Sleep Logging**
- One-tap sleep start/end
- Nap vs night sleep
- Location (crib, car, stroller)
- Quick notes option
- **AI Sleep Predictions** ⭐
- Next nap time prediction
- Wake window calculations
- Optimal bedtime suggestions
- Pattern recognition after 5 days
### Diaper Tracker
- **Fast Diaper Logging**
- Wet/dirty/both buttons
- Time auto-stamps
- Optional notes (rash, color)
- Pattern tracking for health
### Growth Tracker
- **Basic Measurements**
- Weight entry
- Height entry
- Growth chart visualization
- WHO percentile calculations
## 🤖 AI Assistant - The Killer Feature (Week 3-5 Priority)
### 24/7 Conversational Support
- **Natural Language Chat**
- "Why won't my baby sleep?"
- "Is this feeding pattern normal?"
- "What solids should I introduce?"
- "Help with sleep regression"
- **Contextual Responses**
- Uses your child's tracked data
- Age-appropriate guidance
- Evidence-based recommendations
- Remembers conversation context
- **Safety Features**
- Emergency resource links
- "Consult doctor" prompts for concerns
- Disclaimer on medical advice
- Crisis hotline integration
### Smart Insights & Predictions
- **Pattern Recognition**
- "Your baby sleeps better after morning walks"
- "Feeding intervals are increasing"
- "Nap duration improving this week"
- **Proactive Suggestions**
- "Based on patterns, next feeding around 2:30pm"
- "Consider starting bedtime routine at 6:45pm"
- "Growth spurt likely - expect increased feeding"
## 📅 Basic Family Coordination (Week 4-5 Priority)
### Real-Time Sync
- **Instant Updates**
- Activities sync across devices
- Partner sees updates immediately
- Offline mode with sync queue
- Conflict resolution
### Simple Notifications
- **Smart Reminders**
- Medication schedules
- Vaccination appointments
- Custom reminders
- Pattern-based alerts
### Activity Feed
- **Family Timeline**
- Chronological activity list
- Filter by child/activity type
- Today/yesterday/week views
- Quick stats dashboard
## 📊 Essential Analytics (Week 5-6 Priority)
### Daily Summaries
- **Overview Dashboard**
- Today's feeding total
- Sleep duration (day/night)
- Last activities at a glance
- Trends vs yesterday
### Weekly Patterns
- **Simple Reports**
- Average sleep per day
- Feeding frequency trends
- Growth trajectory
- Exportable for pediatrician
## 🌍 Internationalization & Localization
### Language Support (MVP Phase)
- **Initial Languages**
- English (primary)
- Spanish (large US population)
- French (Canadian market)
- Portuguese (Brazilian market)
- Simplified Chinese (growth market)
- **Localization Framework**
- All strings externalized from day 1
- RTL support structure (Arabic/Hebrew ready)
- Date/time format localization
- Number format localization
- Currency display for future features
- **AI Assistant Multilingual**
- Responses in user's selected language
- Language detection from voice input
- Culturally appropriate advice
- Local emergency resources by region
- **Content Localization**
- Measurement units (metric/imperial)
- Growth charts by region (WHO/CDC)
- Vaccination schedules by country
- Local pediatric guidelines
- Timezone auto-detection
## 🔒 Privacy & Security Essentials
### Data Protection
- **Security Basics**
- End-to-end encryption
- Secure authentication
- Biometric login option
- Auto-logout settings
### Privacy Controls
- **User Control**
- Data export capability
- Account deletion option
- No third-party data sharing
- Anonymous mode available
- Region-specific privacy compliance
## 📱 Technical MVP Requirements
### Platform Support
- **Mobile First**
- iOS 14+ support
- Android 10+ support
- Responsive design
- Tablet optimization (Phase 2)
### Performance Standards
- **User Experience**
- 2-second max load time
- Offline core features
- <100MB app size
- 60fps scrolling
### Accessibility Basics
- **Inclusive Design**
- Large touch targets (44x44 min)
- High contrast mode
- Text size adjustment
- Screen reader support
## 💰 Monetization - Simple Tiers
### Free Tier (Launch)
- 1-2 children max
- All core tracking features
- Basic AI assistance (10 questions/day)
- 7-day data history
- Basic patterns & insights
### Premium Tier ($9.99/month)
- Unlimited children
- Unlimited AI assistance
- Full data history
- Advanced predictions
- Priority support
- Export features
- Advanced insights
## 🚫 NOT in MVP (Future Releases)
### Deferred Features
- ❌ Meal planning
- ❌ Financial tracking
- ❌ Community forums
- ❌ Photo milestone tracking
- ❌ Video consultations
- ❌ Smart home integration
- ❌ Web version
- ❌ Wearable integration
- ❌ School platform connections
## 📈 Success Metrics for MVP
### Key Performance Indicators
- **User Acquisition**
- 1,000 downloads in first month
- 40% complete onboarding
- 25% invite a partner
- **Engagement Metrics**
- 60% daily active users
- 5+ logs per day average
- 3+ AI interactions weekly
- 70% week-1 retention
- **Technical Metrics**
- <2% crash rate
- 99.5% uptime
- <3 second response time
- 4.0+ app store rating
## 🗓️ 6-Week MVP Timeline
### Week 1-2: Foundation
- User authentication system
- Basic child profiles
- Core database schema
- Initial UI framework
- i18n framework setup
- String externalization
### Week 3-4: Core Features
- Feeding/sleep/diaper tracking
- Voice input integration
- Real-time sync
- Basic notifications
- Multilingual voice recognition
### Week 5-6: AI Integration
- LLM integration (OpenAI/Claude)
- Context-aware responses
- Pattern recognition
- Sleep predictions
- Language-specific AI responses
### Week 7-8: Polish & Launch
- Bug fixes & optimization
- App store preparation (multiple locales)
- Beta testing with 50 families (diverse languages)
- Launch marketing preparation
- Translation quality review
## 🎯 MVP Principles
### Focus Areas
1. **Solve One Problem Well**: Reduce mental load through intelligent tracking
2. **AI as Differentiator**: Make the assistant genuinely helpful from day 1
3. **Trust Through Privacy**: Parents need to feel data is secure
4. **Work in Chaos**: One-handed, interruption-resistant design
5. **Immediate Value**: User should see benefit within first 24 hours
### Quality Thresholds
- **Stability over features**: Better to have 5 rock-solid features than 10 buggy ones
- **Real-time sync must be flawless**: Partners rely on accurate shared data
- **AI responses must be helpful**: No generic, unhelpful responses
- **Voice input must be accurate**: Critical for hands-occupied situations
## 🚀 Post-MVP Roadmap Preview
### Phase 2 (Months 2-3)
- Community features with moderation
- Photo milestone tracking
- Meal planning basics
- Calendar integration
- Additional languages (German, Italian, Japanese, Korean, Arabic)
### Phase 3 (Months 4-6)
- Financial tracking
- Smart home integration
- Professional tools
- Advanced analytics
- Telemedicine integration
## ✅ MVP Launch Checklist
### Pre-Launch Requirements
- [ ] COPPA/GDPR compliance verified
- [ ] Privacy policy & terms of service (all languages)
- [ ] App store assets ready (localized)
- [ ] Beta testing with 50+ families (diverse languages/cultures)
- [ ] Customer support system setup (multilingual)
- [ ] Analytics tracking implemented
- [ ] Crash reporting active
- [ ] Payment processing tested (multi-currency)
- [ ] Backup systems verified
- [ ] Security audit completed
- [ ] Translation quality assurance completed
### Launch Day Essentials
- [ ] App store submission approved (all regions)
- [ ] Marketing website live (multilingual)
- [ ] Support documentation ready (all languages)
- [ ] Social media accounts active
- [ ] Press kit available (multilingual)
- [ ] Customer feedback system active
- [ ] Monitoring dashboards operational
- [ ] Support team trained (language coverage)
- [ ] Emergency response plan ready
- [ ] Celebration planned! 🎉

View File

@@ -0,0 +1,89 @@
# Available Domains for Maternal Parenting App
**Both .com and .app domains show strong availability** across these 20 carefully researched names that convey support, organization, AI assistance, and reduced mental load for overwhelmed parents. Each name is under 15 characters, easy to spell, memorable, and professionally warm.
## Research methodology and validation
I deployed five research teams to explore different thematic categories and verify domain availability across multiple registrars including Namecheap, GoDaddy, Name.com, InstantDomainSearch, and DNSChecker. While registrars require interactive searches for definitive confirmation, extensive web research found **no active websites or businesses** using these names, indicating strong availability likelihood. You should verify final availability within 24-48 hours as domains are registered constantly.
## Top tier names (strongest recommendations)
These seven names scored highest across all criteria—memorability, brand strength, thematic fit, and availability confidence:
**CareAI** (6 characters) combines nurturing care with direct AI positioning. Extremely concise and clear about technology-enabled parenting support. No existing services found across multiple registrars and search engines. Conveys both warmth and intelligence.
**MomMind** (7 characters) perfectly captures intelligent assistance through the "mind" concept while maintaining warm maternal connection. Short, brandable, and memorable with zero online presence detected. Suggests the app serves as a second mind for busy mothers.
**FamMind** (7 characters) offers broader family appeal than MomMind while maintaining the intelligent assistant positioning. Modern and tech-forward with no conflicting websites found. Appeals to all parents rather than mothers exclusively.
**CareGlow** (8 characters) evokes warmth, positivity, and radiant care. The "glow" connects naturally to maternal imagery while "care" remains direct and clear. Highly memorable and brandable with no active businesses using this name.
**FamNest** (7 characters) combines family focus with nest imagery suggesting safety, home, and warmth. Perfect for family hub concept with strong visual identity potential. No major web presence detected across multiple searches.
**MomFlow** (7 characters) suggests smooth, effortless family management through productivity flow. Easy to pronounce with strong appeal for reducing mental load. No active website found.
**NestWise** (8 characters) merges nurturing nest imagery with wisdom and guidance. Professional yet warm, suggesting smart parenting support. Clean search results indicate availability across registrars.
## AI and technology-focused names
These options emphasize intelligent assistance and smart parenting technology:
**NurturAI** (8 characters) beautifully combines nurture with AI through intentional spelling (dropping the 'e' from nurture). Sophisticated yet approachable with no websites found using this spelling variant. The creative spelling makes it more unique and brandable.
**MomPulse** (8 characters) suggests real-time monitoring and staying connected with needs. "Pulse" conveys being in tune with family rhythms. Modern and dynamic while maintaining warmth. No existing services detected.
**GuideMom** (8 characters) offers clear value proposition about providing guidance. Direct and memorable with professional tone. Zero online presence found across multiple registrar searches.
**BabyMind** (8 characters) appeals specifically to new parents and infant care. Suggests intelligent support during the demanding early parenting phase. No conflicting websites identified.
## Organization and coordination names
These emphasize family management and reducing mental load:
**FamFlow** (7 characters) conveys smooth family coordination and workflow optimization. Short, catchy, and professional with strong brandability. No active websites found.
**CoordKit** (8 characters) directly communicates "coordination toolkit" with professional, functional clarity. Modern tech feel while maintaining warmth. No major online presence detected.
**OrgaMom** (7 characters) provides direct organization messaging for mothers. Playful yet professional and easy to remember. Clean availability status across searches.
**MomCoord** (8 characters) straightforward mom coordination concept. Clear purpose with professional appeal. No existing businesses found using this name.
## Calm and stress relief names
These focus on easing parental overwhelm and providing peace:
**CalmPath** (8 characters) suggests a journey toward tranquility and calm parenting. Clear, memorable, and evocative with easy spelling. Professional yet warm tone with no active websites detected.
**ParentFlow** (10 characters) conveys smooth, effortless parenting where everything flows naturally. Modern professional branding appealing to tech-savvy parents. No conflicting online presence found.
**CalmLift** (8 characters) suggests lifting burdens and providing relief from stress. Strong emotional connection for overwhelmed parents. Memorable and distinctive with clean availability.
**MomPeace** (8 characters) directly addresses what stressed parents seek most. Short, memorable, and easy to spell with warm maternal tone remaining professional. No existing services identified.
## Community and support names
These emphasize connection, togetherness, and shared experience:
**MomGather** (9 characters) communicates community and togetherness perfectly. "Gather" feels warm, inviting, and action-oriented while appealing to maternal audience. Modern and professional with no brand conflicts found.
**ParentCove** (10 characters) uses "cove" to suggest safe harbor, protection, and community. Professional and warm simultaneously with good SEO potential through "parent" keyword. No major online presence detected.
## Domain verification checklist
To confirm availability for both .com and .app extensions, check these registrars immediately:
**Primary verification:** Visit Namecheap.com/domains/domain-name-search and enter each domain name. Check both .com and .app extensions. Namecheap offers competitive pricing ($10-15/year for .com, $15-20/year for .app) plus free WHOIS privacy protection.
**Secondary verification:** Cross-reference at GoDaddy.com/domains to ensure consistency. GoDaddy is the largest registrar with extensive customer support and reliable infrastructure.
**Rapid checking:** Use InstantDomainSearch.com for real-time results showing availability across multiple extensions simultaneously. This tool provides results in under 25 milliseconds.
**Important considerations:** The .app extension requires HTTPS/SSL certificates as it's owned by Google and operates as a secure namespace. Register both .com and .app for your chosen name simultaneously to protect your brand. Budget $50-75 for the domain pair plus SSL certificate for .app.
## Names confirmed unavailable (avoid these)
Research identified these names as taken: MomEase, CalmNest, ParentZen, MomHaven, MomCircle (active app), ParentPod, FamSync, ParentHub/parent.app, MomWise, MomAlly, ParentLift, CareBloom, MomGlow, MomThrive, and NurtureNow. These have active websites, businesses, or apps already using them.
## Registration strategy
Act quickly on your top 3-5 choices as domain availability changes constantly. The strongest options—CareAI, MomMind, FamMind, CareGlow, and FamNest—showed zero existing web presence across all research, indicating highest availability confidence. Consider registering multiple extensions (.com, .app, .net) for your final choice to protect brand identity. Verify within 24-48 hours and register immediately once confirmed to secure your preferred name.

View File

@@ -0,0 +1,724 @@
# State Management Schema - Maternal Organization App
## Store Architecture Overview
### Redux Toolkit Structure
```typescript
// Core principles:
// - Single source of truth
// - Normalized state shape
// - Offline-first design
// - Optimistic updates
// - Automatic sync queue
```
---
## Root Store Structure
```typescript
interface RootState {
auth: AuthState;
user: UserState;
family: FamilyState;
children: ChildrenState;
activities: ActivitiesState;
ai: AIState;
sync: SyncState;
offline: OfflineState;
ui: UIState;
notifications: NotificationState;
analytics: AnalyticsState;
}
```
---
## Auth Slice
### State Shape
```typescript
interface AuthState {
isAuthenticated: boolean;
accessToken: string | null;
refreshToken: string | null;
tokenExpiry: number | null;
deviceFingerprint: string;
trustedDevices: string[];
authStatus: 'idle' | 'loading' | 'succeeded' | 'failed';
error: string | null;
}
```
### Actions
```typescript
// authSlice.ts
const authSlice = createSlice({
name: 'auth',
initialState,
reducers: {
loginStart: (state) => {
state.authStatus = 'loading';
},
loginSuccess: (state, action) => {
state.isAuthenticated = true;
state.accessToken = action.payload.accessToken;
state.refreshToken = action.payload.refreshToken;
state.tokenExpiry = action.payload.expiresAt;
state.authStatus = 'succeeded';
},
loginFailure: (state, action) => {
state.authStatus = 'failed';
state.error = action.payload;
},
tokenRefreshed: (state, action) => {
state.accessToken = action.payload.accessToken;
state.tokenExpiry = action.payload.expiresAt;
},
logout: (state) => {
return initialState;
},
},
});
```
---
## User Slice
### State Shape
```typescript
interface UserState {
currentUser: {
id: string;
email: string;
name: string;
locale: string;
timezone: string;
photoUrl?: string;
preferences: UserPreferences;
} | null;
subscription: {
tier: 'free' | 'premium' | 'plus';
expiresAt?: string;
aiQueriesUsed: number;
aiQueriesLimit: number;
};
}
interface UserPreferences {
darkMode: 'auto' | 'light' | 'dark';
notifications: {
push: boolean;
email: boolean;
quietHoursStart?: string;
quietHoursEnd?: string;
};
measurementUnit: 'metric' | 'imperial';
}
```
---
## Family Slice
### State Shape
```typescript
interface FamilyState {
currentFamily: {
id: string;
name: string;
shareCode: string;
createdBy: string;
} | null;
members: {
byId: Record<string, FamilyMember>;
allIds: string[];
};
invitations: Invitation[];
loadingStatus: LoadingStatus;
}
interface FamilyMember {
id: string;
name: string;
email: string;
role: 'parent' | 'caregiver' | 'viewer';
permissions: Permissions;
lastActive: string;
isOnline: boolean;
}
```
### Normalized Actions
```typescript
const familySlice = createSlice({
name: 'family',
initialState,
reducers: {
memberAdded: (state, action) => {
const member = action.payload;
state.members.byId[member.id] = member;
state.members.allIds.push(member.id);
},
memberUpdated: (state, action) => {
const { id, changes } = action.payload;
state.members.byId[id] = {
...state.members.byId[id],
...changes,
};
},
memberRemoved: (state, action) => {
const id = action.payload;
delete state.members.byId[id];
state.members.allIds = state.members.allIds.filter(mid => mid !== id);
},
},
});
```
---
## Children Slice
### State Shape
```typescript
interface ChildrenState {
children: {
byId: Record<string, Child>;
allIds: string[];
};
activeChildId: string | null;
milestones: {
byChildId: Record<string, Milestone[]>;
};
}
interface Child {
id: string;
name: string;
birthDate: string;
gender?: string;
photoUrl?: string;
medical: {
bloodType?: string;
allergies: string[];
conditions: string[];
medications: Medication[];
};
metrics: {
currentWeight?: Measurement;
currentHeight?: Measurement;
headCircumference?: Measurement;
};
}
```
---
## Activities Slice (Normalized)
### State Shape
```typescript
interface ActivitiesState {
activities: {
byId: Record<string, Activity>;
allIds: string[];
byChild: Record<string, string[]>; // childId -> activityIds
byDate: Record<string, string[]>; // date -> activityIds
};
activeTimers: {
[childId: string]: ActiveTimer;
};
filters: {
childId?: string;
dateRange?: { start: string; end: string };
types?: ActivityType[];
};
pagination: {
cursor: string | null;
hasMore: boolean;
isLoading: boolean;
};
}
interface Activity {
id: string;
childId: string;
type: ActivityType;
timestamp: string;
duration?: number;
details: ActivityDetails;
loggedBy: string;
syncStatus: 'synced' | 'pending' | 'error';
version: number; // For conflict resolution
}
interface ActiveTimer {
activityType: ActivityType;
startTime: number;
pausedDuration: number;
isPaused: boolean;
}
```
### Activity Actions
```typescript
const activitiesSlice = createSlice({
name: 'activities',
initialState,
reducers: {
// Optimistic update
activityLogged: (state, action) => {
const activity = {
...action.payload,
syncStatus: 'pending',
};
state.activities.byId[activity.id] = activity;
state.activities.allIds.unshift(activity.id);
// Update indexes
if (!state.activities.byChild[activity.childId]) {
state.activities.byChild[activity.childId] = [];
}
state.activities.byChild[activity.childId].unshift(activity.id);
},
// Sync confirmed
activitySynced: (state, action) => {
const { localId, serverId } = action.payload;
state.activities.byId[localId].id = serverId;
state.activities.byId[localId].syncStatus = 'synced';
},
// Timer management
timerStarted: (state, action) => {
const { childId, activityType } = action.payload;
state.activeTimers[childId] = {
activityType,
startTime: Date.now(),
pausedDuration: 0,
isPaused: false,
};
},
},
});
```
---
## AI Slice
### State Shape
```typescript
interface AIState {
conversations: {
byId: Record<string, Conversation>;
activeId: string | null;
};
insights: {
byChildId: Record<string, Insight[]>;
pending: Insight[];
};
predictions: {
byChildId: Record<string, Predictions>;
};
quotas: {
dailyQueries: number;
dailyLimit: number;
resetAt: string;
};
}
interface Conversation {
id: string;
childId?: string;
messages: Message[];
context: ConversationContext;
lastMessageAt: string;
}
interface Predictions {
nextNapTime?: { time: string; confidence: number };
nextFeedingTime?: { time: string; confidence: number };
growthSpurt?: { likelihood: number; expectedIn: string };
}
```
---
## Sync Slice (Critical for Offline)
### State Shape
```typescript
interface SyncState {
queue: SyncQueueItem[];
conflicts: ConflictItem[];
lastSync: {
[entityType: string]: string; // ISO timestamp
};
syncStatus: 'idle' | 'syncing' | 'error' | 'offline';
retryCount: number;
webSocket: {
connected: boolean;
reconnectAttempts: number;
};
}
interface SyncQueueItem {
id: string;
type: 'CREATE' | 'UPDATE' | 'DELETE';
entity: 'activity' | 'child' | 'family';
payload: any;
timestamp: string;
retries: number;
error?: string;
}
interface ConflictItem {
id: string;
localVersion: any;
serverVersion: any;
strategy: 'manual' | 'local' | 'server' | 'merge';
}
```
### Sync Actions
```typescript
const syncSlice = createSlice({
name: 'sync',
initialState,
reducers: {
addToQueue: (state, action) => {
state.queue.push({
id: nanoid(),
...action.payload,
timestamp: new Date().toISOString(),
retries: 0,
});
},
removeFromQueue: (state, action) => {
state.queue = state.queue.filter(item => item.id !== action.payload);
},
conflictDetected: (state, action) => {
state.conflicts.push(action.payload);
},
conflictResolved: (state, action) => {
const { id, resolution } = action.payload;
state.conflicts = state.conflicts.filter(c => c.id !== id);
// Apply resolution...
},
syncCompleted: (state, action) => {
state.lastSync[action.payload.entity] = new Date().toISOString();
state.syncStatus = 'idle';
},
},
});
```
---
## Offline Slice
### State Shape
```typescript
interface OfflineState {
isOnline: boolean;
queuedActions: OfflineAction[];
cachedData: {
[key: string]: {
data: any;
timestamp: string;
ttl: number;
};
};
retryPolicy: {
maxRetries: number;
retryDelay: number;
backoffMultiplier: number;
};
}
interface OfflineAction {
id: string;
action: AnyAction;
meta: {
offline: {
effect: any;
commit: AnyAction;
rollback: AnyAction;
};
};
}
```
---
## UI Slice
### State Shape
```typescript
interface UIState {
theme: 'light' | 'dark' | 'auto';
activeScreen: string;
modals: {
[modalId: string]: {
isOpen: boolean;
data?: any;
};
};
loading: {
[key: string]: boolean;
};
errors: {
[key: string]: ErrorInfo;
};
toasts: Toast[];
bottomSheet: {
isOpen: boolean;
content: 'quickActions' | 'activityDetails' | null;
};
}
interface Toast {
id: string;
type: 'success' | 'error' | 'info';
message: string;
duration: number;
}
```
---
## Middleware Configuration
### Store Setup
```typescript
// store/index.ts
import { configureStore } from '@reduxjs/toolkit';
import {
persistStore,
persistReducer,
FLUSH,
REHYDRATE,
PAUSE,
PERSIST,
PURGE,
REGISTER,
} from 'redux-persist';
import AsyncStorage from '@react-native-async-storage/async-storage';
const persistConfig = {
key: 'root',
storage: AsyncStorage,
whitelist: ['auth', 'user', 'children', 'activities'],
blacklist: ['ui', 'sync'], // Don't persist UI state
};
const rootReducer = combineReducers({
auth: authReducer,
user: userReducer,
family: familyReducer,
children: childrenReducer,
activities: activitiesReducer,
ai: aiReducer,
sync: syncReducer,
offline: offlineReducer,
ui: uiReducer,
notifications: notificationsReducer,
analytics: analyticsReducer,
});
const persistedReducer = persistReducer(persistConfig, rootReducer);
export const store = configureStore({
reducer: persistedReducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: {
ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
},
}).concat([
syncMiddleware,
offlineMiddleware,
analyticsMiddleware,
conflictResolutionMiddleware,
]),
});
export const persistor = persistStore(store);
```
### Sync Middleware
```typescript
// middleware/syncMiddleware.ts
export const syncMiddleware: Middleware = (store) => (next) => (action) => {
const result = next(action);
// Queue actions for sync
if (action.type.includes('activities/') && !action.meta?.skipSync) {
const state = store.getState();
if (!state.offline.isOnline) {
store.dispatch(addToQueue({
type: 'UPDATE',
entity: 'activity',
payload: action.payload,
}));
} else {
// Sync immediately
syncActivity(action.payload);
}
}
return result;
};
```
### Offline Middleware
```typescript
// middleware/offlineMiddleware.ts
export const offlineMiddleware: Middleware = (store) => (next) => (action) => {
// Check network status
if (action.type === 'network/statusChanged') {
const isOnline = action.payload;
if (isOnline && store.getState().sync.queue.length > 0) {
// Process offline queue
store.dispatch(processOfflineQueue());
}
}
// Handle optimistic updates
if (action.meta?.offline) {
const { effect, commit, rollback } = action.meta.offline;
// Apply optimistic update
next(action);
// Attempt sync
effect()
.then(() => next(commit))
.catch(() => next(rollback));
return;
}
return next(action);
};
```
---
## Selectors
### Memoized Selectors
```typescript
// selectors/activities.ts
import { createSelector } from '@reduxjs/toolkit';
export const selectActivitiesByChild = createSelector(
[(state: RootState) => state.activities.activities.byId,
(state: RootState, childId: string) => state.activities.activities.byChild[childId]],
(byId, activityIds = []) =>
activityIds.map(id => byId[id]).filter(Boolean)
);
export const selectTodaysSummary = createSelector(
[(state: RootState, childId: string) => selectActivitiesByChild(state, childId)],
(activities) => {
const today = new Date().toDateString();
const todaysActivities = activities.filter(
a => new Date(a.timestamp).toDateString() === today
);
return {
feedings: todaysActivities.filter(a => a.type === 'feeding').length,
sleepHours: calculateSleepHours(todaysActivities),
diapers: todaysActivities.filter(a => a.type === 'diaper').length,
};
}
);
```
---
## Conflict Resolution
### Conflict Resolution Strategy
```typescript
// utils/conflictResolution.ts
export const resolveConflict = (
local: Activity,
remote: Activity
): Activity => {
// Last write wins for simple conflicts
if (local.version === remote.version) {
return local.timestamp > remote.timestamp ? local : remote;
}
// Server version is higher - merge changes
if (remote.version > local.version) {
return {
...remote,
// Preserve local notes if different
details: {
...remote.details,
notes: local.details.notes !== remote.details.notes
? `${remote.details.notes}\n---\n${local.details.notes}`
: remote.details.notes,
},
};
}
// Local version is higher
return local;
};
```
---
## Performance Optimizations
### Normalized State Updates
```typescript
// Batch updates for performance
const activitiesSlice = createSlice({
name: 'activities',
reducers: {
activitiesBatchUpdated: (state, action) => {
const activities = action.payload;
// Use immer's batching
activities.forEach(activity => {
state.activities.byId[activity.id] = activity;
if (!state.activities.allIds.includes(activity.id)) {
state.activities.allIds.push(activity.id);
}
});
},
},
});
```
### Lazy Loading
```typescript
// Lazy load historical data
export const loadMoreActivities = createAsyncThunk(
'activities/loadMore',
async ({ cursor, limit = 20 }, { getState }) => {
const response = await api.getActivities({ cursor, limit });
return response.data;
},
{
condition: (_, { getState }) => {
const state = getState() as RootState;
return !state.activities.pagination.isLoading;
},
}
);
```

View File

@@ -0,0 +1,420 @@
# Technical Stack - Open Source Technologies for Maternal Organization App
## Mobile Application Development
### Cross-Platform Framework
- **React Native** (Primary Choice)
- `react-native`: Core framework
- `react-native-cli`: Command line interface
- `expo`: Development toolchain and libraries
- `react-navigation`: Navigation library
- `react-native-paper`: Material Design components
- `react-native-elements`: UI toolkit
### Alternative Native Development
- **Flutter** (Alternative Option)
- `flutter`: Core SDK
- `flutter_bloc`: State management
- `provider`: Dependency injection
- `get_it`: Service locator
- `dio`: HTTP client
### State Management
- **Redux Toolkit**
- `@reduxjs/toolkit`: Modern Redux with less boilerplate
- `react-redux`: React bindings
- `redux-persist`: Offline data persistence
- `redux-offline`: Offline-first functionality
- `redux-saga`: Side effects management
### Local Database & Storage
- **SQLite** (Primary local database)
- `react-native-sqlite-storage`: SQLite for React Native
- `typeorm`: Object-relational mapping
- `realm`: Alternative mobile database
- **Async Storage**
- `@react-native-async-storage/async-storage`: Key-value storage
- `react-native-mmkv`: Fast key-value storage alternative
## Backend Infrastructure
### Core Backend Framework
- **Node.js** with **NestJS**
- `@nestjs/core`: Enterprise-grade Node.js framework
- `@nestjs/common`: Common utilities
- `@nestjs/platform-express`: Express adapter
- `@nestjs/microservices`: Microservices support
- `@nestjs/websockets`: WebSocket support
- `@nestjs/graphql`: GraphQL integration
### API Development
- **GraphQL**
- `apollo-server-express`: GraphQL server
- `type-graphql`: TypeScript GraphQL framework
- `graphql-subscriptions`: Real-time subscriptions
- `graphql-upload`: File upload handling
- **REST API**
- `express`: Web framework
- `fastify`: Alternative high-performance framework
- `cors`: Cross-origin resource sharing
- `helmet`: Security headers
- `compression`: Response compression
### Database Systems
- **PostgreSQL** (Primary database)
- `pg`: PostgreSQL client
- `knex`: SQL query builder
- `prisma`: Modern ORM
- `typeorm`: Alternative ORM
- **MongoDB** (Document storage)
- `mongoose`: MongoDB object modeling
- `mongodb`: Native driver
### Caching & Performance
- **Redis**
- `redis`: Redis client
- `ioredis`: Advanced Redis client
- `bull`: Queue management
- `node-cache`: In-memory caching
- **Elasticsearch** (Search & analytics)
- `@elastic/elasticsearch`: Official client
- `searchkit`: Search UI components
## AI & Machine Learning
### LLM Integration (Proprietary APIs)
- **OpenAI API** / **Anthropic Claude API** / **Google Gemini API**
- **LangChain** (Framework)
- `langchain`: Core library
- `@langchain/community`: Community integrations
- `@langchain/openai`: OpenAI integration
### Open Source ML/AI
- **TensorFlow.js**
- `@tensorflow/tfjs`: Core library
- `@tensorflow/tfjs-node`: Node.js bindings
- `@tensorflow/tfjs-react-native`: React Native support
- **ONNX Runtime**
- `onnxruntime-node`: Node.js inference
- `onnxruntime-react-native`: Mobile inference
### Natural Language Processing
- **Natural**
- `natural`: General NLP tasks
- `compromise`: Natural language understanding
- `sentiment`: Sentiment analysis
- `franc`: Language detection
### Pattern Recognition & Analytics
- **Time Series Analysis**
- `timeseries-analysis`: Time series forecasting
- `simple-statistics`: Statistical functions
- `regression`: Regression analysis
- **Data Processing**
- `pandas-js`: Data manipulation
- `dataframe-js`: DataFrame operations
- `ml-js`: Machine learning algorithms
## Real-Time Communication
### WebSocket & Real-Time Sync
- **Socket.io**
- `socket.io`: Server implementation
- `socket.io-client`: Client library
- `socket.io-redis`: Redis adapter for scaling
### Push Notifications
- **Firebase Cloud Messaging** (Free tier available)
- `firebase-admin`: Server SDK
- `react-native-firebase`: React Native integration
- **Alternative: Expo Push Notifications**
- `expo-notifications`: Notification handling
- `expo-server-sdk`: Server implementation
## Voice & Audio Processing
### Voice Input & Recognition
- **Whisper** (OpenAI's open source)
- `whisper`: Speech recognition
- `react-native-voice`: Voice recognition wrapper
- **Web Speech API**
- `react-speech-kit`: React speech components
- `speech-to-text`: Browser-based recognition
### Audio Processing
- **FFmpeg**
- `fluent-ffmpeg`: Node.js wrapper
- `react-native-ffmpeg`: Mobile integration
- **Web Audio API**
- `tone.js`: Audio synthesis and effects
- `wavesurfer.js`: Audio visualization
## Security & Privacy
### Authentication & Authorization
- **Supabase** (Open source Firebase alternative)
- `@supabase/supabase-js`: Client library
- `@supabase/auth-helpers`: Authentication utilities
- **Passport.js**
- `passport`: Authentication middleware
- `passport-jwt`: JWT strategy
- `passport-local`: Local strategy
### Encryption & Security
- **Cryptography**
- `bcrypt`: Password hashing
- `jsonwebtoken`: JWT tokens
- `crypto-js`: Encryption utilities
- `node-forge`: Cryptography toolkit
- **Security Middleware**
- `helmet`: Security headers
- `express-rate-limit`: Rate limiting
- `express-validator`: Input validation
- `hpp`: HTTP parameter pollution prevention
### COPPA/GDPR Compliance
- **Age Verification**
- `age-calculator`: Age calculation utilities
- Custom implementation required
- **Data Privacy**
- `anonymize`: Data anonymization
- `gdpr-guard`: GDPR compliance helpers
## File & Media Management
### Image Processing
- **Sharp**
- `sharp`: High-performance image processing
- `react-native-image-resizer`: Mobile image resizing
- `react-native-image-picker`: Image selection
### File Storage
- **MinIO** (Self-hosted S3-compatible)
- `minio`: Object storage server
- `multer`: File upload middleware
- `multer-s3`: S3 storage engine
### Document Processing
- **PDF Generation**
- `pdfkit`: PDF generation
- `puppeteer`: HTML to PDF conversion
- `react-native-pdf`: PDF viewing
## Calendar & Scheduling
### Calendar Integration
- **Calendar Libraries**
- `node-ical`: iCal parsing
- `ical-generator`: iCal generation
- `react-native-calendars`: Calendar components
- `react-big-calendar`: Web calendar component
### Scheduling
- **Cron Jobs**
- `node-cron`: Task scheduling
- `agenda`: Job scheduling
- `bull`: Queue-based job processing
## Integration Libraries
### External Service Integrations
- **Google APIs**
- `googleapis`: Google services client
- `@react-native-google-signin/google-signin`: Google sign-in
- **Microsoft Graph**
- `@microsoft/microsoft-graph-client`: Graph API client
- **School Platforms**
- Custom API integrations required
- `axios`: HTTP client for API calls
### Smart Home Integration
- **Home Assistant**
- `home-assistant-js-websocket`: WebSocket client
- **Voice Assistants**
- `ask-sdk`: Alexa Skills Kit
- `actions-on-google`: Google Assistant
## Data Visualization & Analytics
### Charting Libraries
- **D3.js Ecosystem**
- `d3`: Core visualization library
- `react-native-svg`: SVG support for React Native
- `victory-native`: React Native charts
- **Chart.js**
- `chart.js`: Charting library
- `react-chartjs-2`: React wrapper
- `react-native-chart-kit`: React Native charts
### Analytics
- **Matomo** (Open source analytics)
- `matomo-tracker`: Analytics tracking
- **PostHog** (Open source product analytics)
- `posthog-js`: JavaScript client
- `posthog-react-native`: React Native client
## Development Tools
### Testing Frameworks
- **Unit Testing**
- `jest`: Testing framework
- `@testing-library/react-native`: React Native testing
- `enzyme`: Component testing
- **E2E Testing**
- `detox`: React Native E2E testing
- `appium`: Cross-platform mobile testing
- `cypress`: Web testing
### Code Quality
- **Linting & Formatting**
- `eslint`: JavaScript linter
- `prettier`: Code formatter
- `husky`: Git hooks
- `lint-staged`: Pre-commit linting
### Development Environment
- **Build Tools**
- `webpack`: Module bundler
- `babel`: JavaScript compiler
- `metro`: React Native bundler
- **Development Servers**
- `nodemon`: Node.js auto-restart
- `concurrently`: Run multiple commands
- `dotenv`: Environment variables
## DevOps & Infrastructure
### Container Orchestration
- **Docker**
- `docker`: Containerization
- `docker-compose`: Multi-container apps
- **Kubernetes** (for scaling)
- `kubernetes`: Container orchestration
- `helm`: Kubernetes package manager
### CI/CD
- **GitHub Actions** / **GitLab CI** / **Jenkins**
- `semantic-release`: Automated versioning
- `standard-version`: Changelog generation
### Monitoring & Logging
- **Sentry** (Open source error tracking)
- `@sentry/node`: Node.js SDK
- `@sentry/react-native`: React Native SDK
- **Winston** (Logging)
- `winston`: Logging library
- `morgan`: HTTP request logger
### Message Queue
- **RabbitMQ**
- `amqplib`: RabbitMQ client
- **Apache Kafka** (for high scale)
- `kafkajs`: Kafka client
## Additional Utilities
### Date & Time
- `dayjs`: Lightweight date library
- `date-fns`: Date utility library
- `moment-timezone`: Timezone handling
- `react-native-date-picker`: Date picker component
### Forms & Validation
- `react-hook-form`: Form management
- `yup`: Schema validation
- `joi`: Object schema validation
- `react-native-masked-text`: Input masking
### Localization
- `i18next`: Internationalization framework
- `react-i18next`: React integration
- `react-native-localize`: Device locale detection
### Utilities
- `lodash`: Utility functions
- `uuid`: UUID generation
- `validator`: String validators
- `numeral`: Number formatting
## Infrastructure Services (Self-Hosted Options)
### Backend as a Service
- **Supabase** (Complete backend solution)
- **Appwrite** (Alternative BaaS)
- **Parse Server** (Mobile backend)
### Search Infrastructure
- **Meilisearch** (Fast search engine)
- **Typesense** (Typo-tolerant search)
### Email Service
- **Nodemailer** with SMTP
- **SendGrid** (Free tier available)
- **Postal** (Self-hosted)
## Performance Optimization
### Mobile Performance
- `react-native-fast-image`: Optimized image loading
- `react-native-super-grid`: Efficient grid rendering
- `recyclerlistview`: High-performance lists
- `react-native-reanimated`: Smooth animations
### Backend Performance
- `cluster`: Node.js clustering
- `pm2`: Process management
- `compression`: Response compression
- `memory-cache`: In-memory caching
## Accessibility Tools
- `react-native-accessibility`: Accessibility utilities
- `react-native-tts`: Text-to-speech
- `react-native-screen-reader`: Screen reader detection
## Development Recommendations
### Minimum Viable Stack
1. **Frontend**: React Native + Expo
2. **Backend**: NestJS + PostgreSQL
3. **Real-time**: Socket.io
4. **AI**: OpenAI/Claude API + LangChain
5. **Auth**: Supabase Auth
6. **Storage**: MinIO/Supabase Storage
7. **Cache**: Redis
8. **Search**: Meilisearch
### Scalability Considerations
- Start with monolithic backend, prepare for microservices
- Use message queues early for async operations
- Implement caching strategy from day one
- Design for offline-first mobile experience
- Plan for horizontal scaling with Kubernetes
### Security Priorities
- Implement end-to-end encryption for sensitive data
- Use JWT with refresh tokens
- Apply rate limiting on all endpoints
- Regular security audits with OWASP tools
- COPPA/GDPR compliance from the start

View File

@@ -0,0 +1,575 @@
# Testing Strategy Document - Maternal Organization App
## Testing Philosophy
### Core Principles
- **User-Centric Testing**: Focus on real parent workflows
- **Offline-First Validation**: Test sync and conflict resolution
- **AI Response Quality**: Verify helpful, safe responses
- **Accessibility Testing**: Ensure one-handed operation works
- **Performance Under Stress**: Test with interrupted network, low battery
### Coverage Goals
- **Unit Tests**: 80% code coverage
- **Integration Tests**: All API endpoints
- **E2E Tests**: Critical user journeys
- **Performance**: Sub-3 second response times
- **Accessibility**: WCAG AA compliance
---
## Unit Testing
### Test Structure
```javascript
// Standard test file naming
ComponentName.test.tsx
ServiceName.test.ts
utils.test.ts
```
### Component Testing Example
```typescript
// FeedingTracker.test.tsx
describe('FeedingTracker', () => {
it('should start timer on breast feeding selection', () => {
const { getByTestId } = render(<FeedingTracker childId="chd_123" />);
fireEvent.press(getByTestId('breast-left-button'));
expect(getByTestId('timer-display')).toBeTruthy();
});
it('should validate minimum feeding duration', () => {
const onSave = jest.fn();
const { getByTestId } = render(<FeedingTracker onSave={onSave} />);
fireEvent.press(getByTestId('save-button'));
expect(getByTestId('error-message')).toHaveTextContent('Feeding too short');
expect(onSave).not.toHaveBeenCalled();
});
});
```
### Service Testing Example
```typescript
// SleepPredictionService.test.ts
describe('SleepPredictionService', () => {
it('should predict nap time within 30 minutes', async () => {
const mockSleepData = generateMockSleepHistory(7); // 7 days
const prediction = await service.predictNextNap('chd_123', mockSleepData);
expect(prediction.confidence).toBeGreaterThan(0.7);
expect(prediction.predictedTime).toBeInstanceOf(Date);
expect(prediction.wakeWindow).toBeBetween(90, 180); // minutes
});
});
```
### Redux Testing
```typescript
// trackingSlice.test.ts
describe('tracking reducer', () => {
it('should handle activity logged', () => {
const action = activityLogged({
id: 'act_123',
type: 'feeding',
timestamp: new Date().toISOString()
});
const newState = trackingReducer(initialState, action);
expect(newState.activities).toHaveLength(1);
expect(newState.lastSync).toBeDefined();
});
});
```
---
## Integration Testing
### API Endpoint Testing
```typescript
// auth.integration.test.ts
describe('POST /api/v1/auth/register', () => {
it('should create user with family', async () => {
const response = await request(app)
.post('/api/v1/auth/register')
.send({
email: 'test@example.com',
password: 'SecurePass123!',
name: 'Test User'
});
expect(response.status).toBe(201);
expect(response.body.data).toHaveProperty('user.id');
expect(response.body.data).toHaveProperty('family.shareCode');
expect(response.body.data.tokens.accessToken).toMatch(/^eyJ/);
});
it('should enforce password requirements', async () => {
const response = await request(app)
.post('/api/v1/auth/register')
.send({
email: 'test@example.com',
password: 'weak'
});
expect(response.status).toBe(400);
expect(response.body.error.code).toBe('VALIDATION_ERROR');
});
});
```
### WebSocket Testing
```typescript
// realtime.integration.test.ts
describe('Family Activity Sync', () => {
let client1, client2;
beforeEach((done) => {
client1 = io('http://localhost:3000', {
auth: { token: 'parent1_token' }
});
client2 = io('http://localhost:3000', {
auth: { token: 'parent2_token' }
});
done();
});
it('should broadcast activity to family members', (done) => {
client2.on('activity-logged', (data) => {
expect(data.activityId).toBe('act_123');
expect(data.type).toBe('feeding');
done();
});
client1.emit('log-activity', {
type: 'feeding',
childId: 'chd_123'
});
});
});
```
---
## E2E Testing with Detox
### Critical User Journeys
```javascript
// e2e/criticalPaths.e2e.js
describe('Onboarding Flow', () => {
beforeAll(async () => {
await device.launchApp({ newInstance: true });
});
it('should complete registration and add first child', async () => {
// Registration
await element(by.id('get-started-button')).tap();
await element(by.id('email-input')).typeText('parent@test.com');
await element(by.id('password-input')).typeText('TestPass123!');
await element(by.id('register-button')).tap();
// Add child
await expect(element(by.id('add-child-screen'))).toBeVisible();
await element(by.id('child-name-input')).typeText('Emma');
await element(by.id('birth-date-picker')).tap();
await element(by.text('15')).tap();
await element(by.id('save-child-button')).tap();
// Verify dashboard
await expect(element(by.text('Emma'))).toBeVisible();
});
});
```
### Offline Sync Testing
```javascript
describe('Offline Activity Logging', () => {
it('should queue activities when offline', async () => {
// Go offline
await device.setURLBlacklist(['.*']);
// Log activity
await element(by.id('quick-log-feeding')).tap();
await element(by.id('amount-input')).typeText('4');
await element(by.id('save-button')).tap();
// Verify local storage
await expect(element(by.id('sync-pending-badge'))).toBeVisible();
// Go online
await device.clearURLBlacklist();
// Verify sync
await waitFor(element(by.id('sync-pending-badge')))
.not.toBeVisible()
.withTimeout(5000);
});
});
```
---
## Mock Data Structures
### User & Family Mocks
```typescript
// mocks/users.ts
export const mockParent = {
id: 'usr_mock1',
email: 'test@example.com',
name: 'Jane Doe',
locale: 'en-US',
timezone: 'America/New_York'
};
export const mockFamily = {
id: 'fam_mock1',
name: 'Test Family',
shareCode: 'TEST01',
members: [mockParent],
children: []
};
```
### Activity Mocks
```typescript
// mocks/activities.ts
export const mockFeeding = {
id: 'act_feed1',
childId: 'chd_mock1',
type: 'feeding',
startTime: '2024-01-10T14:30:00Z',
duration: 15,
details: {
type: 'breast',
side: 'left',
amount: null
}
};
export const generateMockActivities = (days: number) => {
const activities = [];
const now = new Date();
for (let d = 0; d < days; d++) {
// Generate realistic daily pattern
activities.push(
createMockFeeding(subDays(now, d), '07:00'),
createMockSleep(subDays(now, d), '09:00', 90),
createMockFeeding(subDays(now, d), '10:30'),
createMockDiaper(subDays(now, d), '11:00'),
createMockSleep(subDays(now, d), '13:00', 120),
createMockFeeding(subDays(now, d), '15:00')
);
}
return activities;
};
```
### AI Response Mocks
```typescript
// mocks/aiResponses.ts
export const mockAIResponses = {
sleepQuestion: {
message: "Why won't my baby sleep?",
response: "Based on Emma's recent patterns, she may be experiencing the 7-month sleep regression...",
suggestions: [
"Try starting bedtime routine 15 minutes earlier",
"Ensure room temperature is 68-72°F"
],
confidence: 0.85
},
feedingConcern: {
message: "Baby seems hungry all the time",
response: "Increased hunger at 6 months often signals a growth spurt...",
suggestions: [
"Consider increasing feeding frequency temporarily",
"Track wet diapers to ensure adequate intake"
],
confidence: 0.92
}
};
```
---
## Performance Testing
### Load Testing Scenarios
```javascript
// performance/loadTest.js
import http from 'k6/http';
import { check } from 'k6';
export const options = {
stages: [
{ duration: '2m', target: 100 }, // Ramp up
{ duration: '5m', target: 100 }, // Stay at 100 users
{ duration: '2m', target: 0 }, // Ramp down
],
thresholds: {
http_req_duration: ['p(95)<3000'], // 95% requests under 3s
http_req_failed: ['rate<0.1'], // Error rate under 10%
},
};
export default function () {
// Test activity logging endpoint
const payload = JSON.stringify({
childId: 'chd_test',
type: 'feeding',
amount: 120
});
const response = http.post('http://localhost:3000/api/v1/activities/feeding', payload, {
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ${__ENV.TEST_TOKEN}'
},
});
check(response, {
'status is 201': (r) => r.status === 201,
'response time < 500ms': (r) => r.timings.duration < 500,
});
}
```
### Mobile Performance Testing
```typescript
// Mobile performance metrics
describe('Performance Benchmarks', () => {
it('should render dashboard in under 1 second', async () => {
const startTime = Date.now();
await element(by.id('dashboard-screen')).tap();
await expect(element(by.id('activities-list'))).toBeVisible();
const loadTime = Date.now() - startTime;
expect(loadTime).toBeLessThan(1000);
});
it('should handle 1000+ activities smoothly', async () => {
// Test with large dataset
await device.launchApp({
newInstance: true,
launchArgs: { mockLargeDataset: true }
});
// Measure scroll performance
await element(by.id('activities-list')).scroll(500, 'down', NaN, 0.8);
// Should not freeze or stutter
});
});
```
---
## Accessibility Testing
### WCAG Compliance Tests
```typescript
// accessibility/wcag.test.tsx
import { axe, toHaveNoViolations } from 'jest-axe';
expect.extend(toHaveNoViolations);
describe('Accessibility Compliance', () => {
it('should have no WCAG violations on dashboard', async () => {
const { container } = render(<Dashboard />);
const results = await axe(container);
expect(results).toHaveNoViolations();
});
it('should support screen reader navigation', () => {
const { getByLabelText } = render(<FeedingTracker />);
expect(getByLabelText('Log feeding')).toBeTruthy();
expect(getByLabelText('Select breast side')).toBeTruthy();
});
});
```
### One-Handed Operation Tests
```javascript
// e2e/oneHanded.e2e.js
describe('One-Handed Operation', () => {
it('should access all critical functions with thumb', async () => {
const screenHeight = await device.getScreenHeight();
const thumbReach = screenHeight * 0.6; // Bottom 60%
// Verify critical buttons are in thumb zone
const feedButton = await element(by.id('quick-log-feeding')).getLocation();
expect(feedButton.y).toBeGreaterThan(thumbReach);
const sleepButton = await element(by.id('quick-log-sleep')).getLocation();
expect(sleepButton.y).toBeGreaterThan(thumbReach);
});
});
```
---
## AI Testing
### LLM Response Validation
```typescript
// ai/llmResponse.test.ts
describe('AI Assistant Response Quality', () => {
it('should provide contextual responses', async () => {
const context = {
childAge: 7, // months
recentActivities: mockRecentActivities,
query: "baby won't sleep"
};
const response = await aiService.generateResponse(context);
expect(response).toContain('7-month');
expect(response.confidence).toBeGreaterThan(0.7);
expect(response.suggestions).toBeArray();
expect(response.harmfulContent).toBe(false);
});
it('should refuse inappropriate requests', async () => {
const response = await aiService.generateResponse({
query: "diagnose my baby's rash"
});
expect(response).toContain('consult');
expect(response).toContain('healthcare provider');
});
});
```
---
## Test Data Management
### Database Seeding
```typescript
// test/seed.ts
export async function seedTestDatabase() {
await db.clean(); // Clear all data
const family = await createTestFamily();
const parent1 = await createTestUser('parent1@test.com', family.id);
const parent2 = await createTestUser('parent2@test.com', family.id);
const child = await createTestChild('Emma', '2023-06-15', family.id);
// Generate realistic activity history
await generateActivityHistory(child.id, 30); // 30 days
return { family, parent1, parent2, child };
}
```
### Test Isolation
```typescript
// jest.setup.ts
beforeEach(async () => {
await db.transaction.start();
});
afterEach(async () => {
await db.transaction.rollback();
jest.clearAllMocks();
});
```
---
## CI/CD Test Pipeline
### GitHub Actions Configuration
```yaml
# .github/workflows/test.yml
name: Test Suite
on: [push, pull_request]
jobs:
unit-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- run: npm ci
- run: npm run test:unit
- uses: codecov/codecov-action@v2
integration-tests:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:15
redis:
image: redis:7
steps:
- uses: actions/checkout@v2
- run: npm ci
- run: npm run test:integration
e2e-tests:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2
- run: npm ci
- run: npx detox build -c ios.sim.release
- run: npx detox test -c ios.sim.release
```
---
## Test Coverage Requirements
### Minimum Coverage Thresholds
```json
// jest.config.js
{
"coverageThreshold": {
"global": {
"branches": 70,
"functions": 80,
"lines": 80,
"statements": 80
},
"src/services/": {
"branches": 85,
"functions": 90
},
"src/components/": {
"branches": 75,
"functions": 85
}
}
}
```
### Critical Path Coverage
- Authentication flow: 100%
- Activity logging: 95%
- Real-time sync: 90%
- AI responses: 85%
- Offline queue: 90%
---
## Test Reporting
### Test Result Format
```bash
# Console output
PASS src/components/FeedingTracker.test.tsx
✓ should start timer on selection (45ms)
✓ should validate minimum duration (23ms)
✓ should sync with family members (112ms)
Test Suites: 45 passed, 45 total
Tests: 234 passed, 234 total
Coverage: 82% statements, 78% branches
Time: 12.456s
```
### Coverage Reports
- HTML reports in `/coverage/lcov-report/`
- Codecov integration for PR comments
- SonarQube for code quality metrics

View File

@@ -0,0 +1,590 @@
# Voice Input Processing Guide - Maternal Organization App
## Voice Processing Architecture
### Overview
Voice input enables hands-free logging during childcare activities. The system processes natural language in 5 languages, extracting structured data from casual speech patterns.
### Processing Pipeline
```
Audio Input → Speech Recognition → Language Detection →
Intent Classification → Entity Extraction → Action Execution →
Confirmation Feedback
```
---
## Whisper API Integration
### Configuration
```typescript
// services/whisperService.ts
import OpenAI from 'openai';
class WhisperService {
private client: OpenAI;
constructor() {
this.client = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
}
async transcribeAudio(audioBuffer: Buffer, language?: string): Promise<TranscriptionResult> {
try {
const response = await this.client.audio.transcriptions.create({
file: audioBuffer,
model: 'whisper-1',
language: language || 'en', // ISO-639-1 code
response_format: 'verbose_json',
timestamp_granularities: ['word'],
});
return {
text: response.text,
language: response.language,
confidence: this.calculateConfidence(response),
words: response.words,
};
} catch (error) {
return this.handleTranscriptionError(error);
}
}
}
```
### Audio Preprocessing
```typescript
// utils/audioPreprocessing.ts
export const preprocessAudio = async (audioFile: File): Promise<Buffer> => {
// Validate format
const validFormats = ['wav', 'mp3', 'm4a', 'webm'];
if (!validFormats.includes(getFileExtension(audioFile))) {
throw new Error('Unsupported audio format');
}
// Check file size (max 25MB for Whisper)
if (audioFile.size > 25 * 1024 * 1024) {
// Compress or chunk the audio
return await compressAudio(audioFile);
}
// Noise reduction for better accuracy
return await reduceNoise(audioFile);
};
```
---
## Natural Language Command Patterns
### Intent Classification
```typescript
enum VoiceIntent {
LOG_FEEDING = 'LOG_FEEDING',
LOG_SLEEP = 'LOG_SLEEP',
LOG_DIAPER = 'LOG_DIAPER',
LOG_MEDICATION = 'LOG_MEDICATION',
START_TIMER = 'START_TIMER',
STOP_TIMER = 'STOP_TIMER',
ASK_QUESTION = 'ASK_QUESTION',
CHECK_STATUS = 'CHECK_STATUS',
CANCEL = 'CANCEL'
}
interface IntentPattern {
intent: VoiceIntent;
patterns: RegExp[];
requiredEntities: string[];
examples: string[];
}
```
### English Language Patterns
```typescript
const englishPatterns: IntentPattern[] = [
{
intent: VoiceIntent.LOG_FEEDING,
patterns: [
/(?:baby |she |he )?(?:fed|ate|drank|had|nursed)/i,
/(?:bottle|breast|nursing|feeding)/i,
/(?:finished|done) (?:eating|feeding|nursing)/i,
],
requiredEntities: ['amount?', 'time?', 'type?'],
examples: [
"Baby fed 4 ounces",
"Just nursed for 15 minutes on the left",
"She had 120ml of formula at 3pm",
"Finished feeding, both sides, 20 minutes total"
]
},
{
intent: VoiceIntent.LOG_SLEEP,
patterns: [
/(?:went|going) (?:to )?(?:sleep|bed|nap)/i,
/(?:woke|wake|waking) up/i,
/(?:nap|sleep)(?:ping|ed)? (?:for|since)/i,
/(?:fell) asleep/i,
],
requiredEntities: ['time?', 'duration?'],
examples: [
"Down for a nap",
"Woke up from nap",
"Sleeping since 2pm",
"Just fell asleep in the stroller"
]
},
{
intent: VoiceIntent.LOG_DIAPER,
patterns: [
/(?:chang|dirty|wet|soil|poop|pee)/i,
/diaper/i,
/(?:number|#) (?:one|two|1|2)/i,
],
requiredEntities: ['type?'],
examples: [
"Changed wet diaper",
"Dirty diaper with rash",
"Just changed a poopy one",
"Diaper change, both wet and dirty"
]
}
];
```
### Multi-Language Patterns
```typescript
// Spanish patterns
const spanishPatterns: IntentPattern[] = [
{
intent: VoiceIntent.LOG_FEEDING,
patterns: [
/(?:comió|tomó|bebió|amamanté)/i,
/(?:biberón|pecho|lactancia)/i,
],
examples: [
"Tomó 120ml de fórmula",
"Amamanté 15 minutos lado izquierdo",
"Ya comió papilla"
]
}
];
// French patterns
const frenchPatterns: IntentPattern[] = [
{
intent: VoiceIntent.LOG_FEEDING,
patterns: [
/(?:mangé|bu|allaité|nourri)/i,
/(?:biberon|sein|tétée)/i,
],
examples: [
"Biberon de 120ml",
"Allaité 15 minutes côté gauche",
"A mangé sa purée"
]
}
];
// Portuguese patterns
const portuguesePatterns: IntentPattern[] = [
{
intent: VoiceIntent.LOG_FEEDING,
patterns: [
/(?:comeu|tomou|bebeu|amamentei)/i,
/(?:mamadeira|peito|amamentação)/i,
],
examples: [
"Tomou 120ml de fórmula",
"Amamentei 15 minutos lado esquerdo"
]
}
];
// Chinese patterns
const chinesePatterns: IntentPattern[] = [
{
intent: VoiceIntent.LOG_FEEDING,
patterns: [
/(?:喂|吃|喝|哺乳)/,
/(?:奶瓶|母乳|配方奶)/,
],
examples: [
"喝了120毫升配方奶",
"母乳喂养15分钟",
"吃了辅食"
]
}
];
```
---
## Entity Extraction
### Entity Types
```typescript
interface ExtractedEntities {
amount?: {
value: number;
unit: 'oz' | 'ml' | 'minutes';
};
time?: {
value: Date;
precision: 'exact' | 'approximate';
};
duration?: {
value: number;
unit: 'minutes' | 'hours';
};
side?: 'left' | 'right' | 'both';
type?: 'breast' | 'bottle' | 'solid' | 'wet' | 'dirty' | 'both';
location?: string;
notes?: string;
}
```
### Extraction Logic
```typescript
class EntityExtractor {
extractAmount(text: string): ExtractedEntities['amount'] {
// Numeric amounts with units
const amountPattern = /(\d+(?:\.\d+)?)\s*(oz|ounce|ml|milliliter|minute|min)/i;
const match = text.match(amountPattern);
if (match) {
return {
value: parseFloat(match[1]),
unit: this.normalizeUnit(match[2])
};
}
// Word numbers
const wordNumbers = {
'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5,
'ten': 10, 'fifteen': 15, 'twenty': 20, 'thirty': 30,
};
for (const [word, value] of Object.entries(wordNumbers)) {
if (text.includes(word)) {
return { value, unit: this.inferUnit(text) };
}
}
return undefined;
}
extractTime(text: string, timezone: string): ExtractedEntities['time'] {
const now = new Date();
// Relative times
if (/just|now|right now/i.test(text)) {
return { value: now, precision: 'exact' };
}
if (/ago/i.test(text)) {
const minutesAgo = this.extractMinutesAgo(text);
return {
value: new Date(now.getTime() - minutesAgo * 60000),
precision: 'approximate'
};
}
// Clock times
const timePattern = /(\d{1,2}):?(\d{2})?\s*(am|pm)?/i;
const match = text.match(timePattern);
if (match) {
return {
value: this.parseClockTime(match, timezone),
precision: 'exact'
};
}
return { value: now, precision: 'approximate' };
}
extractSide(text: string): ExtractedEntities['side'] {
if (/left|izquierdo|gauche|esquerdo|左/i.test(text)) return 'left';
if (/right|derecho|droit|direito|右/i.test(text)) return 'right';
if (/both|ambos|deux|ambos|两|両/i.test(text)) return 'both';
return undefined;
}
}
```
---
## Intent Processing Engine
### Main Processing Flow
```typescript
class VoiceCommandProcessor {
async processVoiceInput(
audioBuffer: Buffer,
context: UserContext
): Promise<ProcessedCommand> {
// 1. Transcribe audio
const transcription = await this.whisperService.transcribeAudio(
audioBuffer,
context.language
);
if (transcription.confidence < 0.5) {
return this.handleLowConfidence(transcription);
}
// 2. Detect intent
const intent = await this.detectIntent(
transcription.text,
context.language
);
// 3. Extract entities
const entities = await this.extractEntities(
transcription.text,
intent,
context
);
// 4. Validate command
const validation = this.validateCommand(intent, entities);
if (!validation.isValid) {
return this.requestClarification(validation.missingInfo);
}
// 5. Execute action
return this.executeCommand(intent, entities, context);
}
private async detectIntent(
text: string,
language: string
): Promise<VoiceIntent> {
const patterns = this.getPatternsByLanguage(language);
for (const pattern of patterns) {
for (const regex of pattern.patterns) {
if (regex.test(text)) {
return pattern.intent;
}
}
}
// Fallback to AI intent detection
return this.detectIntentWithAI(text, language);
}
}
```
---
## Error Recovery
### Common Recognition Errors
```typescript
interface RecognitionError {
type: 'LOW_CONFIDENCE' | 'AMBIGUOUS' | 'MISSING_DATA' | 'INVALID_VALUE';
originalText: string;
suggestions?: string[];
}
class ErrorRecovery {
handleLowConfidence(transcription: TranscriptionResult): ProcessedCommand {
// Check for common misheard phrases
const corrections = this.checkCommonMishears(transcription.text);
if (corrections.confidence > 0.7) {
return this.retryWithCorrection(corrections.text);
}
return {
success: false,
action: 'CONFIRM',
message: `Did you say "${transcription.text}"?`,
alternatives: this.getSimilarPhrases(transcription.text)
};
}
checkCommonMishears(text: string): CorrectionResult {
const corrections = {
'for ounces': 'four ounces',
'to ounces': 'two ounces',
'write side': 'right side',
'laugh side': 'left side',
'wet and dirty': 'wet and dirty',
'wedding dirty': 'wet and dirty',
};
for (const [misheard, correct] of Object.entries(corrections)) {
if (text.includes(misheard)) {
return {
text: text.replace(misheard, correct),
confidence: 0.8
};
}
}
return { text, confidence: 0.3 };
}
}
```
### Clarification Prompts
```typescript
const clarificationPrompts = {
MISSING_AMOUNT: {
en: "How much did baby eat?",
es: "¿Cuánto comió el bebé?",
fr: "Combien a mangé bébé?",
pt: "Quanto o bebê comeu?",
zh: "宝宝吃了多少?"
},
MISSING_TIME: {
en: "When did this happen?",
es: "¿Cuándo ocurrió esto?",
fr: "Quand cela s'est-il passé?",
pt: "Quando isso aconteceu?",
zh: "这是什么时候发生的?"
},
AMBIGUOUS_INTENT: {
en: "What would you like to log?",
es: "¿Qué te gustaría registrar?",
fr: "Que souhaitez-vous enregistrer?",
pt: "O que você gostaria de registrar?",
zh: "您想记录什么?"
}
};
```
---
## Offline Voice Processing
### Fallback Strategy
```typescript
class OfflineVoiceProcessor {
async processOffline(audioBuffer: Buffer): Promise<BasicTranscription> {
// Use device's native speech recognition
if (Platform.OS === 'ios') {
return this.useiOSSpeechRecognition(audioBuffer);
} else if (Platform.OS === 'android') {
return this.useAndroidSpeechRecognition(audioBuffer);
}
// Queue for later processing
return this.queueForOnlineProcessing(audioBuffer);
}
private async useiOSSpeechRecognition(audio: Buffer) {
// Use SFSpeechRecognizer
const recognizer = new SFSpeechRecognizer();
return recognizer.recognize(audio);
}
private async useAndroidSpeechRecognition(audio: Buffer) {
// Use Android SpeechRecognizer
const recognizer = new AndroidSpeechRecognizer();
return recognizer.recognize(audio);
}
}
```
---
## Confirmation & Feedback
### Voice Feedback System
```typescript
interface VoiceConfirmation {
text: string;
speech: string; // SSML for TTS
visual: {
icon: string;
color: string;
animation: string;
};
haptic?: 'success' | 'warning' | 'error';
}
const confirmations = {
FEEDING_LOGGED: {
text: "Feeding logged",
speech: "<speak>Got it! <break time='200ms'/> Logged <say-as interpret-as='cardinal'>4</say-as> ounces.</speak>",
visual: {
icon: 'check_circle',
color: 'success',
animation: 'bounce'
},
haptic: 'success'
}
};
```
---
## Testing Voice Commands
### Test Scenarios
```typescript
const voiceTestCases = [
// English
{ input: "Baby ate 4 ounces", expected: { intent: 'LOG_FEEDING', amount: 4, unit: 'oz' }},
{ input: "Nursed for fifteen minutes on the left", expected: { intent: 'LOG_FEEDING', duration: 15, side: 'left' }},
// Spanish
{ input: "Tomó 120 mililitros", expected: { intent: 'LOG_FEEDING', amount: 120, unit: 'ml' }},
// Edge cases
{ input: "Fed... um... about 4 or 5 ounces", expected: { intent: 'LOG_FEEDING', amount: 4, confidence: 'low' }},
{ input: "Changed a really dirty diaper", expected: { intent: 'LOG_DIAPER', type: 'dirty', notes: 'really dirty' }},
];
```
---
## Performance Optimization
### Audio Streaming
```typescript
class StreamingVoiceProcessor {
private audioChunks: Buffer[] = [];
private isProcessing = false;
async processStream(chunk: Buffer) {
this.audioChunks.push(chunk);
if (!this.isProcessing && this.hasEnoughAudio()) {
this.isProcessing = true;
const result = await this.processChunks();
this.isProcessing = false;
return result;
}
}
private hasEnoughAudio(): boolean {
// Need at least 0.5 seconds of audio
const totalSize = this.audioChunks.reduce((sum, chunk) => sum + chunk.length, 0);
return totalSize > 8000; // ~0.5s at 16kHz
}
}
```
### Caching Common Commands
```typescript
const commandCache = new LRUCache<string, ProcessedCommand>({
max: 100,
ttl: 1000 * 60 * 60, // 1 hour
});
// Cache exact matches for common phrases
const cachedPhrases = [
"wet diaper",
"dirty diaper",
"just nursed",
"bottle feeding done",
"down for a nap",
"woke up"
];
```

View File

@@ -0,0 +1,87 @@
# The overwhelmed mother's digital lifeline: Building an AI-powered organization app for modern parenting
Mothers carry **71% of household mental load** while managing careers, childcare, and their own wellbeing - often with minimal support. With 10-20% experiencing untreated perinatal mental health conditions globally and 90% facing career-threatening challenges upon returning to work, the need for intelligent digital support has never been more critical. This comprehensive analysis reveals how an AI-powered app can transform the chaos of modern motherhood into manageable, predictable routines that actually work.
## The hidden crisis modern mothers face daily
The data paints a stark picture of maternal overwhelm that crosses all demographics and geographies. **Mothers handle 79% of daily household tasks** - over twice the contribution of fathers - while simultaneously managing complex schedules, making thousands of micro-decisions, and often sacrificing their own sleep and wellbeing. The mental load crisis is quantifiable: women perform nearly 4 hours of unpaid work daily compared to men's 2.5 hours globally, with mothers reporting feeling rushed 86% of the time.
Mental health challenges compound these organizational struggles. Postpartum depression affects 13-20% of mothers worldwide, yet **75% remain untreated** due to stigma, access barriers, and time constraints. In developing countries, rates climb to 19.8% postpartum. The economic toll is staggering - untreated maternal mental health conditions cost $14.2 billion annually in the US alone, or $32,000 per mother-infant pair. Sleep deprivation peaks during infancy, with mothers losing an average of 42 minutes nightly, while 40.3% of infants aged 4-11 months don't meet recommended sleep durations, creating a destructive cycle of exhaustion.
The work-life balance struggle intensifies these challenges. Nine out of ten working mothers face at least one major career-threatening challenge, with 57% of those with children under five feeling professionally held back. **Half of all employees with children** have considered leaving their organization due to inadequate childcare support. The partnership gap adds another layer - 74% of mothers manage children's schedules compared to their partners, and men consistently overestimate their household contributions, leading to resentment and conflict.
## Current solutions fall short of mothers' complex needs
The parenting app market, valued at $1.45-2.0 billion and growing at 7.8-20.37% annually, offers fragmented solutions that fail to address the holistic nature of maternal challenges. While apps like Huckleberry excel at sleep prediction with 93% success rates among 4 million users, and Cozi provides color-coded calendars for family coordination, **no single platform integrates all aspects** of maternal organization with intelligent automation.
Major gaps plague existing solutions. Integration between different apps remains poor, forcing mothers to manage multiple platforms. AI capabilities are limited to basic pattern recognition rather than predictive, proactive support. Community features often devolve into toxic environments - BabyCenter's 1.8/5 Trustpilot rating stems from "mean girl mob mentality" and poor moderation. Platform inconsistencies frustrate users, with features working differently across web and mobile versions. Perhaps most critically, current apps treat symptoms rather than addressing the underlying mental load problem.
User complaints reveal deep dissatisfaction with generic, copy-pasted advice that ignores individual family contexts. Peanut's "Tinder for moms" concept struggles to create meaningful connections, with users reporting difficulty converting matches to real friendships. Premium pricing feels steep for basic features - Huckleberry charges $58.99 annually for sleep recommendations that become less useful once children enter daycare. The market clearly demands a comprehensive, intelligent solution that grows with families rather than forcing them to constantly switch platforms.
## AI transforms overwhelming complexity into manageable routines
The most promising AI implementations demonstrate remarkable potential for reducing maternal burden. Huckleberry's SweetSpot® algorithm analyzes hundreds of millions of sleep data points to predict optimal nap times with uncanny accuracy, adapting to individual patterns within 5 days. Their success - trusted by 4 million parents across 179 countries - proves mothers will embrace AI that delivers tangible results. Natural language processing enables voice logging during hands-occupied moments ("baby fed 4oz at 3pm"), while pattern recognition identifies trends humans miss.
Mental health support represents AI's most transformative application. Woebot's randomized controlled trial with 184 postpartum women showed **70% achieving clinically significant improvement** versus 30% in the control group, with participants engaging 5 times weekly on average. The 24/7 availability addresses traditional therapy barriers - cost, stigma, scheduling - while providing immediate crisis support with human escalation protocols. University of Texas researchers are developing specialized chatbots for postpartum depression through Postpartum Support International, recognizing AI's potential to reach underserved mothers.
Practical automation capabilities extend beyond emotional support. Ollie AI's meal planning platform saves families 5 hours weekly through natural language dietary preference processing and automated grocery integration. Google Assistant's Family Features recognize up to 6 family members' voices, enabling personalized responses and parental controls. Microsoft's Document Intelligence processes receipts with 90% accuracy improvement over manual entry, while computer vision applications automatically sort photos by child and milestone. These aren't futuristic concepts - they're proven technologies ready for integration.
## Core MVP features that deliver immediate value
Based on comprehensive research, the MVP must prioritize features addressing the most acute pain points while building toward a comprehensive platform. **Essential tracking capabilities** form the foundation: feeding, sleep, and diaper logging with voice input for hands-free operation. The magic happens when AI analyzes this data - Huckleberry's sleep prediction model demonstrates how pattern recognition transforms raw data into actionable insights. Multi-user access ensures both parents and caregivers stay synchronized, addressing the coordination challenges 74% of mothers face.
The **AI conversational assistant** represents the MVP's breakthrough feature. Available 24/7, it provides evidence-based guidance personalized to each child's patterns and developmental stage. Unlike generic chatbots, it learns from family data to offer increasingly relevant suggestions. Dr. Becky Kennedy's Good Inside app validates this approach with 90,000+ paying members for AI-powered parenting scripts. The assistant should handle everything from "why won't my baby sleep?" to "healthy dinner ideas for picky toddlers," reducing decision fatigue that plagues overwhelmed mothers.
Age-specific adaptations ensure relevance across the 0-6 range. For infants (0-1 year), prioritize feeding schedules, sleep optimization, growth tracking, and vaccination reminders. Toddler features (1-3 years) focus on routine management, potty training progress, and behavioral pattern analysis. Preschool tools (3-6 years) emphasize school readiness, social skill development, and activity coordination. **The platform must grow with families** rather than forcing app-switching as children develop.
Quick-win AI features provide immediate value while building user trust. Smart notifications deliver context-aware reminders based on family patterns - alerting about nap time based on wake windows, suggesting feeding times from hunger cues. Pattern detection identifies correlations mothers might miss: "Your baby sleeps 47 minutes longer after outdoor morning activities." Voice processing allows natural language input during chaotic moments. These features require relatively simple implementation while delivering outsized impact on daily stress.
## Building trust through privacy-first design
Privacy concerns dominate parental technology decisions, making compliance and transparency competitive advantages rather than regulatory burdens. **COPPA compliance in the US** requires verifiable parental consent before collecting data from children under 13, with clear policies describing collection practices. GDPR Article 8 extends protection in Europe, with age thresholds varying by country. The app must implement risk-based verification - email confirmation for low-risk features, credit card verification for medium risk, government ID for high-risk data access.
Security architecture must exceed typical app standards given sensitive family data. End-to-end encryption protects information in transit and at rest. Regular security audits and penetration testing ensure ongoing protection. Multi-factor authentication secures parental accounts while maintaining quick access for authorized caregivers. **Data minimization principles** mean collecting only essential information, with automatic deletion of unnecessary data. Parents must control their data completely - viewing, downloading, and permanently deleting at will.
Transparency builds trust where many apps fail. Clear, plain-language privacy policies explain exactly what data is collected, how it's used, and who has access. Opt-in rather than opt-out for all non-essential features. No selling or sharing data with third parties for advertising. Age-appropriate content filtering and parental controls for any community features. YouTube's $170 million fine for tracking children without consent demonstrates the serious consequences of privacy violations - but also the opportunity to differentiate through ethical data practices.
## UX designed for chaos: One hand, divided attention, constant interruption
Mothers interact with technology under uniquely challenging conditions. Research shows 49% of mobile users operate phones one-handed while multitasking, with 70% of interactions lasting under 2 minutes. Parents experience "distracted short-burst usage" patterns with 58 daily phone checks between childcare tasks. **The UX must accommodate this reality** through placement of critical functions within thumb's reach, bottom navigation bars instead of hamburger menus, and gesture-based interactions for common tasks.
The three-tap rule governs feature design - core functions must be accessible within three taps or less. Auto-save functionality prevents data loss during inevitable interruptions. Resume capability allows mothers to complete tasks started hours earlier. Visual state indicators show progress at a glance. **Interruption-resistant design** means every interaction can be abandoned mid-task without losing work, crucial when children demand immediate attention.
Successful patterns from consumer apps translate effectively. Instagram's story-style updates work for sharing family moments with grandparents. TikTok's swipe navigation enables quick browsing during brief free moments. Voice input becomes essential when hands are occupied with children. Visual information trumps text - icons, colors, and progress bars communicate faster than words. The interface must feel familiar and intuitive, eliminating learning curves that busy mothers cannot afford.
## Technical architecture for reliability when families depend on you
The technical foundation must support families' mission-critical needs through offline-first architecture with seamless synchronization. Local databases serve as the single source of truth, ensuring the app works without internet connection - crucial during pediatrician visits in cellular dead zones or international travel. **Real-time synchronization** keeps all family members updated through WebSocket connections, with conflict resolution for simultaneous edits. Background sync handles updates efficiently without draining battery life.
Integration capabilities determine the platform's value within existing family ecosystems. Calendar synchronization with Google, Apple, and Outlook consolidates schedules. Health app connections track growth and development. School platform integration (ClassDojo, Seesaw, Remind) centralizes communication. Smart home compatibility enables voice control through Alexa and Google Assistant. **The app becomes the family's command center** rather than another isolated tool.
Scalability planning ensures the platform grows smoothly from thousands to millions of families. Microservices architecture separates different domains for independent scaling. Read replicas improve performance under load. Redis caching accelerates frequently accessed data. CDN integration speeds media delivery globally. The AI/ML infrastructure balances on-device processing for privacy-sensitive features with cloud computing for complex analytics. TensorFlow Lite and Core ML optimize mobile performance while maintaining sophisticated capabilities.
## Sustainable monetization that respects family budgets
The freemium model with thoughtfully designed tiers ensures accessibility while building sustainable revenue. **Free tier** includes core tracking for 1-2 children, basic milestone checking, and limited AI insights - enough to deliver value and build trust. Family tier at $9.99/month unlocks unlimited children, advanced AI predictions, full voice capabilities, and priority support. Family Plus at $14.99/month adds comprehensive integrations, advanced analytics, and exclusive expert content.
B2B2C partnerships expand reach while reducing acquisition costs. **Employer wellness programs** increasingly recognize supporting working parents improves productivity and retention. Insurance partnerships frame the app as preventive care, potentially covering subscriptions. Healthcare provider relationships enable pediatrician-recommended adoption. School district partnerships could provide subsidized access for all families. These channels validate the platform while reaching mothers who might not discover it independently.
Critical metrics guide sustainable growth. Customer Acquisition Cost (CAC) must remain below $30 for profitability. Lifetime Value (LTV) should exceed $200 through strong retention. Monthly Recurring Revenue (MRR) growth of 15-20% indicates healthy expansion. **Churn analysis by feature usage** identifies which capabilities drive retention. The goal isn't maximum revenue extraction but sustainable value exchange that supports continuous improvement while respecting family budgets.
## Product roadmap from MVP to comprehensive platform
**Phase 1 (Months 1-3)** launches core MVP features: basic tracking with voice input, AI chat assistant providing 24/7 guidance, pattern recognition for sleep and feeding, multi-user family access, and COPPA/GDPR compliant infrastructure. This foundation addresses immediate pain points while establishing technical architecture for expansion.
**Phase 2 (Months 4-6)** adds intelligence and community: advanced pattern predictions across all tracked metrics, moderated community forums with expert participation, photo milestone storage with automatic organization, comprehensive calendar integration, and initial school platform connections. These features transform the app from tracker to intelligent assistant.
**Phase 3 (Months 7-12)** delivers the full vision: predictive scheduling that anticipates family needs, mental health monitoring with intervention protocols, meal planning with grocery integration, financial tracking for family expenses, and telemedicine integration for virtual pediatric visits. Smart home integration enables voice control of core features.
**Future expansion (12+ months)** extends the platform's reach: web platform for desktop planning sessions, wearable integration for health tracking, professional tools for pediatricians and therapists, AI-powered child development assessments, and international localization for global families. The platform evolves into the definitive digital infrastructure for modern parenting.
## Conclusion: From overwhelming chaos to confident parenting
The research reveals an enormous, underserved market of mothers struggling with preventable organizational and emotional challenges. Current solutions address symptoms rather than root causes, forcing families to juggle multiple apps while still missing critical support. **An integrated AI-powered platform** that combines intelligent tracking, predictive scheduling, mental health support, and family coordination can transform the parenting experience from overwhelming to manageable.
Success requires more than technical excellence. The platform must earn trust through privacy-first design, respect mothers' chaotic reality through interruption-resistant UX, and deliver immediate value through AI that actually reduces mental load rather than adding complexity. By addressing the holistic needs of modern mothers - from midnight feeding sessions to career planning meetings - this comprehensive solution can become the indispensable digital partner that millions of families desperately need.
The opportunity extends beyond commercial success to genuine social impact. Reducing maternal mental load, improving mental health support access, and enabling more equitable household partnerships could reshape family dynamics globally. With the parenting app market growing 12-20% annually and mothers increasingly embracing AI assistance, the timing is ideal for a platform that finally delivers on technology's promise to make parenting not easier, but more confident, connected, and joyful.