mirror of
https://github.com/Oak-and-Sprout/sprout-track.git
synced 2026-02-09 00:59:01 -06:00
updates to multi-family support
This commit is contained in:
1025
documentation/Family-Documentation/api-changes.md
Normal file
1025
documentation/Family-Documentation/api-changes.md
Normal file
File diff suppressed because it is too large
Load Diff
1041
documentation/Family-Documentation/frontend-changes.md
Normal file
1041
documentation/Family-Documentation/frontend-changes.md
Normal file
File diff suppressed because it is too large
Load Diff
122
documentation/Family-Documentation/implementation-summary.md
Normal file
122
documentation/Family-Documentation/implementation-summary.md
Normal file
@@ -0,0 +1,122 @@
|
||||
# Multi-Family Support Implementation Summary
|
||||
|
||||
This document provides a high-level summary of the changes required to implement multi-family support in the baby tracker application. It brings together the key points from the detailed documentation files.
|
||||
|
||||
## Overview
|
||||
|
||||
The goal is to transform the application from a single-family system to a multi-family platform where:
|
||||
|
||||
1. Each family has its own isolated data
|
||||
2. Users can belong to multiple families
|
||||
3. Family data is accessed through family-specific URLs
|
||||
4. The application maintains proper data isolation and security
|
||||
|
||||
## Key Components
|
||||
|
||||
### 1. Database Changes ([schema.prisma](../prisma/schema.prisma))
|
||||
|
||||
- Added a new `Family` model to represent family entities
|
||||
- Added `familyId` to all relevant models to establish relationships
|
||||
- Created a `FamilyMember` model to manage family membership
|
||||
- Added appropriate indexes for performance optimization
|
||||
- Made `familyId` nullable initially for migration purposes
|
||||
|
||||
### 2. Migration Strategy ([migration-script.md](./migration-script.md))
|
||||
|
||||
- Created a migration script to add the Family model and familyId fields
|
||||
- Implemented a process to create a default family for existing data
|
||||
- Developed a strategy to assign all existing data to the default family
|
||||
- Provided verification steps to ensure data integrity
|
||||
|
||||
### 3. API Changes ([api-changes.md](./api-changes.md))
|
||||
|
||||
- Updated authentication to include family context
|
||||
- Added middleware for family-based access control
|
||||
- Modified all API endpoints to include family filtering
|
||||
- Created new endpoints for family management
|
||||
- Implemented utility functions for family context
|
||||
|
||||
### 4. Frontend Changes ([frontend-changes.md](./frontend-changes.md))
|
||||
|
||||
- Created a Family context provider for state management
|
||||
- Developed a family selector component
|
||||
- Updated the app layout to include family selection
|
||||
- Modified all data fetching to include family context
|
||||
- Created interfaces for family management
|
||||
- Updated routing to include family slugs
|
||||
|
||||
## Implementation Plan ([plan.md](./plan.md))
|
||||
|
||||
The implementation is divided into five phases:
|
||||
|
||||
1. **Database Schema Updates**
|
||||
- Add Family model
|
||||
- Add familyId to existing models
|
||||
- Create migration scripts
|
||||
|
||||
2. **Authentication & Authorization**
|
||||
- Update auth flow
|
||||
- Implement family membership
|
||||
- Add family-based access control
|
||||
|
||||
3. **API Routes**
|
||||
- Update existing endpoints
|
||||
- Create new family management endpoints
|
||||
- Implement family-based filtering
|
||||
|
||||
4. **Frontend Changes**
|
||||
- Update app layout
|
||||
- Modify routing
|
||||
- Create family management UI
|
||||
|
||||
5. **Data Migration**
|
||||
- Create default family
|
||||
- Assign existing data
|
||||
- Verify data integrity
|
||||
|
||||
## Technical Approach
|
||||
|
||||
### Data Isolation
|
||||
|
||||
- Every database query includes familyId filtering
|
||||
- API middleware verifies family access permissions
|
||||
- Frontend components only display family-specific data
|
||||
|
||||
### User Experience
|
||||
|
||||
- Users can switch between families using a dropdown selector
|
||||
- Family management interface allows creating, editing, and deleting families
|
||||
- Family-specific URLs provide direct access to family data
|
||||
|
||||
### Security
|
||||
|
||||
- JWT tokens include familyId for authentication
|
||||
- Middleware verifies user has access to requested family
|
||||
- Database queries enforce family-based filtering
|
||||
|
||||
## Migration Considerations
|
||||
|
||||
- The initial migration makes familyId nullable to avoid breaking existing data
|
||||
- A migration script creates a default family and assigns all existing data
|
||||
- After migration, familyId can be made required for data integrity
|
||||
- Thorough testing is required to ensure no data is lost or corrupted
|
||||
|
||||
## Mobile Considerations
|
||||
|
||||
When adapting these changes for React Native:
|
||||
|
||||
- Replace URL-based navigation with React Navigation
|
||||
- Use AsyncStorage instead of localStorage
|
||||
- Adapt UI components for touch interactions
|
||||
- Maintain the same data isolation principles
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. Implement the database changes and run initial migration
|
||||
2. Update the authentication system to include family context
|
||||
3. Modify API endpoints to enforce family-based filtering
|
||||
4. Develop the frontend components for family selection and management
|
||||
5. Test thoroughly with multiple families and users
|
||||
6. Deploy with feature flags to enable gradual rollout
|
||||
|
||||
By following this implementation plan, the application will be transformed into a multi-family platform that maintains proper data isolation while providing a seamless user experience.
|
||||
173
documentation/Family-Documentation/migration-script.md
Normal file
173
documentation/Family-Documentation/migration-script.md
Normal file
@@ -0,0 +1,173 @@
|
||||
# Multi-Family Migration Script
|
||||
|
||||
This document provides a migration script and instructions for transitioning the existing database to support multiple families. The migration process is designed to be minimally disruptive, allowing for a smooth transition from a single-family to a multi-family model.
|
||||
|
||||
## Migration Process Overview
|
||||
|
||||
1. Create a new Prisma migration that adds the Family model and familyId fields to all relevant models
|
||||
2. Run the migration to update the database schema
|
||||
3. Execute a script to create a default family and assign all existing data to it
|
||||
4. Optionally, make the familyId fields required after the migration is complete
|
||||
|
||||
## Step 1: Create Prisma Migration
|
||||
|
||||
Run the following command to create a new migration:
|
||||
|
||||
```bash
|
||||
npx prisma migrate dev --name add-multi-family-support
|
||||
```
|
||||
|
||||
This will generate a new migration file based on the changes made to the schema.prisma file.
|
||||
|
||||
## Step 2: Migration Script
|
||||
|
||||
Create a file named `migrate-to-multi-family.ts` in the `prisma` directory with the following content:
|
||||
|
||||
```typescript
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
async function main() {
|
||||
console.log('Starting multi-family migration...');
|
||||
|
||||
// Create default family
|
||||
const defaultFamily = await prisma.family.create({
|
||||
data: {
|
||||
name: 'Default Family',
|
||||
slug: 'default-family',
|
||||
isActive: true,
|
||||
},
|
||||
});
|
||||
|
||||
console.log(`Created default family with ID: ${defaultFamily.id}`);
|
||||
|
||||
// Get existing settings to use the familyName
|
||||
const existingSettings = await prisma.settings.findFirst();
|
||||
|
||||
if (existingSettings) {
|
||||
// Update the default family name if settings exist
|
||||
await prisma.family.update({
|
||||
where: { id: defaultFamily.id },
|
||||
data: { name: existingSettings.familyName },
|
||||
});
|
||||
console.log(`Updated default family name to: ${existingSettings.familyName}`);
|
||||
}
|
||||
|
||||
// Update all existing records to reference the default family
|
||||
const models = [
|
||||
'baby',
|
||||
'caretaker',
|
||||
'sleepLog',
|
||||
'unit',
|
||||
'feedLog',
|
||||
'diaperLog',
|
||||
'moodLog',
|
||||
'note',
|
||||
'settings',
|
||||
'milestone',
|
||||
'pumpLog',
|
||||
'playLog',
|
||||
'bathLog',
|
||||
'measurement',
|
||||
'contact',
|
||||
'calendarEvent',
|
||||
'medicine',
|
||||
'medicineLog',
|
||||
];
|
||||
|
||||
for (const model of models) {
|
||||
const count = await updateModelFamilyId(model, defaultFamily.id);
|
||||
console.log(`Updated ${count} records in ${model} model`);
|
||||
}
|
||||
|
||||
// Create FamilyMember records for all caretakers
|
||||
const caretakers = await prisma.caretaker.findMany();
|
||||
|
||||
for (const caretaker of caretakers) {
|
||||
await prisma.familyMember.create({
|
||||
data: {
|
||||
familyId: defaultFamily.id,
|
||||
caretakerId: caretaker.id,
|
||||
role: caretaker.role === 'ADMIN' ? 'admin' : 'member',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
console.log(`Created ${caretakers.length} family member records`);
|
||||
|
||||
console.log('Migration completed successfully!');
|
||||
}
|
||||
|
||||
async function updateModelFamilyId(model: string, familyId: string): Promise<number> {
|
||||
// Use dynamic property access to update each model
|
||||
const updateResult = await (prisma as any)[model].updateMany({
|
||||
where: {
|
||||
familyId: null,
|
||||
},
|
||||
data: {
|
||||
familyId,
|
||||
},
|
||||
});
|
||||
|
||||
return updateResult.count;
|
||||
}
|
||||
|
||||
main()
|
||||
.catch((e) => {
|
||||
console.error('Migration failed:', e);
|
||||
process.exit(1);
|
||||
})
|
||||
.finally(async () => {
|
||||
await prisma.$disconnect();
|
||||
});
|
||||
```
|
||||
|
||||
## Step 3: Run the Migration Script
|
||||
|
||||
Execute the migration script with the following command:
|
||||
|
||||
```bash
|
||||
npx ts-node prisma/migrate-to-multi-family.ts
|
||||
```
|
||||
|
||||
This script will:
|
||||
1. Create a default family
|
||||
2. Update the family name based on existing settings
|
||||
3. Update all existing records to reference the default family
|
||||
4. Create FamilyMember records for all caretakers
|
||||
|
||||
## Step 4: Make familyId Required (Optional)
|
||||
|
||||
After confirming that the migration was successful and all data is properly associated with the default family, you can make the familyId fields required. This step is optional but recommended for data integrity.
|
||||
|
||||
1. Update the schema.prisma file to make familyId required in all models by changing `String?` to `String`
|
||||
2. Create a new migration:
|
||||
|
||||
```bash
|
||||
npx prisma migrate dev --name make-family-id-required
|
||||
```
|
||||
|
||||
## Verification Steps
|
||||
|
||||
After completing the migration, verify that:
|
||||
|
||||
1. All records have been properly associated with the default family
|
||||
2. The application functions correctly with the new multi-family schema
|
||||
3. New records are properly associated with families
|
||||
4. Family-based filtering works as expected
|
||||
|
||||
## Rollback Plan
|
||||
|
||||
If issues are encountered during the migration:
|
||||
|
||||
1. Restore the database from backup
|
||||
2. Revert the schema changes
|
||||
3. Run `npx prisma migrate resolve --rolled-back add-multi-family-support`
|
||||
|
||||
## Additional Considerations
|
||||
|
||||
- **API Updates**: Ensure all API endpoints include family-based filtering
|
||||
- **Authentication**: Update authentication to include family context
|
||||
- **Frontend**: Update UI to display and manage family information
|
||||
- **Testing**: Thoroughly test all functionality with multiple families
|
||||
@@ -13,28 +13,73 @@ model Family {
|
||||
name String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
isActive Boolean @default(true)
|
||||
|
||||
// Relations
|
||||
babies Baby[]
|
||||
caretakers Caretaker[]
|
||||
settings Settings[]
|
||||
// Add other relations as needed
|
||||
babies Baby[]
|
||||
caretakers Caretaker[]
|
||||
settings Settings[]
|
||||
sleepLogs SleepLog[]
|
||||
feedLogs FeedLog[]
|
||||
diaperLogs DiaperLog[]
|
||||
moodLogs MoodLog[]
|
||||
notes Note[]
|
||||
milestones Milestone[]
|
||||
pumpLogs PumpLog[]
|
||||
playLogs PlayLog[]
|
||||
bathLogs BathLog[]
|
||||
measurements Measurement[]
|
||||
medicines Medicine[]
|
||||
medicineLogs MedicineLog[]
|
||||
contacts Contact[]
|
||||
calendarEvents CalendarEvent[]
|
||||
units Unit[]
|
||||
// All other relations should be included here
|
||||
}
|
||||
```
|
||||
|
||||
### 1.2 Update Existing Models
|
||||
- Add `familyId` field to all relevant models
|
||||
- Make `familyId` required for most models
|
||||
- Set up proper relations
|
||||
- Add indexes for better query performance
|
||||
- Add `familyId` field to all models that store family-specific data:
|
||||
- **Entity models**: Baby, Caretaker, Medicine, Contact
|
||||
- **Activity logs**: SleepLog, FeedLog, DiaperLog, MoodLog, Note, Milestone, PumpLog, PlayLog, BathLog, Measurement, MedicineLog
|
||||
- **Configuration**: Settings, Unit (unless units should be shared across families)
|
||||
- **Events**: CalendarEvent
|
||||
- Make `familyId` required for all these models
|
||||
- Set up proper relations with the Family model
|
||||
- Add indexes for better query performance on familyId fields
|
||||
- Consider how junction tables (BabyEvent, CaretakerEvent, etc.) will handle family relationships
|
||||
|
||||
### 1.3 Migration Strategy
|
||||
### 1.3 Example Model Update
|
||||
```prisma
|
||||
model Baby {
|
||||
id String @id @default(uuid())
|
||||
firstName String
|
||||
lastName String
|
||||
birthDate DateTime
|
||||
gender Gender?
|
||||
inactive Boolean @default(false)
|
||||
// Other fields...
|
||||
|
||||
// Add family relation
|
||||
family Family @relation(fields: [familyId], references: [id])
|
||||
familyId String
|
||||
|
||||
// Existing relations...
|
||||
|
||||
@@index([familyId])
|
||||
// Other indexes...
|
||||
}
|
||||
```
|
||||
|
||||
### 1.4 Migration Strategy
|
||||
- Create migration script to:
|
||||
- Add Family model
|
||||
- Add familyId to all models
|
||||
- Create default family for existing users
|
||||
- Generate slugs for all families
|
||||
- Generate slugs for all families (based on family name)
|
||||
- Assign all existing data to default family
|
||||
- Ensure referential integrity across all tables
|
||||
- Handle edge cases where data might need to be split into multiple families
|
||||
|
||||
## Phase 2: Authentication & Authorization
|
||||
|
||||
@@ -42,19 +87,44 @@ model Family {
|
||||
- Modify login to handle family selection
|
||||
- Store selected familyId in session/token
|
||||
- Update auth context to include family information
|
||||
- Consider how users will be associated with multiple families (if applicable)
|
||||
|
||||
### 2.2 Update Middleware
|
||||
### 2.2 Family Membership
|
||||
- Create a model for tracking family membership:
|
||||
```prisma
|
||||
model FamilyMember {
|
||||
family Family @relation(fields: [familyId], references: [id])
|
||||
familyId String
|
||||
caretaker Caretaker @relation(fields: [caretakerId], references: [id])
|
||||
caretakerId String
|
||||
role String // e.g., "admin", "member"
|
||||
joinedAt DateTime @default(now())
|
||||
|
||||
@@id([familyId, caretakerId])
|
||||
@@index([familyId])
|
||||
@@index([caretakerId])
|
||||
}
|
||||
```
|
||||
- Define roles and permissions for family members
|
||||
- Implement invitation and acceptance flow
|
||||
|
||||
### 2.3 Update Middleware
|
||||
- Add family-based access control
|
||||
- Verify user has access to requested family
|
||||
- Automatically add familyId to all database queries
|
||||
- Create utility functions that enforce family-based filtering
|
||||
- Handle unauthorized access gracefully
|
||||
- Consider implementing row-level security if your database supports it
|
||||
|
||||
## Phase 3: API Routes
|
||||
|
||||
### 3.1 Update Existing Endpoints
|
||||
- Add family-based filtering to all GET endpoints
|
||||
- Create middleware that automatically adds familyId to all queries
|
||||
- Update input validation to include familyId
|
||||
- Modify responses to be family-scoped
|
||||
- Add proper error handling
|
||||
- Add proper error handling for family-related errors
|
||||
- Ensure all database operations respect family boundaries
|
||||
|
||||
### 3.2 New API Endpoints
|
||||
- `GET /api/families` - List all families for current user
|
||||
@@ -149,23 +219,35 @@ model Family {
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
1. Family member roles (admin, member, etc.)
|
||||
1. Advanced family member roles and permissions
|
||||
2. Family activity feed
|
||||
3. Family usage analytics
|
||||
4. Family-specific settings
|
||||
5. Family data export
|
||||
4. Additional family-specific settings
|
||||
5. Family data export and import
|
||||
6. Cross-family data sharing (for specific use cases)
|
||||
7. Family templates for quick setup
|
||||
|
||||
## Risks & Mitigations
|
||||
|
||||
1. **Performance Impact**
|
||||
- Add proper indexing
|
||||
- Monitor query performance
|
||||
- Add proper indexing on all familyId fields
|
||||
- Monitor query performance with family filtering
|
||||
- Consider database sharding for very large deployments
|
||||
- Optimize queries that join across multiple tables
|
||||
|
||||
2. **Data Migration**
|
||||
- Backup before migration
|
||||
- Test migration thoroughly
|
||||
- Test migration thoroughly on a copy of production data
|
||||
- Create a rollback plan
|
||||
- Consider a phased migration approach for large datasets
|
||||
|
||||
3. **User Experience**
|
||||
- Provide clear feedback
|
||||
- Add loading states
|
||||
- Handle errors gracefully
|
||||
- Provide clear feedback during family switching
|
||||
- Add loading states for all family-related operations
|
||||
- Handle errors gracefully with user-friendly messages
|
||||
- Ensure UI clearly indicates which family is currently active
|
||||
|
||||
4. **Data Isolation**
|
||||
- Regularly audit database queries to ensure proper family filtering
|
||||
- Implement automated tests that verify data isolation
|
||||
- Create monitoring for potential cross-family data leaks
|
||||
|
||||
Reference in New Issue
Block a user