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:
551
docs/maternal-app-ai-context.md
Normal file
551
docs/maternal-app-ai-context.md
Normal 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,
|
||||
},
|
||||
},
|
||||
];
|
||||
```
|
||||
Reference in New Issue
Block a user