Appearance
Epic 45 — Profile Badge System (Beta User, Bounty Hero)
New. Decision (user, 2026-06-16): A badge system on user profiles. First badges: Beta User and Bounty Hero (more than 10 bounties claimed). (The Beta User badge is awarded by the Beta flag — Epic 46.)
✅ SHIPPED 2026-06-18. Backend
src/services/badges/index.ts—BADGESregistry (BETA_USERSTATIC /BOUNTY_HEROCOMPUTED = strictly >10HIREDBountyClaim), pureresolveBadges(staticKeys, {hiredBountyClaimCount})+ asyncbadgesForUser. GraphQLBadge { key label icon description }+badges: [Badge!]!on PublicUser / TalentProfile / ProducerProfile (field resolvers inresolvers/social.ts;PublicUsercarries internalbadgeKeysfromtoPublicUserso only the computed-count query runs). RootUser.badges: [String!]!(raw keys, self/admin) retained. Frontend DSProfileBadges(phosphor icon + nativetitletooltip, accent per key, renders null when empty) next to the Verified pin on Talent/Producer profile pages +PostCard/SuggestionCard/TalentCard;apps/app/src/lib/badges.tslocalizeBadges(i18n by key via shared instance,badges.*keys in en/pt/es, English API fallback); queries extended (PUBLIC_USER_FIELDS, feed author, talent/producer fragments, POST_QUERY). BE 1414 (+10) / FE app 564 / DS 44 (+5 ProfileBadges) tests green; typecheck + i18n-key lint clean. Note: list surfaces that selectbadges(followers/following/suggestions/search) now issue onebountyClaim.countper row — acceptable at beta scale; batch later if needed.
Why: User.badges String[] exists ("e.g. EARLY_ADOPTER from CasTars Bounty") but is never rendered, and the only profile chip today is the computed Verified pin (verifiedAt → verified). This epic adds a small, extensible badge registry + a display component, with the first two badges.
Architecture: A server-side BADGES registry (key, label, icon, description, kind: STATIC|COMPUTED). Static badges (e.g. BETA_USER) live in User.badges. Computed badges (e.g. BOUNTY_HERO) are derived in a badges field resolver on PublicUser (no storage). Render alongside the existing Verified pin. Decision (user, 2026-06-16): "Bounty Hero" = more than 10 BountyClaim rows with status HIRED (earned/successful claims, not merely submitted).
BE-BADGE-001 — Badge registry + PublicUser.badges resolver
Files:
- Create:
castyou-backend/src/services/badges/index.ts—BADGESregistry +resolveBadges(user)merging staticUser.badgeswith computed ones (BOUNTY_HEROwhen the user's HIREDBountyClaimcount > 10). - Edit:
castyou-backend/src/graphql/schema/index.ts+src/services/social/index.ts— exposebadges: [Badge!]!onPublicUser/profile types (Badge { key, label, icon, description }).
Acceptance criteria: A user with BETA_USER in User.badges and >10 HIRED claims returns both badges; others return none.
FE-BADGE-001 — Badge display component
Files:
- Create:
@castyou/design-systemProfileBadges(icon + tooltip) ([[Design System Rule]]); render on profile pages, profile cards, and feed author chips next to Verified. - Edit: i18n en/pt/es for badge labels/descriptions.
Acceptance criteria: Badges render with label/tooltip on profiles + cards in all 3 locales; sourced from the design system.
TEST-BADGE-001 — Badge coverage
Acceptance criteria: Registry resolution (static + computed Bounty Hero threshold) and the display component are tested.