feat: add NFT usernames and bot verification (#22)

Implements collectible usernames, official verification workflows, and third-party bot verification after maintainer protocol and migration review.

The composite activity/moderation rating remains an admin-only read model; Telegram Stars Rating wire fields stay unset pending a dedicated official-semantics implementation.

Reviewed-Head: 2796345775ea0f908fb7734601e5e1dee4b653b9
Original-Head: fa082b892fd5180c9c9bc53c81c21cf5d250a75b

Co-authored-by: Egor Egorov <business.egor.sg@gmail.com>
This commit is contained in:
Egor Egorov 2026-07-27 20:18:00 +03:00 committed by GitHub
parent b0fd3976f1
commit fff8de783a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
169 changed files with 55769 additions and 282 deletions

View file

@ -567,6 +567,11 @@ func (r *Router) withUserSearchPresence(res domain.UserSearchResult) domain.User
return res
}
// tgUser / tgSelfUser deliberately do NOT overlay the username registry or the
// bot verification icon: they are called inside per-id loops (users.getUsers), and a
// per-object read there would be exactly the N+1 the batch overlay exists to avoid.
// Single-object handlers pick both up from applyPeerReadModels at the response
// boundary.
func (r *Router) tgUser(u domain.User) *tg.User {
return r.withBotProfileFlags(context.Background(), tgUser(r.withUserPresence(u)))
}
@ -578,6 +583,8 @@ func (r *Router) tgSelfUser(u domain.User) *tg.User {
func (r *Router) tgUsers(users []domain.User) []tg.UserClass {
out := tgUsers(r.withUsersPresence(users))
r.withBotProfileFlagsForUsers(context.Background(), out)
r.applyUsernamesToPeerObjects(context.Background(), out, nil)
r.applyBotVerificationIconsToPeerObjects(context.Background(), out, nil)
return out
}
@ -586,6 +593,8 @@ func (r *Router) tgUsers(users []domain.User) []tg.UserClass {
func (r *Router) tgUsersForViewer(viewerUserID int64, users []domain.User) []tg.UserClass {
out := tgUsersForViewer(viewerUserID, r.withUsersPresence(users))
r.withBotProfileFlagsForUsers(context.Background(), out)
r.applyUsernamesToPeerObjects(context.Background(), out, nil)
r.applyBotVerificationIconsToPeerObjects(context.Background(), out, nil)
return out
}