sidequest_common.schemas.badges =============================== .. py:module:: sidequest_common.schemas.badges .. autoapi-nested-parse:: Hall of Heroes badge definitions and earned-badge schemas. Badges are defined in code, not configured on the site: ``BADGES`` is the single source of truth for every badge's id, display name, description, icon, and the color its Discord role gets. The bot creates one Discord role per badge (stored in ``GuildConfigSchema.badge_role_ids``) and keeps membership in sync with ``MemberBadge`` rows the API computes. Adjust thresholds here; nothing else needs to change. Attributes ---------- .. autoapisummary:: sidequest_common.schemas.badges.BADGES sidequest_common.schemas.badges.BADGE_LIST sidequest_common.schemas.badges.CHATTERBOX_LEVEL sidequest_common.schemas.badges.FOUNDING_MEMBER_CUTOFF_ISO sidequest_common.schemas.badges.PERFECT_MONTH_MIN_RAIDS sidequest_common.schemas.badges.RAID_REGULAR_THRESHOLD sidequest_common.schemas.badges.RAID_VETERAN_THRESHOLD Classes ------- .. autoapisummary:: sidequest_common.schemas.badges.BadgeAck sidequest_common.schemas.badges.BadgeDefinition sidequest_common.schemas.badges.BadgeRoleState sidequest_common.schemas.badges.BadgeSyncReport sidequest_common.schemas.badges.EarnedBadge sidequest_common.schemas.badges.PendingBadgeAnnouncement Module Contents --------------- .. py:class:: BadgeAck Bases: :py:obj:`pydantic.BaseModel` Body for ``POST /api/guilds/{id}/badges/ack``: badges whose announcement has posted. .. py:attribute:: badge_id :type: str .. py:attribute:: discord_id :type: int .. py:class:: BadgeDefinition Bases: :py:obj:`pydantic.BaseModel` One badge's fixed metadata. ``color`` is a Discord role color (0xRRGGBB). .. py:attribute:: color :type: int .. py:attribute:: description :type: str .. py:attribute:: icon :type: str .. py:attribute:: id :type: str .. py:attribute:: name :type: str .. py:class:: BadgeRoleState Bases: :py:obj:`pydantic.BaseModel` One member's current badge ids, for the bot's role sync (``GET /api/guilds/{id}/badges/state``). .. py:attribute:: badge_ids :type: list[str] .. py:attribute:: discord_id :type: int .. py:class:: BadgeSyncReport Bases: :py:obj:`pydantic.BaseModel` ``GET /api/guilds/{id}/badges/sync``: recomputes every member's badges, then reports the result. ``role_state`` is every linked member's full current badge set (the bot diffs this against actual role membership). ``pending`` is newly earned badges not yet announced; the bot posts them, then calls ``POST /api/guilds/{id}/badges/ack`` to mark them announced. .. py:attribute:: pending :type: list[PendingBadgeAnnouncement] .. py:attribute:: role_state :type: list[BadgeRoleState] .. py:class:: EarnedBadge Bases: :py:obj:`pydantic.BaseModel` One badge a member has earned, for the profile's badge case. .. py:attribute:: description :type: str .. py:attribute:: earned_at :type: datetime.datetime .. py:attribute:: icon :type: str .. py:attribute:: id :type: str .. py:attribute:: model_config .. py:attribute:: name :type: str .. py:class:: PendingBadgeAnnouncement Bases: :py:obj:`pydantic.BaseModel` A newly earned badge not yet announced in Discord. .. py:attribute:: badge_id :type: str .. py:attribute:: description :type: str .. py:attribute:: discord_id :type: int .. py:attribute:: name :type: str .. py:data:: BADGES :type: dict[str, BadgeDefinition] .. py:data:: BADGE_LIST :type: tuple[BadgeDefinition, Ellipsis] .. py:data:: CHATTERBOX_LEVEL :value: 10 .. py:data:: FOUNDING_MEMBER_CUTOFF_ISO :value: '2026-11-04T00:00:00+00:00' Members confirmed on the roster before this instant (the launch date, UTC midnight) earn Founding Member. .. py:data:: PERFECT_MONTH_MIN_RAIDS :value: 4 .. py:data:: RAID_REGULAR_THRESHOLD :value: 10 .. py:data:: RAID_VETERAN_THRESHOLD :value: 25