Child Management
Child data model, AES-256-GCM credential encryption, ownership verification, and multi-parent sharing.
Child Management
Children are real Sharetribe users with encrypted credentials, owned by one or more parent users.
Child Lifecycle
%%{init: {'theme': 'neutral'}}%%
stateDiagram-v2
[*] --> Created: POST /api/children/create
Created --> HasCalendar: CalDAV calendar auto-provisioned
Created --> InviteSent: POST /api/children/share
HasCalendar --> InviteSent: Share with co-parent
InviteSent --> Shared: Accept invitation
InviteSent --> HasCalendar: Decline invitation
HasCalendar --> [*]: DELETE /api/children/delete
Created --> [*]: DELETE /api/children/deleteData Model
Parent's privateData:
{
"childIds": ["child-uuid-1", "child-uuid-2"],
"childCredentials": {
"child-uuid-1": { "ci": "child-xxx@child.placeholder.local", "ck": "<encrypted>" }
},
"davisUsername": "parent@example.com",
"davisPassword": "...",
"davisUserId": "davis-internal-id"
}Child's privateData:
{
"parentIds": ["parent-uuid"],
"childName": "Alice",
"birthYear": 2018,
"isChildProfile": true,
"calendarUrl": "http://localhost:9000/dav/<davisUserId>/calendars/<uuid>/"
}Credential Encryption
Child passwords are encrypted with AES-256-GCM before storage in the parent's privateData. The key is CHILD_CREDENTIAL_ENCRYPTION_KEY (32-byte hex string). See server/api-util/crypto.js.
Generate a key:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"Ownership Verification
Every child endpoint uses bidirectional ownership checks (server/api-util/childOwnership.js):
- Parent's
childIdsmust contain the child ID - Child's
parentIdsmust contain the parent ID
Both checks must pass or the request returns 403.
CRUD Operations
| Endpoint | Method | Description |
|---|---|---|
/api/children/create | POST | Create child user, encrypt creds, optionally create CalDAV calendar |
/api/children | GET | List all children for the authenticated parent |
/api/children/update | POST | Update child profile fields |
/api/children/delete | POST | Delete child user and remove from parent's childIds |
/api/children/upload-avatar | POST | Upload child avatar (multipart/form-data) |
/api/children/remove-avatar | POST | Remove child avatar |
Multi-Parent Sharing
Parents can share children with other parents via invitations:
| Endpoint | Method | Description |
|---|---|---|
/api/children/share | POST | Send invitation to share a child |
/api/children/invitations | GET | List pending invitations |
/api/children/invitations/accept | POST | Accept and add child to your profile |
/api/children/invitations/decline | POST | Decline invitation |
Child Preferences (Supabase)
Preferences are stored in Supabase, not Sharetribe privateData:
| Table | Purpose |
|---|---|
child_interests | Category interests per child (10 canonical categories) |
child_likes | Activity favourites per child |
child_connections | Relationships between children (twin, sibling, friend, etc.) |