Customer Profile Management¶
Complete guide to managing customer profiles, preferences, consent, and GDPR compliance in the Reserva platform.
Overview¶
The customer profile system provides comprehensive self-service management with GDPR compliance:
- Profile Management - View and update personal information
- Preference Management - Booking preferences, communication channels, localization
- Consent Management - Marketing, data processing, and analytics preferences
- Account Deletion - GDPR-compliant right to be forgotten
Key Concepts:
- Profile = Personal information (name, phone, date of birth, gender)
- Preferences = Booking defaults, communication settings, localization
- Consent = Privacy controls for marketing, analytics, and data processing
- GDPR Compliance = Full data deletion and anonymization capabilities
Get Customer Profile¶
Retrieve the authenticated customer's complete profile information with loyalty and booking statistics.
Endpoint¶
Authentication: Required (Customer JWT token)
Response¶
{
"id": "507f1f77bcf86cd799439011",
"email": "jane.smith@example.com",
"first_name": "Jane",
"last_name": "Smith",
"phone": "+6281234567890",
"date_of_birth": "1990-05-15",
"gender": "female",
"email_verified": true,
"phone_verified": false,
"preferences": {
"preferred_outlet_id": "507f1f77bcf86cd799439012",
"preferred_staff_ids": ["507f1f77bcf86cd799439013"],
"preferred_services": ["507f1f77bcf86cd799439014"],
"communication_preferences": {
"email": true,
"sms": false,
"push": true,
"whatsapp": false
},
"marketing_consent": false,
"language": "en",
"timezone": "Asia/Jakarta"
},
"loyalty_points": 450,
"membership_tier": "silver",
"total_appointments": 12,
"last_appointment_date": "2025-09-30",
"created_at": "2024-06-01T00:00:00Z"
}
Membership Tiers:
Loyalty tier calculation based on accumulated points:
basic- 0-99 pointssilver- 100-499 pointsgold- 500-999 pointsplatinum- 1000+ points
Features:
- Complete customer profile with personal details
- Email and phone verification status
- Loyalty points and membership tier calculation
- Booking history summary statistics
- Customer preferences and settings
- Account creation and verification timestamps
Business Rules:
- Profile data is filtered for privacy compliance
- Loyalty tier calculated based on points
- Booking statistics include all non-deleted appointments
- Verification status reflects current email/phone validation
Update Customer Profile¶
Update the authenticated customer's personal profile information with validation.
Endpoint¶
Authentication: Required (Customer JWT token)
Request Body¶
{
"first_name": "Jane",
"last_name": "Smith",
"phone": "+6281234567890",
"date_of_birth": "1990-05-15",
"gender": "female"
}
Parameters:
first_name(optional) - Customer's first name (1-50 characters)last_name(optional) - Customer's last name (1-50 characters)phone(optional) - Phone number in E.164 format (e.g., +6281234567890)date_of_birth(optional) - Date of birth in YYYY-MM-DD formatgender(optional) - Gender:male,female,other,prefer_not_to_say
Response¶
Returns the updated customer profile (same format as GET profile):
{
"id": "507f1f77bcf86cd799439011",
"email": "jane.smith@example.com",
"first_name": "Jane",
"last_name": "Smith",
"phone": "+6281234567890",
"date_of_birth": "1990-05-15",
"gender": "female",
"email_verified": true,
"phone_verified": false,
"loyalty_points": 450,
"membership_tier": "silver",
"total_appointments": 12,
"created_at": "2024-06-01T00:00:00Z"
}
Business Rules:
- Email cannot be changed through this endpoint (security)
- Phone changes reset verification status to
false - Names are trimmed and validated for length
- At least one field must be provided for update
- Date of birth validation for reasonable age ranges
- All fields are optional (partial updates supported)
Process:
- Validate at least one field is provided
- Sanitize and validate all input fields
- Reset verification status for changed contact info
- Update customer record with new information
- Return updated profile with computed fields
Get Customer Preferences¶
Retrieve the authenticated customer's complete preferences and settings.
Endpoint¶
Authentication: Required (Customer JWT token)
Response¶
{
"preferred_outlet_id": "507f1f77bcf86cd799439012",
"preferred_staff_ids": ["507f1f77bcf86cd799439013", "507f1f77bcf86cd799439014"],
"preferred_services": ["507f1f77bcf86cd799439015"],
"communication_preferences": {
"email": true,
"sms": false,
"push": true,
"whatsapp": false
},
"marketing_consent": false,
"data_processing_consent": true,
"analytics_consent": false,
"language": "en",
"timezone": "Asia/Jakarta",
"notification_settings": {
"booking_reminders": true,
"promotional_offers": false,
"appointment_updates": true,
"loyalty_updates": true
},
"notes": null
}
Features:
- Booking preferences with outlet, staff, and service selections
- Communication channel preferences
- Privacy and consent management
- Notification and alert settings
- Localization preferences (language, timezone)
- Default values for unset preferences
Business Rules:
- Default preferences applied for missing values
- Communication preferences default to privacy-safe settings
- Consent preferences default to minimal required permissions
- Language defaults to English, timezone to UTC
- Preferred entities must exist and be accessible
Default Values:
{
"communication_preferences": {
"email": true,
"sms": false,
"push": true,
"whatsapp": false
},
"marketing_consent": false,
"data_processing_consent": true,
"analytics_consent": false,
"language": "en",
"timezone": "UTC",
"notification_settings": {
"booking_reminders": true,
"promotional_offers": false,
"appointment_updates": true,
"loyalty_updates": true
}
}
Update Customer Preferences¶
Update the authenticated customer's preferences and settings with validation.
Endpoint¶
Authentication: Required (Customer JWT token)
Request Body¶
{
"preferred_outlet_id": "507f1f77bcf86cd799439012",
"preferred_staff_ids": ["507f1f77bcf86cd799439013", "507f1f77bcf86cd799439014"],
"preferred_services": ["507f1f77bcf86cd799439015"],
"communication_preferences": {
"email": true,
"sms": false,
"push": true,
"whatsapp": false
},
"marketing_consent": false,
"language": "en",
"timezone": "Asia/Jakarta",
"notification_settings": {
"booking_reminders": true,
"promotional_offers": false
}
}
Parameters:
preferred_outlet_id(optional) - Default outlet for bookings (ObjectId string)preferred_staff_ids(optional) - List of preferred staff members (array of ObjectId strings)preferred_services(optional) - List of favorite services (array of ObjectId strings)communication_preferences(optional) - Channel preferences (email, sms, push, whatsapp)marketing_consent(optional) - Consent for promotional communications (boolean)language(optional) - Language code:en,id,mstimezone(optional) - IANA timezone string (e.g., "Asia/Jakarta")notification_settings(optional) - Notification preferences by category
Response¶
Returns the updated preferences object (same format as GET preferences).
Business Rules:
- Preferred outlets must exist and be active in tenant
- Preferred staff must exist and be active in tenant
- Preferred services must exist and be active in tenant
- Communication preferences merge with existing settings
- Language must be supported (en, id, ms)
- Timezone validation for valid timezone strings
- All parameters are optional (partial updates supported)
Entity Validation:
The endpoint validates that all referenced entities exist and are accessible:
# Outlet validation
if preferred_outlet_id:
outlet = await db.outlets.find_one({
"_id": ObjectId(preferred_outlet_id),
"tenant_id": tenant_id,
"is_active": True,
"is_deleted": {"$ne": True}
})
if not outlet:
raise HTTPException(400, "Invalid outlet ID")
# Staff validation
if preferred_staff_ids:
staff_count = await db.staff.count_documents({
"_id": {"$in": [ObjectId(id) for id in preferred_staff_ids]},
"tenant_id": tenant_id,
"is_active": True,
"is_deleted": {"$ne": True}
})
if staff_count != len(preferred_staff_ids):
raise HTTPException(400, "Invalid staff IDs")
Process:
- Validate current customer exists
- Merge new preferences with existing preferences
- Validate entity references (outlets, staff, services)
- Apply preference updates with validation
- Save updated preferences to customer record
Update Customer Consent¶
Update customer consent preferences for marketing, data processing, and communications with GDPR compliance.
Endpoint¶
Authentication: Required (Customer JWT token)
Request Body¶
{
"marketing_consent": false,
"data_processing_consent": true,
"analytics_consent": false,
"communication_consent": {
"email": true,
"sms": false,
"push": true,
"whatsapp": false
}
}
Parameters:
marketing_consent(optional) - Consent for marketing communications (boolean)data_processing_consent(optional) - Consent for data processing and optimization (boolean)analytics_consent(optional) - Consent for analytics tracking (boolean)communication_consent(optional) - Channel-specific communication preferences
Response¶
{
"marketing_consent": false,
"data_processing_consent": true,
"analytics_consent": false,
"communication_preferences": {
"email": true,
"sms": false,
"push": true,
"whatsapp": false
},
"last_updated": "2025-10-18T10:30:00Z",
"message": "Consent preferences updated successfully"
}
Features:
- Granular consent management by category
- Timestamp tracking for all consent changes
- Communication channel-specific preferences
- GDPR-compliant consent recording
- Comprehensive audit logging
- Withdrawal capability for all consent types
Business Rules:
- Consent can be granted or withdrawn at any time
- All changes recorded with precise timestamps
- Marketing consent affects promotional communications
- Data processing consent affects analytics and optimization
- Communication consent controls channel preferences
- At least one consent field must be provided for update
Audit Trail:
All consent changes are logged for GDPR compliance:
{
"action": "CUSTOMER_CONSENT_UPDATED",
"entity_type": "customer",
"entity_id": "507f1f77bcf86cd799439011",
"tenant_id": "507f1f77bcf86cd799439010",
"details": {
"consent_changes": {
"marketing": false,
"analytics": false
},
"consent_timestamp": "2025-10-18T10:30:00Z"
},
"created_at": "2025-10-18T10:30:00Z"
}
Process:
- Validate at least one consent field is provided
- Update consent preferences with timestamps
- Merge communication preferences with existing settings
- Save updated preferences to customer record
- Log consent changes for audit compliance
Note: Implements GDPR consent management requirements (Articles 7 & 13).
Delete Customer Account¶
Permanently delete customer account and all associated data (GDPR Right to be Forgotten).
Endpoint¶
Authentication: Required (Customer JWT token)
Request Body¶
No request body required.
Response¶
{
"success": true,
"message": "Account deletion completed successfully. All personal data has been permanently removed in compliance with GDPR."
}
Features:
- Complete account deletion with data anonymization
- GDPR-compliant data removal process
- Past appointment anonymization for business records
- Payment record anonymization for accounting
- Comprehensive audit logging
- Immediate session termination
Business Rules:
- Cannot delete with pending or processing payments
- Cannot delete with future appointments (not cancelled/no-show)
- Past appointments anonymized but preserved for business records
- Completed payments anonymized but preserved for accounting
- All other customer data permanently deleted
- Action is irreversible once completed
Pre-Deletion Checks:
# Check 1: Pending payments
pending_payments = await db.payments.count_documents({
"customer_id": customer_id,
"status": {"$in": ["pending", "processing"]}
})
if pending_payments > 0:
raise HTTPException(400, "Cannot delete with pending payments")
# Check 2: Future appointments
future_appointments = await db.appointments.count_documents({
"customer_id": customer_id,
"appointment_date": {"$gte": today},
"status": {"$nin": ["cancelled", "no_show"]}
})
if future_appointments > 0:
raise HTTPException(400, "Cannot delete with upcoming appointments")
GDPR Deletion Process (10 Steps)¶
The deletion follows a comprehensive data removal process:
-
Anonymize Past Appointments - Remove PII, keep business data
-
Delete Customer Sessions - Remove all active sessions
-
Delete Customer Wallet - Remove wallet and balance
-
Delete Customer Reviews - Remove all reviews and ratings
-
Delete Customer Notifications - Remove notification history
-
Delete Saved Payment Methods - Remove stored payment data
-
Anonymize Completed Payments - Keep for accounting, remove PII
-
Delete Incomplete Payments - Permanently remove non-completed payments
-
Delete Customer Record - Hard delete customer document
-
Audit Logging - Record deletion for compliance
{ "action": "CUSTOMER_ACCOUNT_DELETED", "entity_type": "customer", "entity_id": "507f1f77bcf86cd799439011", "details": { "email": "jane.smith@example.com", "deletion_timestamp": "2025-10-18T10:30:00Z", "gdpr_deletion": true, "reason": "Customer requested account deletion (GDPR Right to be Forgotten)" } }
Data Retention for Business Compliance:
| Data Type | Action | Reason |
|---|---|---|
| Customer Record | Hard delete | GDPR compliance |
| Past Appointments | Anonymize | Business records, analytics |
| Completed Payments | Anonymize | Accounting, tax compliance |
| Incomplete Payments | Hard delete | No compliance requirement |
| Sessions | Hard delete | No longer needed |
| Wallet | Hard delete | GDPR compliance |
| Reviews | Hard delete | User-generated content |
| Notifications | Hard delete | Personal communications |
Important Notes:
- This implements GDPR Article 17 "Right to be Forgotten"
- Deletion is immediate and irreversible
- Customer will be immediately logged out after deletion
- Business records (appointments, payments) are anonymized, not deleted
- Audit logs are retained for compliance purposes
Subscription Plan Limitations¶
Customer profile features are available across all subscription plans with no restrictions:
| Feature | FREE | PRO | ENTERPRISE |
|---|---|---|---|
| Profile Management | ✅ Full access | ✅ Full access | ✅ Full access |
| Preference Updates | ✅ Full access | ✅ Full access | ✅ Full access |
| Consent Management | ✅ Full access | ✅ Full access | ✅ Full access |
| Account Deletion | ✅ Full access | ✅ Full access | ✅ Full access |
| Loyalty Points | ✅ Enabled | ✅ Enabled | ✅ Enabled |
| Membership Tiers | ✅ All tiers | ✅ All tiers | ✅ All tiers |
Note: Customer profile management is a core feature available to all customers regardless of the tenant's subscription plan. Subscription limits apply to tenant-level features (outlets, staff, appointments) as documented in Subscription Management.
Related Documentation¶
- Customer Authentication - Customer registration, login, email verification
- Customer Booking - Creating appointments, viewing bookings
- Subscription Management - Tenant subscription plans and limits
- Appointment Management - Admin appointment management
- Invoice Management - Payment and invoice tracking
Security & Privacy¶
Data Protection¶
Personal Information Security:
- All profile data encrypted at rest
- JWT tokens for authentication
- Password hashing with bcrypt
- Secure session management
- Rate limiting on profile updates
GDPR Compliance:
- Right to access (GET /profile)
- Right to rectification (PUT /profile)
- Right to data portability (GET /profile returns all data)
- Right to erasure (DELETE /account)
- Right to withdraw consent (PUT /consent)
- Consent tracking with timestamps
- Comprehensive audit logging
Privacy Controls¶
Customer Privacy Features:
- Granular consent management
- Communication channel preferences
- Marketing opt-out capability
- Analytics opt-out capability
- Data processing transparency
- Account deletion with anonymization
Data Anonymization:
When customers delete their accounts, the system:
- Removes all PII (name, email, phone)
- Preserves business data (anonymized appointments, payments)
- Maintains referential integrity (foreign keys set to null)
- Keeps audit trails (compliance requirement)
Best Practices¶
For Customers¶
✅ DO:
- Keep profile information up-to-date for better service
- Verify email and phone for appointment reminders
- Set preferred outlets and staff for faster booking
- Review consent preferences regularly
- Update communication preferences to reduce unwanted messages
- Cancel pending payments before account deletion
❌ DON'T:
- Share account credentials with others
- Use fake or incorrect personal information
- Ignore verification emails/SMS
- Delete account with pending bookings or payments
- Provide invalid phone numbers (affects SMS notifications)
For Developers¶
✅ DO:
- Always validate entity references (outlets, staff, services)
- Log all consent changes for GDPR compliance
- Implement idempotency for profile updates
- Use transactions for multi-step operations
- Sanitize and trim all user input
- Reset verification status when contact info changes
- Preserve business records during deletion
❌ DON'T:
- Allow email changes without re-verification
- Skip validation of preferred entities
- Delete business records (anonymize instead)
- Process deletion without checking dependencies
- Skip audit logging for consent changes
- Trust client-provided verification status
Troubleshooting¶
Profile Update Fails¶
Symptoms: 400 Bad Request when updating profile
Common Causes:
- Invalid phone number format (must be E.164: +6281234567890)
- Invalid gender value (must be: male, female, other, prefer_not_to_say)
- No fields provided for update
- Name exceeds 50 characters
Fix:
- Validate phone number format before submission
- Use allowed gender values only
- Provide at least one field for update
- Keep names under 50 characters
Preference Update Rejected¶
Symptoms: 400 Bad Request with "Invalid outlet/staff/service ID"
Common Causes:
- Referenced outlet doesn't exist or is inactive
- Staff member not active in tenant
- Service not available in tenant
- Using wrong tenant's entity IDs
Fix:
- Verify entity IDs belong to current tenant
- Ensure entities are active and not deleted
- Use GET endpoints to fetch valid entity IDs first
- Check entity status before setting as preferred
Account Deletion Blocked¶
Symptoms: 400 Bad Request "Cannot delete account"
Common Causes:
- Pending or processing payments exist
- Future appointments not cancelled
- Incomplete payment transactions
Fix:
- Cancel or complete all pending payments first
- Cancel all future appointments before deletion
- Wait for payment processing to complete
- Contact support if issues persist
Consent Update Not Reflected¶
Symptoms: Consent changes don't affect communications
Common Causes:
- Background jobs haven't processed changes yet
- Communication system cache not invalidated
- Email already in send queue before consent withdrawal
Fix:
- Wait 5-10 minutes for changes to propagate
- Check consent preferences with GET /preferences
- Contact support to stop queued communications
- Review audit logs to confirm consent was recorded
API Reference Summary¶
| Endpoint | Method | Purpose | Authentication |
|---|---|---|---|
/customers/profile |
GET | Get customer profile | Customer JWT |
/customers/profile |
PUT | Update customer profile | Customer JWT |
/customers/preferences |
GET | Get customer preferences | Customer JWT |
/customers/preferences |
PUT | Update customer preferences | Customer JWT |
/customers/consent |
PUT | Update consent preferences | Customer JWT |
/customers/account |
DELETE | Delete customer account | Customer JWT |
Example Workflows¶
Complete Profile Setup¶
# 1. Register and login (see customer-authentication.md)
# 2. Get current profile
curl -X GET http://localhost:8000/api/v1/customers/profile \
-H "Authorization: Bearer $CUSTOMER_TOKEN"
# 3. Update personal information
curl -X PUT http://localhost:8000/api/v1/customers/profile \
-H "Authorization: Bearer $CUSTOMER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"first_name": "Jane",
"last_name": "Smith",
"phone": "+6281234567890",
"date_of_birth": "1990-05-15",
"gender": "female"
}'
# 4. Set booking preferences
curl -X PUT http://localhost:8000/api/v1/customers/preferences \
-H "Authorization: Bearer $CUSTOMER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"preferred_outlet_id": "507f1f77bcf86cd799439012",
"preferred_staff_ids": ["507f1f77bcf86cd799439013"],
"language": "en",
"timezone": "Asia/Jakarta",
"communication_preferences": {
"email": true,
"sms": false,
"push": true
}
}'
# 5. Update consent preferences
curl -X PUT http://localhost:8000/api/v1/customers/consent \
-H "Authorization: Bearer $CUSTOMER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"marketing_consent": false,
"analytics_consent": false
}'
Privacy-Focused Configuration¶
# Opt out of all non-essential communications
curl -X PUT http://localhost:8000/api/v1/customers/consent \
-H "Authorization: Bearer $CUSTOMER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"marketing_consent": false,
"analytics_consent": false,
"communication_consent": {
"email": true,
"sms": false,
"push": false,
"whatsapp": false
}
}'
# Minimal notification settings
curl -X PUT http://localhost:8000/api/v1/customers/preferences \
-H "Authorization: Bearer $CUSTOMER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"notification_settings": {
"booking_reminders": true,
"promotional_offers": false,
"appointment_updates": true,
"loyalty_updates": false
}
}'
Account Deletion Workflow¶
# 1. Check for pending obligations
curl -X GET http://localhost:8000/api/v1/customers/appointments/upcoming \
-H "Authorization: Bearer $CUSTOMER_TOKEN"
# 2. Cancel future appointments if any
curl -X PUT http://localhost:8000/api/v1/customers/appointments/{id}/cancel \
-H "Authorization: Bearer $CUSTOMER_TOKEN"
# 3. Verify no pending payments
curl -X GET http://localhost:8000/api/v1/customers/payments?status=pending \
-H "Authorization: Bearer $CUSTOMER_TOKEN"
# 4. Delete account
curl -X DELETE http://localhost:8000/api/v1/customers/account \
-H "Authorization: Bearer $CUSTOMER_TOKEN"
Next Steps:
- Complete customer profile after registration
- Set booking preferences for faster checkout
- Configure notification preferences
- Review and update consent settings
- Verify email and phone for appointment reminders
For authentication and registration, see Customer Authentication. For booking appointments, see Customer Booking.