Rewrite the encryption/persona/JWT docs to match the implemented code and record the multi-person sharing design. - multi-person-sharing.md (NEW): ADR for per-profile DEK + X25519 envelope sharing. All five original open questions resolved 2026-07-18. Covers divorced-parents, pets, graduation, and elderly-parent care; adds an admin permission tier for owner-incapacity. Decided, not yet implemented. (#3) - encryption.md: full rewrite to the implemented wrapped-DEK / Web Crypto model; the old version described ZK encryption as 'planned'. (#4) - jwt-authentication-decision.md: rewritten to match implementation (PBKDF2 not bcrypt, no Redis, token_version revocation, real Claims). Original aspirational content preserved in a History section. (#4) - PERSONA_AND_FAMILY_MANAGEMENT.md: 'Current reality' section added, old 'Implementation Status' marked superseded, encryption section corrected. (#4) - ENCRYPTION_UPDATE_SUMMARY.md: archived (changelog for a rewrite that itself went stale). (#4) - ADR README index updated for the new + reconciled entries.
26 KiB
Persona and Family Management - Product Definition
Document Version: 1.1
Date: 2026-07-18 (reconciled with code; original draft 2026-03-09)
Status: Vision doc — implementation status section corrected to match code
Purpose: Consolidate all current information about persona and family management features for further product refinement
How to read this doc. Sections marked Vision describe the target product and are still valid for discussion. Sections marked Today (code) describe what is actually implemented and have been verified against the codebase as of 2026-07-18. Where the two diverge, the gap is called out and linked to the relevant Forgejo issue.
📋 Table of Contents
- Executive Summary
- User Personas
- Family Management Concept
- Current Implementation Status
- Data Models
- API Endpoints
- User Stories
- Security Considerations
- MVP Prioritization
- Open Questions
Executive Summary
Normogen supports multi-person health data management through a persona and family management system. This enables:
- Primary users to manage their own health data
- Family caregivers to manage health data for dependents (children, elderly parents)
- Data sharing between family members and caregivers
- Privacy control through granular permissions
Key Insight: The persona/family feature is CRITICAL for MVP as it enables the core use case of parents tracking medications and health data for their entire family.
Current reality (as of 2026-07-18)
This section corrects the earlier "Current Implementation Status" section below, which described an earlier state. Verified against the code:
| Capability | Status | Notes |
|---|---|---|
| Single profile per user account | ✅ Done | GET/PUT /api/profiles/me; profile is auto-created as profile_{user_id} at registration. Display name is client-encrypted. |
| Multi-profile (child/dependent) within one account | ❌ Not built | ProfileRepository::find_by_user_id returns a single profile; no create/list/switch endpoints. profileId can be tagged onto medications but there is no backing entity beyond the owner's. |
| Family groups | ❌ Not built | Family model exists but has no handler and no routes. JWT carries family_id but nothing populates or checks it. |
| Cross-user sharing (spouse, caregiver) | ❌ Blocked by design | /api/shares routes exist but cannot grant decryption access — all data is encrypted under the owner's DEK and there is no key-distribution mechanism. See issue #3. |
| Caregiver roles / permissions | ❌ Not built | permissions field exists on Profile and in JWT claims but is not enforced. |
| Zero-knowledge encryption of health data | ✅ Done | Client-side Web Crypto, wrapped-DEK recovery. See encryption.md. |
Implication for the family/caregiver personas below: the single biggest open question is architectural — how does sharing work under zero-knowledge? That must be decided before family/caregiver features can be implemented. Until then, the realistic near-term scope is multi-profile within a single account (one login managing several people's data, no cross-account sharing).
User Personas
Primary: Privacy-Conscious Individual
Demographics:
- Age: 25-45
- Tech-savvy
- Concerns about data privacy
- Wants to track personal medications and health stats
Needs:
- Secure medication tracking
- Health statistics monitoring
- Data ownership and control
- Privacy from corporations
Motivations:
- Values control over personal data
- Distrusts commercial health platforms
- Wants self-hosting option
- Needs comprehensive health tracking
Secondary: Family Caregiver ⭐ MVP CRITICAL
Demographics:
- Age: 30-55
- Managing health for dependents (children, elderly parents)
- Often time-constrained
- Needs simple, efficient workflows
Needs:
- Multi-person health data management
- Easy data sharing with other caregivers
- Medication reminders for family members
- Family health history tracking
- Caregiver access management
Motivations:
- Ensure family medication adherence
- Coordinate care with other family members
- Monitor elderly parents' health remotely
- Track children's health over time
Pain Points:
- Juggling multiple medications for different family members
- Forgetting to give medications on time
- Difficulty sharing health info with doctors/caregivers
- Fragmented health records across different systems
Daily Scenarios:
- Morning Routine: Check medications due for spouse, child, and self
- Doctor Visit: Export family medication history for pediatrician
- Care Coordination: Share child's health data with grandparent babysitter
- Travel: Ensure medications are tracked while away from home
Tertiary: Health Enthusiast
Demographics:
- Age: 20-40
- Tracks fitness, sleep, nutrition
- Uses wearables and sensors
- Data-driven approach to health
Needs:
- Integration with wearable devices
- Advanced analytics and trends
- Data visualization
- Export capabilities
Motivations:
- Optimize personal health
- Identify patterns in health data
- Quantified self movement
- Biohacking interests
Family Management Concept
Vision
Normogen enables family-centered health data management where one user account can manage health data for multiple people through:
- Person Profiles - Individual health profiles for each family member
- Family Groups - Logical grouping of related individuals
- Permission-Based Access - Granular control over who can view/manage data
- Caregiver Roles - Designated caregivers for dependents
Core Concepts
User Account vs. Profile
User Account:
- Represents a login identity (email/password)
- Has authentication credentials
- Owns the data
- Can create multiple profiles
Profile (Persona):
- Represents an individual person's health data
- Belongs to a user account
- Can be the account owner (self) or a dependent (child, elderly parent)
- Has its own medications, health stats, lab results
Example:
User Account: jane.doe@example.com (Jane)
├── Profile: Jane Doe (self) - age 35
├── Profile: John Doe (spouse) - age 37 - shared with Jane
├── Profile: Emma Doe (daughter) - age 8 - managed by Jane
└── Profile: Robert Smith (father) - age 72 - managed by Jane
Family Structure
Family Group:
- Collection of profiles related by family/caregiver relationship
- Enables sharing and permissions across family members
- One user can be part of multiple families (e.g., nuclear family + aging parents)
Family Roles:
- Owner: Primary account holder
- Manager: Can manage health data for dependents
- Member: Can view own data
- Caregiver: External person with granted access (e.g., nanny, home health aide)
Current Implementation Status (superseded — see "Current reality" above)
The detail below was written 2026-03-09 against an earlier state and overstates what existed then. It is retained for history. For the accurate current picture, read the Current reality section near the top of this document, and
encryption.mdfor encryption.
✅ Implemented (Backend)
User Model (backend/src/models/user.rs)
- User authentication with email/password
- User profile management (username, email)
- Password recovery with recovery phrase
- Account deletion
- Settings management
User Structure:
pub struct User {
pub id: Option<ObjectId>,
pub email: String,
pub username: String,
pub password_hash: String,
pub recovery_phrase_hash: Option<String>,
pub recovery_enabled: bool,
pub token_version: i32,
pub created_at: DateTime,
pub last_active: DateTime,
pub email_verified: bool,
}
Profile Model (backend/src/models/profile.rs)
- Profile creation and management
- Link to user account
- Link to family group
- Role-based permissions
- Encrypted profile data
Profile Structure:
pub struct Profile {
pub id: Option<ObjectId>,
pub profile_id: String,
pub user_id: String, // Owner user account
pub family_id: Option<String>, // Family group ID
pub name: String, // Encrypted
pub name_iv: String, // Encryption IV
pub name_auth_tag: String, // Encryption auth tag
pub role: String, // Role in family
pub permissions: Vec<String>, // Permissions list
pub created_at: DateTime,
pub updated_at: DateTime,
}
Family Model (backend/src/models/family.rs)
- Family group creation
- Member management
- Encrypted family data
Family Structure:
pub struct Family {
pub id: Option<ObjectId>,
pub family_id: String,
pub name: String, // Encrypted
pub name_iv: String,
pub name_auth_tag: String,
pub member_ids: Vec<String>, // Profile IDs
pub created_at: DateTime,
pub updated_at: DateTime,
}
Share/Permission System
- Create shares for health data
- Grant read/write/admin permissions
- Expiring access links
- Resource-level permissions
Share Model (backend/src/models/share.rs):
pub struct Share {
pub id: Option<ObjectId>,
pub share_id: String,
pub resource_type: String, // "medication", "health_stat", etc.
pub resource_id: String,
pub target_user_id: String, // Who receives access
pub permissions: Vec<String>, // ["read", "write", "delete", "share", "admin"]
pub expires_at: Option<DateTime>,
pub active: bool,
}
🚧 Partially Implemented
Medication Management
- ✅ Create/list/update/delete medications
- ✅ Profile-based filtering (
profile_idparameter) - ✅ Log doses for specific profiles
- ✅ Calculate adherence by profile
- ✅ OpenFDA integration for drug data
Medication Structure:
pub struct Medication {
pub id: Option<ObjectId>,
pub user_id: String,
pub profile_id: Option<String>, // ✅ Multi-person support
pub name: String,
pub dosage: String,
pub frequency: String,
// ... other fields
}
Example: Parent managing child's medication:
# Create medication for child's profile
curl -X POST http://localhost:6500/api/medications \
-H "Authorization: Bearer <token>" \
-d '{
"name": "Amoxicillin",
"dosage": "250mg",
"frequency": "Twice daily",
"profile_id": "child_profile_123"
}'
# Log dose for child
curl -X POST http://localhost:6500/api/medications/{id}/log \
-H "Authorization: Bearer <token>" \
-d '{"profile_id": "child_profile_123"}'
# View child's adherence
curl http://localhost:6500/api/medications/{id}/adherence?profile_id=child_profile_123 \
-H "Authorization: Bearer <token>"
❌ Not Implemented
Profile Management Endpoints
- No dedicated API for profile CRUD operations
- No UI for creating/managing family profiles
- No profile switching interface
- No family group management UI
Frontend Support
- Basic React app structure exists (~10% complete)
- No profile management UI
- No family management UI
- No profile switching functionality
Data Models
User Account
interface User {
id: string;
email: string;
username: string;
passwordHash: string;
recoveryPhraseHash?: string;
recoveryEnabled: boolean;
tokenVersion: number;
createdAt: Date;
lastActive: Date;
emailVerified: boolean;
}
Profile (Persona)
interface Profile {
id: string;
profileId: string;
userId: string; // Owner user account
familyId?: string; // Optional family group
name: string; // Encrypted
role: string; // "self", "child", "dependent", "spouse"
permissions: string[]; // ["read", "write", "delete", "share", "admin"]
dateOfBirth?: Date; // For age calculations
relationship?: string; // "daughter", "son", "father", "mother", etc.
avatar?: string; // Profile picture URL
createdAt: Date;
updatedAt: Date;
}
Family Group
interface Family {
id: string;
familyId: string;
name: string; // Encrypted (e.g., "Smith Family")
memberIds: string[]; // Array of profile IDs
createdAt: Date;
updatedAt: Date;
}
Share/Permission
interface Share {
id: string;
shareId: string;
resourceType: string; // "medication", "health_stat", "lab_result"
resourceId: string;
targetUserId: string; // User receiving access
permissions: Permission[]; // ["read", "write", "delete", "share", "admin"]
expiresAt?: Date;
active: boolean;
createdAt: Date;
}
type Permission = "read" | "write" | "delete" | "share" | "admin";
API Endpoints
Currently Implemented
User Profile Management
GET /api/users/me // Get current user profile
PUT /api/users/me // Update user profile
DELETE /api/users/me // Delete account
POST /api/users/me/change-password // Change password
GET /api/users/me/settings // Get user settings
PUT /api/users/me/settings // Update user settings
Medication Management (with profile support)
POST /api/medications // Create medication (with profile_id)
GET /api/medications // List medications (filter by profile_id)
GET /api/medications/:id // Get specific medication
PUT /api/medications/:id // Update medication
POST /api/medications/:id/delete // Delete medication
POST /api/medications/:id/log // Log dose (with profile_id)
GET /api/medications/:id/adherence // Get adherence (filter by profile_id)
Health Statistics (with profile support)
POST /api/health-stats // Create health stat (with profile_id)
GET /api/health-stats // List health stats (filter by profile_id)
GET /api/health-stats/:id // Get specific health stat
PUT /api/health-stats/:id // Update health stat
DELETE /api/health-stats/:id // Delete health stat
GET /api/health-stats/trends // Get trends (filter by profile_id)
Share/Permission Management
POST /api/shares // Create share
GET /api/shares // List shares
PUT /api/shares/:id // Update share
DELETE /api/shares/:id // Delete share
POST /api/permissions/check // Check permissions
Needed for Complete Family Management
Profile CRUD
GET /api/profiles // List all profiles for current user
POST /api/profiles // Create new profile (family member)
GET /api/profiles/:id // Get specific profile
PUT /api/profiles/:id // Update profile
DELETE /api/profiles/:id // Delete profile
GET /api/profiles/:id/medications // Get medications for profile
GET /api/profiles/:id/health-stats // Get health stats for profile
Family Group Management
GET /api/families // List families
POST /api/families // Create family
GET /api/families/:id // Get family details
PUT /api/families/:id // Update family
DELETE /api/families/:id // Delete family
POST /api/families/:id/members // Add member to family
DELETE /api/families/:id/members/:id // Remove member from family
Caregiver Access
POST /api/profiles/:id/caregivers // Add caregiver to profile
DELETE /api/profiles/:id/caregivers/:id // Remove caregiver
GET /api/profiles/:id/caregivers // List caregivers
PUT /api/profiles/:id/caregivers/:id // Update caregiver permissions
User Stories
Story 1: Parent Managing Child's Medications
As a parent, I want to manage my child's medications so that I can ensure they take their medication correctly.
Acceptance Criteria:
- Create a profile for my child (name, DOB, relationship)
- Add medications to my child's profile
- Log doses for my child
- View my child's medication adherence
- Set up reminders for my child's medications
- Share my child's medication list with spouse
Happy Path:
- Parent logs into Normogen
- Creates profile for daughter "Emma" (DOB: 2016-05-15, relationship: "daughter")
- Adds medication "Amoxicillin 250mg" to Emma's profile
- Sets reminder for 8am and 8pm daily
- Logs morning dose at 8:05am
- Views Emma's medication adherence (95% this month)
- Shares Emma's medications with spouse (read access)
Story 2: Caring for Elderly Parent
As an adult child, I want to manage my elderly father's health data so that I can ensure he's taking his medications and monitor his health.
Acceptance Criteria:
- Create profile for elderly parent
- Add multiple medications with complex schedules
- Track blood pressure readings
- View medication adherence
- Receive alerts for missed doses
- Share health data with home health aide
Happy Path:
- User creates profile for father "Robert" (age 72, relationship: "father")
- Adds 5 medications with different schedules
- Records BP readings twice daily
- Gets notification: "Robert missed 6pm Lisinopril dose"
- Views trends: BP average 135/85 this week
- Grants read access to home health aide for 30 days
Story 3: Family Sharing Health Data
As a parent, I want to share my child's health data with grandparents so that they can provide care when babysitting.
Acceptance Criteria:
- Create share for child's medications
- Set expiration on share (1 day, 7 days, 30 days)
- Grant read-only access
- Revoke access when needed
- Share multiple resources at once
Happy Path:
- Parent creates share for daughter Emma's medications
- Selects "Grandma" as target user
- Grants "read" permission
- Sets expiration to "1 day" (for sleepover)
- Grandma receives link, views Emma's medication schedule
- Next day, share expires automatically
Story 4: Switching Between Family Profiles
As a parent, I want to easily switch between family members' profiles so that I can manage health data for each person.
Acceptance Criteria:
- View all profiles I have access to
- Switch active profile with one click
- See filtered data for selected profile
- Quick-switch from medication list
- Mobile-friendly profile switching
Happy Path:
- Parent opens Normogen app
- Sees profile switcher: "Jane ▼" in header
- Clicks dropdown, sees: [Jane] [John] [Emma] [Robert]
- Selects "Emma"
- App filters to show only Emma's medications and health stats
- Logs dose for Emma's medication
- Switches back to "Jane" to view own data
Security Considerations
Data Ownership & Access Control
Core Principle: Users can only access profiles they own or have been granted access to.
Implementation:
- User Ownership Verification: Every request verifies
user_idmatches JWT token - Profile Ownership Verification: Profile access checks if user owns the profile
- Permission Checking: Share system enforces granted permissions
- Audit Logging: All profile/medication access is logged
Security Rules:
- ✅ Users can only create profiles for their own account
- ✅ Users can only access medications they own or have been shared
- ✅ Profile data is encrypted at rest (AES-256-GCM)
- ✅ Share access expires automatically
- ✅ All access is logged for audit purposes
Children's Data Protection
Additional Protections for Dependent Profiles:
- No public sharing of children's data
- Limited caregiver access (read-only by default)
- Explicit consent required for any sharing
- Audit logging for all children's data access
- Parent can revoke any caregiver access immediately
Implementation:
if profile.role == "child" || profile.age < 18 {
// Enforce stricter sharing rules
require_explicit_parent_consent(share)?;
limit_to_read_only(share)?;
}
Encryption
Correction (2026-07-18): the bullets below described a planned server-side scheme that was never built. The shipped system is client-side zero-knowledge via the browser's Web Crypto API with a wrapped-DEK model. The server has no crypto code at all — it is a blind store. Profile/medication/appointment data is encrypted in the browser before upload and the server cannot read any of it. Full details:
encryption.mdandadr/zero-knowledge-encryption.md.
What's actually encrypted (client-side, today):
- Medication data blob (name, dosage, frequency, route, notes, …)
- Appointment data blob (title, provider, date/time, …)
- Profile display name
What stays plaintext (queryable by the server):
- IDs (
profileId,medicationId,userId,appointmentId) - Medication
activeflag, appointmentstatus,doseSchedule, timestamps
MVP Prioritization
Priority: 🔴 CRITICAL for MVP
Profile Management is marked as CRITICAL in Phase 2.7 MVP prioritization:
| Feature | Priority | MVP Value | Effort | Status |
|---|---|---|---|---|
| Profile Management | 🔴 CRITICAL | 🔥🔥🔥🔥 | Low | 🚧 Partial (model exists, no API) |
| Multi-Person Medications | 🔴 CRITICAL | 🔥🔥🔥🔥🔥 | Medium | ✅ Implemented |
| Profile-Based Filtering | 🔴 CRITICAL | 🔥🔥🔥🔥 | Low | ✅ Implemented |
| Basic Sharing | 🔴 IMPORTANT | 🔥🔥🔥🔥 | Medium | ✅ Implemented |
Why Critical?
- Enables the core use case: parents tracking family health
- Differentiates from competitors (single-person apps)
- Essential for family caregiver persona
- Low implementation effort (models exist, just need API endpoints)
Open Questions
Product Definition
-
Profile Types: Should we have explicit profile types (child, adult, elderly) or just roles?
- Option A: Explicit types with validation rules
- Option B: Flexible roles defined by user
- Recommendation: Start with flexible roles, add types later
-
Family Membership: Can a profile belong to multiple families?
- Example: Spouse in nuclear family + member of extended family
- Recommendation: Yes, support multiple families
-
Caregiver Access: How do external caregivers access shared data?
- Option A: Must have Normogen account
- Option B: Email-based magic link (no account required)
- Recommendation: Start with Normogen account, add magic links later
-
Profile Deletion: What happens when deleting a profile?
- Soft delete (mark as deleted)?
- Hard delete (remove all data)?
- Export option before deletion?
- Recommendation: Soft delete + export option
Technical Implementation
-
Profile Limit: How many profiles per user account?
- Suggested: 10 profiles (reasonable for most families)
-
Family Size Limit: How many members per family?
- Suggested: 20 members (extended family)
-
Share Limit: How many active shares per resource?
- Suggested: No limit (but audit heavily)
-
Data Retention: How long to keep deleted profile data?
- Suggested: 30 days (soft delete period)
UI/UX
-
Profile Switching: Where should profile switcher be located?
- Header dropdown? Sidebar? Separate page?
- Recommendation: Header dropdown for quick access
-
Profile Creation: What information is required?
- Minimum: Name + Relationship
- Optional: DOB, avatar, medical info
- Recommendation: Start with name + relationship, add fields later
-
Family View: Should we have a "family dashboard"?
- Show all family members at once
- Medications due today for all profiles
- Recommendation: Phase 3 feature (not MVP)
Next Steps for Refinement
1. Clarify Product Requirements
- Define exact profile types/roles needed
- Specify required vs optional profile fields
- Define caregiver access model (account vs magic link)
- Specify profile deletion behavior
2. Prioritize API Endpoints
- Profile CRUD (create, read, update, delete)
- Family group management
- Caregiver management
- Profile switching in UI
3. Security Review
- Finalize children's data protection rules
- Define audit logging requirements
- Specify encryption scope
- Define share expiration policies
4. UI/UX Design
- Design profile creation flow
- Design profile switching interface
- Design family management dashboard
- Design caregiver invitation flow
Appendix: Related Documentation
Product Documents
docs/product/introduction.md- User personas and target audiencedocs/product/ROADMAP.md- Development phases and timelinedocs/product/STATUS.md- Current implementation status
Implementation Documents
docs/implementation/MVP_PHASE_2.7_SUMMARY.md- MVP prioritization (profiles as critical)docs/implementation/PHASE_2.7_MVP_PRIORITIZED_PLAN.md- Detailed sprint plan
Code
backend/src/models/profile.rs- Profile data modelbackend/src/models/family.rs- Family data modelbackend/src/models/user.rs- User data modelbackend/src/models/medication.rs- Medication model with profile_id support
Document Status: Ready for refinement and feedback
Next Review: After product team discussion
Owner: Product Team
Contributors: Development Team, UX Team