15 KiB
Family Plan Feature - Implementation Status
✅ Feature Complete - Ready for Production
All phases of the Family Plan feature have been successfully implemented and tested. The feature is production-ready for both self-hosted instances and future Dawarich Cloud integration.
✅ Phase 1: Database Foundation - COMPLETED
- 3 database tables: families, family_memberships, family_invitations
- All models with associations and validations
- Standard bigint primary keys for performance
- Comprehensive test coverage (68+ tests)
✅ Phase 2: Core Business Logic - COMPLETED
- 4 service classes: Create, Invite, AcceptInvitation, Leave
- LocationSharingService for map integration
- Email templates and FamilyMailer
- Pundit authorization policies
- Comprehensive error handling
✅ Phase 3: Controllers and Routes - COMPLETED
- FamiliesController, FamilyMembershipsController, FamilyInvitationsController
- Custom Users::SessionsController for invitation flow
- Public and authenticated routes
- Full authorization integration
✅ Phase 4: User Interface - COMPLETED
- Family dashboard with map integration
- Enhanced invitation landing page with benefits display
- Family creation and management views
- Dark mode support throughout
- Stimulus controllers for interactive elements
- Navigation integration
✅ Phase 5: Polish and Enhancements - COMPLETED
- Family member map visualization with auto-zoom
- Real-time tooltips showing "Last updated: [timestamp]"
- Detailed popups with email and coordinates
- Error handling and user feedback
- Feature gating for cloud vs self-hosted
- Email notification system
Overview
The Family Plan feature allows Dawarich users to create family groups, invite members, and share their latest location data within the family. This feature enhances the social aspect of location tracking while maintaining strong privacy controls.
Key Features
- Create and manage family groups
- Invite members via email
- Share latest location data within family
- Role-based permissions (owner/member)
- Privacy controls for location sharing
- Email notifications and in-app notifications
Business Rules
- Maximum 5 family members per family (hardcoded constant)
- One family per user (must leave current family to join another)
- Family owners cannot delete their accounts
- Invitation tokens expire after 7 days
- Only latest position sharing (no historical data access)
- Free for self-hosted instances, paid feature for Dawarich Cloud
Database Schema
1. Families Table
id(bigint, primary key)name(string, max 50 chars, not null)creator_id(bigint, foreign key to users, not null)created_at,updated_at(datetime)- Constant: MAX_MEMBERS = 5
2. Family Memberships Table
id(bigint, primary key)family_id(bigint, foreign key to families, not null)user_id(bigint, foreign key to users, not null, unique - one family per user)role(integer enum: owner=0, member=1, not null, default: member)created_at,updated_at(datetime)
3. Family Invitations Table
id(bigint, primary key)family_id(bigint, foreign key to families, not null)email(string, not null, validated format)token(string, not null, unique - secure invitation token)expires_at(datetime, not null - 7 days from creation)invited_by_id(bigint, foreign key to users, not null)status(integer enum: pending=0, accepted=1, expired=2, cancelled=3)created_at,updated_at(datetime)
4. User Model Extensions
Added associations and helper methods:
in_family?- Check if user is in a familyfamily_owner?- Check if user owns their familycan_delete_account?- Prevents owners from deleting accounts with members
Core Architecture
Service Classes
All family operations use service objects for business logic:
Families::Create
- Creates family with automatic owner membership
- Validates user eligibility (not already in family)
- Sends notification to creator
Families::Invite
- Sends email invitations with secure tokens
- Validates family capacity (max 5 members)
- Prevents duplicate invitations
- Checks invitee isn't already in a family
Families::AcceptInvitation
- Validates invitation status and email match
- Creates member membership
- Updates invitation status
- Notifies both user and family owner
Families::Leave
- Removes user from family
- Prevents owners from leaving with active members
- Handles ownership transfer logic
- Cleans up family if last member leaves
Families::LocationSharingService
- Retrieves latest location for each family member
- Powers family map visualization
- Returns location data with timestamps
Controllers
FamiliesController - Family CRUD operations and dashboard FamilyMembershipsController - Member management FamilyInvitationsController - Invitation creation and acceptance Users::SessionsController - Custom login flow with invitation tokens
Authorization
Three Pundit policies control access:
- FamilyPolicy - Family operations (create, update, destroy, invite)
- FamilyMembershipPolicy - Member management
- FamilyInvitationPolicy - Invitation management
Email System
FamilyMailer sends invitation emails with:
- Personalized invitation message
- Family name and inviter information
- Benefits explanation
- Accept invitation link
- 7-day expiration notice
Error Handling
Services return true/false and expose error_message for user-friendly feedback:
- All database operations use transactions with rollback
- Comprehensive validation with specific error messages
- Controllers display service error messages to users
- Common errors: capacity limits, duplicate invitations, permission issues
Routes and Navigation
Public Routes
GET /invitations/:id- Public invitation landing page (no auth required)
Authenticated Routes
Family Management:
GET /families- Family index (redirects to user's family)GET /families/new- Create family formPOST /families- Create familyGET /families/:id- Family dashboard with mapGET /families/:id/edit- Family settingsPATCH /families/:id- Update familyDELETE /families/:id- Delete familyDELETE /families/:id/leave- Leave familyPATCH /families/:id/update_location_sharing- Update location sharing preferences
Family Invitations:
GET /families/:family_id/invitations- List invitationsPOST /families/:family_id/invitations- Create invitationGET /families/:family_id/invitations/:id- Show invitationPOST /families/:family_id/invitations/:id/accept- Accept invitationDELETE /families/:family_id/invitations/:id- Cancel invitation
Family Members:
GET /families/:family_id/members- List membersGET /families/:family_id/members/:id- Show memberDELETE /families/:family_id/members/:id- Remove member
API Endpoints:
GET /api/v1/families/locations- Get all family member locations (JSON)
Navigation Integration
Family link added to main navbar:
- Shows "Family" if user is in a family
- Shows "Create Family" if user is not in a family
User Interface
Invitation Landing Page (Enhanced)
Beautiful invitation acceptance page featuring:
- Hero section with gradient background and family icon
- 4 benefit cards explaining family features:
- Share Location Data
- Track Your Location History
- Stay Connected
- Full Control & Privacy
- Invitation details (family name, inviter, expiration)
- Conditional CTAs based on authentication status:
- Not logged in: "Create Account & Join Family" button
- Logged in: "Accept Invitation & Join Family" button
- Dark mode support throughout
- Links to login/register with invitation token preservation
Family Dashboard
- Family name and member count
- Interactive Leaflet map showing all family members
- Family member markers with auto-zoom on layer enable
- Real-time tooltips showing "Last updated: [timestamp]"
- Detailed popup on click with email and coordinates
- Member list with avatars and roles
- Pending invitations section (owners only)
- Invite member button (opens modal)
- Family settings and leave buttons
Create Family Form
- Simple name input
- Feature benefits explanation
- Self-hosted vs cloud feature gating
Family Settings
- Edit family name
- Delete family option (only if no other members)
- Danger zone warnings
Map Visualization Features
Family member markers include:
- Colored circular markers with email initials
- Automatic tooltip showing last update time
- Click for detailed popup with email and coordinates
- Auto-zoom to fit all members when layer enabled
- Single member: centers at zoom 13
- Multiple members: fits bounds with padding
Stimulus Controllers
family_members_controller.js
- Manages family member layer on map
- Creates markers with initials and colors
- Generates tooltips and popups
- Auto-zoom functionality when layer enabled
- Theme-aware styling for tooltips/popups
Feature Gating
DawarichSettings Integration
family_feature_enabled?- Check if family feature is available- Free for self-hosted instances
- Subscription-based for Dawarich Cloud (future)
family_max_members- Configurable member limit per tier
Testing Coverage
Model Tests (68+ tests)
- Association validations
- Business rule enforcement
- User helper methods
- Invitation token generation and expiry
Service Tests (53+ tests)
- Create, Invite, AcceptInvitation, Leave services
- Success and failure scenarios
- Error message validation
- Transaction rollback verification
Controller Tests
- Authorization enforcement
- Successful operations
- Error handling
- Redirect logic
Integration Tests
- Complete invitation flow
- Email delivery
- Notification creation
- Multi-user scenarios
System Tests
- UI interactions
- Form submissions
- Modal interactions
- Map visualization
Implementation Files
Models
app/models/family.rbapp/models/family_membership.rbapp/models/family_invitation.rb- User model extensions
Services
app/services/families/create.rbapp/services/families/invite.rbapp/services/families/accept_invitation.rbapp/services/families/leave.rbapp/services/families/location_sharing_service.rb
Controllers
app/controllers/families_controller.rbapp/controllers/family_memberships_controller.rbapp/controllers/family_invitations_controller.rbapp/controllers/users/sessions_controller.rb
Views
app/views/families/- Dashboard, create, editapp/views/family_invitations/show.html.erb- Enhanced landing pageapp/views/devise/sessions/new.html.erb- Login with invitation contextapp/views/devise/registrations/new.html.erb- Registration with invitation
JavaScript
app/javascript/controllers/family_members_controller.js
Policies
app/policies/family_policy.rbapp/policies/family_membership_policy.rbapp/policies/family_invitation_policy.rb
Mailers
app/mailers/family_mailer.rb- Email templates for invitations
Migrations
db/migrate/..._create_families.rbdb/migrate/..._create_family_memberships.rbdb/migrate/..._create_family_invitations.rb
Routes Summary
Nested resources under families:
resources :families do
member do
delete :leave
patch :update_location_sharing
end
resources :invitations, except: %i[edit update], controller: 'family_invitations' do
member do
post :accept
end
end
resources :members, only: %i[index show destroy], controller: 'family_memberships'
end
# Public family invitation acceptance (no auth required)
get 'invitations/:id', to: 'family_invitations#show', as: :public_invitation
Custom Devise routes for invitation flow:
devise_for :users, controllers: {
registrations: 'users/registrations',
sessions: 'users/sessions'
}
API routes for family locations:
namespace :api do
namespace :v1 do
resources :families, only: [] do
collection do
get :locations
end
end
end
end
Security Considerations
- Token-based Invitations - Secure, unguessable tokens with 7-day expiry
- Sequential IDs - Standard bigint primary keys for performance
- Authorization Policies - Comprehensive Pundit policies for all actions
- Data Privacy - Users control location sharing settings
- Account Protection - Owners cannot delete accounts with active members
- Email Validation - Proper format validation for invitations
Performance Considerations
- Database Indexes - Proper indexing on foreign keys and common queries
- Eager Loading - Use
includes()for associations - Caching - Family locations cached for map display
- Background Jobs - Sidekiq for email sending
- Transaction Safety - All operations wrapped in database transactions
Implementation Phases Summary
✅ Phase 1: Database Foundation - COMPLETED
Database tables, models, associations, validations, and comprehensive tests
✅ Phase 2: Core Business Logic - COMPLETED
Service classes, email system, policies, error handling
✅ Phase 3: Controllers and Routes - COMPLETED
Controllers, authorization, custom Devise integration
✅ Phase 4: User Interface - COMPLETED
Views, enhanced invitation page, map integration, Stimulus controllers, dark mode
✅ Phase 5: Polish and Enhancements - COMPLETED
Map features (auto-zoom, tooltips, popups), error handling, feature gating
Future Enhancements
- Historical Location Sharing - Allow sharing location history with permissions
- Family Messaging - Simple messaging between family members
- Geofencing - Notifications when members enter/leave areas
- Family Events - Plan and track family trips together
- Emergency Features - Quick location sharing in emergencies
- Mobile Push Notifications - Real-time location updates
- Family Statistics - Aggregate travel statistics
- Multiple Families - Allow users in multiple families with different roles
- Rate Limiting - Invitation sending rate limits
Feature Status: ✅ Production Ready
All planned features have been implemented, tested, and are ready for deployment. The family feature maintains Dawarich's patterns for security, privacy, and performance while providing a comprehensive family location sharing experience.
Recent UI/UX Improvements
Invitation Flow Enhancement
- Beautiful landing page with gradient design
- Clear benefit explanations before signup
- Dark mode support throughout
- Proper token preservation through login/registration
- Conditional CTAs based on authentication state
Map Visualization
- Auto-zoom to show all family members when layer enabled
- Real-time tooltips with "Last updated: [time]"
- Detailed popups showing email and coordinates on click
- Theme-aware styling for all map elements
- Smooth user experience with proper bounds handling
These improvements ensure users understand the value proposition before committing and have an excellent experience viewing family locations on the map.