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

@ -17,6 +17,12 @@ export function currentRoute(): RouteState {
}
export function routeTitle(pathname: string, t: TFunction): string {
// Third-party verification is tested before the official section and before
// "/bots": three different prefixes that all read as "verification of a bot".
if (pathname.startsWith("/bot-verification")) return t("route.botVerification");
if (pathname.startsWith("/verification")) return t("route.verification");
if (pathname.startsWith("/collectible-usernames")) return t("route.collectibleUsernames");
if (pathname.startsWith("/account-ratings")) return t("route.accountRatings");
if (pathname.startsWith("/accounts")) return t("route.accounts");
if (pathname.startsWith("/channels")) return t("route.channels");
if (pathname.startsWith("/bots")) return t("route.bots");
@ -29,6 +35,10 @@ export function routeTitle(pathname: string, t: TFunction): string {
}
export function routeSubtitle(pathname: string, t: TFunction): string {
if (pathname.startsWith("/bot-verification")) return t("route.botVerificationSubtitle");
if (pathname.startsWith("/verification")) return t("route.verificationSubtitle");
if (pathname.startsWith("/collectible-usernames")) return t("route.collectibleUsernamesSubtitle");
if (pathname.startsWith("/account-ratings")) return t("route.accountRatingsSubtitle");
if (pathname.startsWith("/accounts")) return t("route.accountsSubtitle");
if (pathname.startsWith("/channels")) return t("route.channelsSubtitle");
if (pathname.startsWith("/bots")) return t("route.botsSubtitle");