939 lines
18 KiB
Markdown
939 lines
18 KiB
Markdown
# 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
|
|
});
|
|
};
|
|
}
|
|
``` |