package valueobjects import ( "knowfoolery/backend/shared/types" ) // PrivacySettings represents a user's privacy preferences type PrivacySettings struct { // Profile visibility profileVisibility ProfileVisibility showRealName bool showEmail bool showDateOfBirth bool showLocation bool // Statistics visibility showStatistics bool showGameHistory bool showAchievements bool showRankings bool // Social features allowFriendRequests bool allowGameInvitations bool allowMessages bool showOnlineStatus bool // Leaderboard participation participateInLeaderboards bool showInGlobalRankings bool allowRankingComparison bool // Data collection allowAnalytics bool allowMarketing bool shareDataWithPartners bool // Communication preferences allowContactByEmail bool allowContactBySMS bool allowPushNotifications bool // Search and discovery allowProfileSearch bool showInPlayerDirectory bool allowRecommendations bool // Update tracking updatedAt types.Timestamp } // ProfileVisibility defines who can see a user's profile type ProfileVisibility string const ( ProfileVisibilityPublic ProfileVisibility = "public" // Anyone can see ProfileVisibilityFriends ProfileVisibility = "friends" // Only friends can see ProfileVisibilityPrivate ProfileVisibility = "private" // Only user can see ProfileVisibilityLimited ProfileVisibility = "limited" // Limited public visibility ) // NewDefaultPrivacySettings creates privacy settings with secure defaults func NewDefaultPrivacySettings() *PrivacySettings { return &PrivacySettings{ // Conservative defaults for privacy profileVisibility: ProfileVisibilityLimited, showRealName: false, showEmail: false, showDateOfBirth: false, showLocation: false, showStatistics: true, // Game stats are generally okay to show showGameHistory: false, // More private showAchievements: true, // Generally okay to show showRankings: true, // Part of competitive gaming allowFriendRequests: true, allowGameInvitations: true, allowMessages: false, // Conservative default showOnlineStatus: false, // Privacy-focused default participateInLeaderboards: true, // Core feature showInGlobalRankings: true, // Core feature allowRankingComparison: true, allowAnalytics: true, // Needed for game improvement allowMarketing: false, // User should opt-in shareDataWithPartners: false, // User should opt-in allowContactByEmail: true, // Important notifications allowContactBySMS: false, // User should opt-in allowPushNotifications: true, // Core functionality allowProfileSearch: false, // Privacy-focused showInPlayerDirectory: false, // Privacy-focused allowRecommendations: true, // Improves experience updatedAt: types.NewTimestamp(), } } // NewPrivacySettings creates privacy settings with specified values func NewPrivacySettings( profileVisibility ProfileVisibility, showStatistics bool, allowFriendRequests bool, ) *PrivacySettings { settings := NewDefaultPrivacySettings() settings.profileVisibility = profileVisibility settings.showStatistics = showStatistics settings.allowFriendRequests = allowFriendRequests settings.markUpdated() return settings } // Getters // ProfileVisibility returns the profile visibility setting func (ps *PrivacySettings) ProfileVisibility() ProfileVisibility { return ps.profileVisibility } // ShowRealName returns true if real name should be shown func (ps *PrivacySettings) ShowRealName() bool { return ps.showRealName } // ShowEmail returns true if email should be shown func (ps *PrivacySettings) ShowEmail() bool { return ps.showEmail } // ShowDateOfBirth returns true if date of birth should be shown func (ps *PrivacySettings) ShowDateOfBirth() bool { return ps.showDateOfBirth } // ShowLocation returns true if location should be shown func (ps *PrivacySettings) ShowLocation() bool { return ps.showLocation } // ShowStatistics returns true if statistics should be shown func (ps *PrivacySettings) ShowStatistics() bool { return ps.showStatistics } // ShowGameHistory returns true if game history should be shown func (ps *PrivacySettings) ShowGameHistory() bool { return ps.showGameHistory } // ShowAchievements returns true if achievements should be shown func (ps *PrivacySettings) ShowAchievements() bool { return ps.showAchievements } // ShowRankings returns true if rankings should be shown func (ps *PrivacySettings) ShowRankings() bool { return ps.showRankings } // AllowFriendRequests returns true if friend requests are allowed func (ps *PrivacySettings) AllowFriendRequests() bool { return ps.allowFriendRequests } // AllowGameInvitations returns true if game invitations are allowed func (ps *PrivacySettings) AllowGameInvitations() bool { return ps.allowGameInvitations } // AllowMessages returns true if messages are allowed func (ps *PrivacySettings) AllowMessages() bool { return ps.allowMessages } // ShowOnlineStatus returns true if online status should be shown func (ps *PrivacySettings) ShowOnlineStatus() bool { return ps.showOnlineStatus } // ParticipateInLeaderboards returns true if user participates in leaderboards func (ps *PrivacySettings) ParticipateInLeaderboards() bool { return ps.participateInLeaderboards } // ShowInGlobalRankings returns true if user should appear in global rankings func (ps *PrivacySettings) ShowInGlobalRankings() bool { return ps.showInGlobalRankings } // AllowRankingComparison returns true if ranking comparison is allowed func (ps *PrivacySettings) AllowRankingComparison() bool { return ps.allowRankingComparison } // AllowAnalytics returns true if analytics are allowed func (ps *PrivacySettings) AllowAnalytics() bool { return ps.allowAnalytics } // AllowMarketing returns true if marketing is allowed func (ps *PrivacySettings) AllowMarketing() bool { return ps.allowMarketing } // ShareDataWithPartners returns true if data sharing with partners is allowed func (ps *PrivacySettings) ShareDataWithPartners() bool { return ps.shareDataWithPartners } // AllowContactByEmail returns true if email contact is allowed func (ps *PrivacySettings) AllowContactByEmail() bool { return ps.allowContactByEmail } // AllowContactBySMS returns true if SMS contact is allowed func (ps *PrivacySettings) AllowContactBySMS() bool { return ps.allowContactBySMS } // AllowPushNotifications returns true if push notifications are allowed func (ps *PrivacySettings) AllowPushNotifications() bool { return ps.allowPushNotifications } // AllowProfileSearch returns true if profile search is allowed func (ps *PrivacySettings) AllowProfileSearch() bool { return ps.allowProfileSearch } // ShowInPlayerDirectory returns true if user should appear in player directory func (ps *PrivacySettings) ShowInPlayerDirectory() bool { return ps.showInPlayerDirectory } // AllowRecommendations returns true if recommendations are allowed func (ps *PrivacySettings) AllowRecommendations() bool { return ps.allowRecommendations } // UpdatedAt returns the last update timestamp func (ps *PrivacySettings) UpdatedAt() types.Timestamp { return ps.updatedAt } // Business methods // SetProfileVisibility sets the profile visibility func (ps *PrivacySettings) SetProfileVisibility(visibility ProfileVisibility) error { validVisibilities := []ProfileVisibility{ ProfileVisibilityPublic, ProfileVisibilityFriends, ProfileVisibilityPrivate, ProfileVisibilityLimited, } isValid := false for _, valid := range validVisibilities { if visibility == valid { isValid = true break } } if !isValid { return errors.ErrValidationFailed("profile_visibility", "invalid profile visibility") } ps.profileVisibility = visibility ps.markUpdated() return nil } // SetProfileInfoVisibility sets which profile information is visible func (ps *PrivacySettings) SetProfileInfoVisibility( showRealName bool, showEmail bool, showDateOfBirth bool, showLocation bool, ) { ps.showRealName = showRealName ps.showEmail = showEmail ps.showDateOfBirth = showDateOfBirth ps.showLocation = showLocation ps.markUpdated() } // SetStatisticsVisibility sets which statistics are visible func (ps *PrivacySettings) SetStatisticsVisibility( showStatistics bool, showGameHistory bool, showAchievements bool, showRankings bool, ) { ps.showStatistics = showStatistics ps.showGameHistory = showGameHistory ps.showAchievements = showAchievements ps.showRankings = showRankings ps.markUpdated() } // SetSocialSettings sets social interaction preferences func (ps *PrivacySettings) SetSocialSettings( allowFriendRequests bool, allowGameInvitations bool, allowMessages bool, showOnlineStatus bool, ) { ps.allowFriendRequests = allowFriendRequests ps.allowGameInvitations = allowGameInvitations ps.allowMessages = allowMessages ps.showOnlineStatus = showOnlineStatus ps.markUpdated() } // SetLeaderboardSettings sets leaderboard participation preferences func (ps *PrivacySettings) SetLeaderboardSettings( participateInLeaderboards bool, showInGlobalRankings bool, allowRankingComparison bool, ) { ps.participateInLeaderboards = participateInLeaderboards ps.showInGlobalRankings = showInGlobalRankings ps.allowRankingComparison = allowRankingComparison ps.markUpdated() } // SetDataCollectionSettings sets data collection preferences func (ps *PrivacySettings) SetDataCollectionSettings( allowAnalytics bool, allowMarketing bool, shareDataWithPartners bool, ) { ps.allowAnalytics = allowAnalytics ps.allowMarketing = allowMarketing ps.shareDataWithPartners = shareDataWithPartners ps.markUpdated() } // SetCommunicationSettings sets communication preferences func (ps *PrivacySettings) SetCommunicationSettings( allowContactByEmail bool, allowContactBySMS bool, allowPushNotifications bool, ) { ps.allowContactByEmail = allowContactByEmail ps.allowContactBySMS = allowContactBySMS ps.allowPushNotifications = allowPushNotifications ps.markUpdated() } // SetDiscoverySettings sets search and discovery preferences func (ps *PrivacySettings) SetDiscoverySettings( allowProfileSearch bool, showInPlayerDirectory bool, allowRecommendations bool, ) { ps.allowProfileSearch = allowProfileSearch ps.showInPlayerDirectory = showInPlayerDirectory ps.allowRecommendations = allowRecommendations ps.markUpdated() } // ApplyPrivacyTemplate applies a privacy template func (ps *PrivacySettings) ApplyPrivacyTemplate(template PrivacyTemplate) { switch template { case PrivacyTemplatePublic: ps.applyPublicTemplate() case PrivacyTemplateBalanced: ps.applyBalancedTemplate() case PrivacyTemplatePrivate: ps.applyPrivateTemplate() case PrivacyTemplateMinimal: ps.applyMinimalTemplate() } ps.markUpdated() } // Query methods // IsProfilePublic returns true if profile is publicly visible func (ps *PrivacySettings) IsProfilePublic() bool { return ps.profileVisibility == ProfileVisibilityPublic } // IsProfilePrivate returns true if profile is completely private func (ps *PrivacySettings) IsProfilePrivate() bool { return ps.profileVisibility == ProfileVisibilityPrivate } // CanBeContactedByEmail returns true if user can be contacted by email func (ps *PrivacySettings) CanBeContactedByEmail() bool { return ps.allowContactByEmail } // CanReceiveGameInvitations returns true if user can receive game invitations func (ps *PrivacySettings) CanReceiveGameInvitations() bool { return ps.allowGameInvitations } // HasDataSharingEnabled returns true if any data sharing is enabled func (ps *PrivacySettings) HasDataSharingEnabled() bool { return ps.allowAnalytics || ps.allowMarketing || ps.shareDataWithPartners } // IsDiscoverable returns true if user can be discovered by others func (ps *PrivacySettings) IsDiscoverable() bool { return ps.allowProfileSearch || ps.showInPlayerDirectory } // GetPrivacyLevel returns a privacy level score (0-100, higher = more private) func (ps *PrivacySettings) GetPrivacyLevel() int { score := 0 // Profile visibility (0-25 points) switch ps.profileVisibility { case ProfileVisibilityPrivate: score += 25 case ProfileVisibilityLimited: score += 15 case ProfileVisibilityFriends: score += 10 case ProfileVisibilityPublic: score += 0 } // Profile information visibility (0-20 points) if !ps.showRealName { score += 5 } if !ps.showEmail { score += 5 } if !ps.showDateOfBirth { score += 5 } if !ps.showLocation { score += 5 } // Social settings (0-15 points) if !ps.allowFriendRequests { score += 3 } if !ps.allowGameInvitations { score += 3 } if !ps.allowMessages { score += 4 } if !ps.showOnlineStatus { score += 5 } // Data collection (0-20 points) if !ps.allowAnalytics { score += 5 } if !ps.allowMarketing { score += 7 } if !ps.shareDataWithPartners { score += 8 } // Discovery settings (0-20 points) if !ps.allowProfileSearch { score += 10 } if !ps.showInPlayerDirectory { score += 10 } return score } // Validation // Validate performs validation on the privacy settings func (ps *PrivacySettings) Validate() *types.ValidationResult { result := types.NewValidationResult() // Validate profile visibility validVisibilities := []ProfileVisibility{ ProfileVisibilityPublic, ProfileVisibilityFriends, ProfileVisibilityPrivate, ProfileVisibilityLimited, } isValidVisibility := false for _, valid := range validVisibilities { if ps.profileVisibility == valid { isValidVisibility = true break } } if !isValidVisibility { result.AddError("invalid profile visibility") } // Logic validation if ps.profileVisibility == ProfileVisibilityPrivate { // If profile is private, certain things shouldn't be visible if ps.showRealName || ps.showEmail || ps.allowProfileSearch || ps.showInPlayerDirectory { result.AddWarning("private profile has some public visibility settings enabled") } } return result } // Helper methods // markUpdated updates the timestamp func (ps *PrivacySettings) markUpdated() { ps.updatedAt = types.NewTimestamp() } // applyPublicTemplate applies the public privacy template func (ps *PrivacySettings) applyPublicTemplate() { ps.profileVisibility = ProfileVisibilityPublic ps.showRealName = true ps.showStatistics = true ps.showGameHistory = true ps.showAchievements = true ps.showRankings = true ps.allowFriendRequests = true ps.allowGameInvitations = true ps.allowMessages = true ps.showOnlineStatus = true ps.participateInLeaderboards = true ps.showInGlobalRankings = true ps.allowProfileSearch = true ps.showInPlayerDirectory = true ps.allowRecommendations = true } // applyBalancedTemplate applies the balanced privacy template func (ps *PrivacySettings) applyBalancedTemplate() { ps.profileVisibility = ProfileVisibilityLimited ps.showRealName = false ps.showStatistics = true ps.showGameHistory = false ps.showAchievements = true ps.showRankings = true ps.allowFriendRequests = true ps.allowGameInvitations = true ps.allowMessages = false ps.showOnlineStatus = false ps.participateInLeaderboards = true ps.showInGlobalRankings = true ps.allowProfileSearch = false ps.showInPlayerDirectory = false ps.allowRecommendations = true } // applyPrivateTemplate applies the private privacy template func (ps *PrivacySettings) applyPrivateTemplate() { ps.profileVisibility = ProfileVisibilityPrivate ps.showRealName = false ps.showEmail = false ps.showDateOfBirth = false ps.showLocation = false ps.showStatistics = false ps.showGameHistory = false ps.showAchievements = false ps.showRankings = false ps.allowFriendRequests = false ps.allowGameInvitations = false ps.allowMessages = false ps.showOnlineStatus = false ps.participateInLeaderboards = false ps.showInGlobalRankings = false ps.allowProfileSearch = false ps.showInPlayerDirectory = false ps.allowMarketing = false ps.shareDataWithPartners = false } // applyMinimalTemplate applies the minimal privacy template (essential features only) func (ps *PrivacySettings) applyMinimalTemplate() { ps.profileVisibility = ProfileVisibilityFriends ps.showRealName = false ps.showEmail = false ps.showDateOfBirth = false ps.showLocation = false ps.showStatistics = true // Keep for core functionality ps.showGameHistory = false ps.showAchievements = true // Keep for core functionality ps.showRankings = true // Keep for core functionality ps.allowFriendRequests = true // Essential social feature ps.allowGameInvitations = true // Essential game feature ps.allowMessages = false ps.showOnlineStatus = false ps.participateInLeaderboards = true // Core feature ps.showInGlobalRankings = true // Core feature ps.allowProfileSearch = false ps.showInPlayerDirectory = false ps.allowAnalytics = true // Needed for game improvement ps.allowMarketing = false ps.shareDataWithPartners = false } // ToSnapshot creates a read-only snapshot func (ps *PrivacySettings) ToSnapshot() *PrivacySettingsSnapshot { return &PrivacySettingsSnapshot{ ProfileVisibility: ps.profileVisibility, ShowRealName: ps.showRealName, ShowEmail: ps.showEmail, ShowDateOfBirth: ps.showDateOfBirth, ShowLocation: ps.showLocation, ShowStatistics: ps.showStatistics, ShowGameHistory: ps.showGameHistory, ShowAchievements: ps.showAchievements, ShowRankings: ps.showRankings, AllowFriendRequests: ps.allowFriendRequests, AllowGameInvitations: ps.allowGameInvitations, AllowMessages: ps.allowMessages, ShowOnlineStatus: ps.showOnlineStatus, ParticipateInLeaderboards: ps.participateInLeaderboards, ShowInGlobalRankings: ps.showInGlobalRankings, AllowRankingComparison: ps.allowRankingComparison, AllowAnalytics: ps.allowAnalytics, AllowMarketing: ps.allowMarketing, ShareDataWithPartners: ps.shareDataWithPartners, AllowContactByEmail: ps.allowContactByEmail, AllowContactBySMS: ps.allowContactBySMS, AllowPushNotifications: ps.allowPushNotifications, AllowProfileSearch: ps.allowProfileSearch, ShowInPlayerDirectory: ps.showInPlayerDirectory, AllowRecommendations: ps.allowRecommendations, UpdatedAt: ps.updatedAt, } } // Privacy templates type PrivacyTemplate string const ( PrivacyTemplatePublic PrivacyTemplate = "public" PrivacyTemplateBalanced PrivacyTemplate = "balanced" PrivacyTemplatePrivate PrivacyTemplate = "private" PrivacyTemplateMinimal PrivacyTemplate = "minimal" ) // PrivacySettingsSnapshot represents a read-only view of privacy settings type PrivacySettingsSnapshot struct { ProfileVisibility ProfileVisibility `json:"profile_visibility"` ShowRealName bool `json:"show_real_name"` ShowEmail bool `json:"show_email"` ShowDateOfBirth bool `json:"show_date_of_birth"` ShowLocation bool `json:"show_location"` ShowStatistics bool `json:"show_statistics"` ShowGameHistory bool `json:"show_game_history"` ShowAchievements bool `json:"show_achievements"` ShowRankings bool `json:"show_rankings"` AllowFriendRequests bool `json:"allow_friend_requests"` AllowGameInvitations bool `json:"allow_game_invitations"` AllowMessages bool `json:"allow_messages"` ShowOnlineStatus bool `json:"show_online_status"` ParticipateInLeaderboards bool `json:"participate_in_leaderboards"` ShowInGlobalRankings bool `json:"show_in_global_rankings"` AllowRankingComparison bool `json:"allow_ranking_comparison"` AllowAnalytics bool `json:"allow_analytics"` AllowMarketing bool `json:"allow_marketing"` ShareDataWithPartners bool `json:"share_data_with_partners"` AllowContactByEmail bool `json:"allow_contact_by_email"` AllowContactBySMS bool `json:"allow_contact_by_sms"` AllowPushNotifications bool `json:"allow_push_notifications"` AllowProfileSearch bool `json:"allow_profile_search"` ShowInPlayerDirectory bool `json:"show_in_player_directory"` AllowRecommendations bool `json:"allow_recommendations"` UpdatedAt types.Timestamp `json:"updated_at"` } // GetPrivacyLevel returns the privacy level from the snapshot func (pss *PrivacySettingsSnapshot) GetPrivacyLevel() int { score := 0 switch pss.ProfileVisibility { case ProfileVisibilityPrivate: score += 25 case ProfileVisibilityLimited: score += 15 case ProfileVisibilityFriends: score += 10 case ProfileVisibilityPublic: score += 0 } if !pss.ShowRealName { score += 5 } if !pss.ShowEmail { score += 5 } if !pss.ShowDateOfBirth { score += 5 } if !pss.ShowLocation { score += 5 } if !pss.AllowFriendRequests { score += 3 } if !pss.AllowGameInvitations { score += 3 } if !pss.AllowMessages { score += 4 } if !pss.ShowOnlineStatus { score += 5 } if !pss.AllowAnalytics { score += 5 } if !pss.AllowMarketing { score += 7 } if !pss.ShareDataWithPartners { score += 8 } if !pss.AllowProfileSearch { score += 10 } if !pss.ShowInPlayerDirectory { score += 10 } return score }