business: add privacy-aware user projection

(cherry picked from commit a636192ef22ee69d792b0ca7db1c6be963be9cb2)
This commit is contained in:
A 2026-06-08 01:07:21 +08:00
parent 14d220c971
commit 8ff3343ae0
29 changed files with 2239 additions and 112 deletions

View file

@ -258,11 +258,21 @@ type StickerSet struct {
SystemKey string `json:"system_key,omitempty"`
}
// ProfilePhotoRef 是渲染头像所需的最小信息(当前 profile photo
// ProfilePhotoKind distinguishes a user's real profile photo from the fallback
// public photo shown when privacy hides the real one.
type ProfilePhotoKind string
const (
ProfilePhotoKindProfile ProfilePhotoKind = "profile"
ProfilePhotoKindFallback ProfilePhotoKind = "fallback"
)
// ProfilePhotoRef 是渲染头像所需的最小信息(当前 profile/fallback/personal photo
type ProfilePhotoRef struct {
PhotoID int64
DCID int
Stripped []byte // photoStrippedSize 内联缩略图,可空
Personal bool // true 表示 viewer 私有联系人头像
}
// StrippedFromSizes 从照片尺寸列表里取出 stripped 缩略图字节(用于 UserProfilePhoto/ChatPhoto 占位)。

View file

@ -0,0 +1,83 @@
package domain
import "errors"
// PrivacyKey identifies a Telegram account privacy setting without exposing tg.*.
type PrivacyKey string
const (
PrivacyKeyStatusTimestamp PrivacyKey = "status_timestamp"
PrivacyKeyChatInvite PrivacyKey = "chat_invite"
PrivacyKeyPhoneCall PrivacyKey = "phone_call"
PrivacyKeyPhoneP2P PrivacyKey = "phone_p2p"
PrivacyKeyForwards PrivacyKey = "forwards"
PrivacyKeyProfilePhoto PrivacyKey = "profile_photo"
PrivacyKeyPhoneNumber PrivacyKey = "phone_number"
PrivacyKeyAddedByPhone PrivacyKey = "added_by_phone"
PrivacyKeyVoiceMessages PrivacyKey = "voice_messages"
PrivacyKeyAbout PrivacyKey = "about"
PrivacyKeyBirthday PrivacyKey = "birthday"
PrivacyKeyStarGiftsAutoSave PrivacyKey = "star_gifts_auto_save"
PrivacyKeyNoPaidMessages PrivacyKey = "no_paid_messages"
PrivacyKeySavedMusic PrivacyKey = "saved_music"
)
// PrivacyRuleKind mirrors Layer 225 privacy rule constructors.
type PrivacyRuleKind string
const (
PrivacyRuleAllowContacts PrivacyRuleKind = "allow_contacts"
PrivacyRuleAllowAll PrivacyRuleKind = "allow_all"
PrivacyRuleAllowUsers PrivacyRuleKind = "allow_users"
PrivacyRuleDisallowContacts PrivacyRuleKind = "disallow_contacts"
PrivacyRuleDisallowAll PrivacyRuleKind = "disallow_all"
PrivacyRuleDisallowUsers PrivacyRuleKind = "disallow_users"
PrivacyRuleAllowChatParticipants PrivacyRuleKind = "allow_chat_participants"
PrivacyRuleDisallowChatParticipants PrivacyRuleKind = "disallow_chat_participants"
PrivacyRuleAllowCloseFriends PrivacyRuleKind = "allow_close_friends"
PrivacyRuleAllowPremium PrivacyRuleKind = "allow_premium"
PrivacyRuleAllowBots PrivacyRuleKind = "allow_bots"
PrivacyRuleDisallowBots PrivacyRuleKind = "disallow_bots"
)
// PrivacyRule is a protocol-neutral privacy rule.
type PrivacyRule struct {
Kind PrivacyRuleKind `json:"kind"`
UserIDs []int64 `json:"user_ids,omitempty"`
ChatIDs []int64 `json:"chat_ids,omitempty"`
}
// PrivacyRules is one owner/key rule set.
type PrivacyRules struct {
OwnerUserID int64 `json:"owner_user_id,omitempty"`
Key PrivacyKey `json:"key"`
Rules []PrivacyRule `json:"rules"`
}
// PrivacyContext describes viewer facts needed for privacy evaluation.
type PrivacyContext struct {
OwnerUserID int64
ViewerUserID int64
ViewerIsContact bool
ViewerIsBot bool
ViewerIsPremium bool
ViewerCloseFriend bool
SharedChatIDs []int64
}
var (
ErrPrivacyKeyInvalid = errors.New("privacy key invalid")
ErrPrivacyRuleInvalid = errors.New("privacy rule invalid")
)
// DefaultPrivacyRules returns Telegram-like defaults used when no user setting exists.
func DefaultPrivacyRules(key PrivacyKey) []PrivacyRule {
switch key {
case PrivacyKeyPhoneNumber:
return []PrivacyRule{{Kind: PrivacyRuleDisallowAll}}
case PrivacyKeyBirthday:
return []PrivacyRule{{Kind: PrivacyRuleAllowContacts}}
default:
return []PrivacyRule{{Kind: PrivacyRuleAllowAll}}
}
}

View file

@ -21,10 +21,11 @@ type User struct {
Support bool
Contact bool
Mutual bool
// Profile photo:反范式存于 users 表,便于无 join 渲染头像。PhotoID==0 表示无头像。
// Profile photo fields are filled by app-layer user projection. PhotoID==0 表示无头像。
PhotoID int64
PhotoDCID int
PhotoStripped []byte
PhotoPersonal bool
LastSeenAt int
Status UserStatus
}
@ -61,3 +62,17 @@ type UserProfileUpdate struct {
About string
HasAbout bool
}
// UserFullView is the app-layer personalized full user view consumed by RPC.
type UserFullView struct {
User User
ProfilePhoto *Photo
PersonalPhoto *Photo
FallbackPhoto *Photo
About string
PhoneCallsAvailable bool
PhoneCallsPrivate bool
VideoCallsAvailable bool
VoiceMessagesForbidden bool
ReadDatesPrivate bool
}