feat: tier-up notification should include refractor card image #144

Closed
opened 2026-04-08 00:19:25 +00:00 by cal · 1 comment
Owner

Problem

build_tier_up_embed() in helpers/refractor_notifs.py sends a text-only embed with title, description, and footer. No card image, no team branding, no visual payoff.

The tier-up moment is the peak emotional payoff of the entire refractor progression loop. A text-only notification undersells it dramatically compared to the full card art visible via /player refractor_tier:N.

Fix

The evaluate-game API response already includes variant_created and player_id. The notification builder should:

  1. Fetch or construct the rendered card image URL (from the render endpoint or S3 image_url)
  2. Include it as the embed image via set_image()
  3. Include team name/logo for context

Impact

High UX value, low-medium effort. This is the single most important engagement touchpoint in the refractor loop.

## Problem `build_tier_up_embed()` in `helpers/refractor_notifs.py` sends a text-only embed with title, description, and footer. No card image, no team branding, no visual payoff. The tier-up moment is the peak emotional payoff of the entire refractor progression loop. A text-only notification undersells it dramatically compared to the full card art visible via `/player refractor_tier:N`. ## Fix The `evaluate-game` API response already includes `variant_created` and `player_id`. The notification builder should: 1. Fetch or construct the rendered card image URL (from the render endpoint or S3 `image_url`) 2. Include it as the embed image via `set_image()` 3. Include team name/logo for context ## Impact High UX value, low-medium effort. This is the single most important engagement touchpoint in the refractor loop.
Claude added the
ai-working
label 2026-04-08 14:31:15 +00:00
Collaborator

Implemented in PR #159.

Approach: _trigger_variant_renders() now returns a player_id → image_url dict from the render endpoint responses. _run_post_game_refractor_hook() runs renders first, then passes each player's image_url to notify_tier_completion(), which passes it to build_tier_up_embed() via set_image().

Ordering change: renders now happen before notifications (previously the reverse) so the card art is available when the Discord embed fires. If the render fails or returns no image_url, the notification sends without an image (graceful degradation).

Team logo: not added — the tier_up dict from evaluate-game doesn't include team data. Would need the API to return team info in tier_up objects.

Implemented in PR #159. **Approach**: `_trigger_variant_renders()` now returns a `player_id → image_url` dict from the render endpoint responses. `_run_post_game_refractor_hook()` runs renders first, then passes each player's `image_url` to `notify_tier_completion()`, which passes it to `build_tier_up_embed()` via `set_image()`. **Ordering change**: renders now happen before notifications (previously the reverse) so the card art is available when the Discord embed fires. If the render fails or returns no `image_url`, the notification sends without an image (graceful degradation). **Team logo**: not added — the `tier_up` dict from `evaluate-game` doesn't include team data. Would need the API to return team info in tier_up objects.
Claude added
ai-pr-opened
and removed
ai-working
labels 2026-04-08 14:39:18 +00:00
cal closed this issue 2026-04-08 15:25:52 +00:00
Sign in to join this conversation.
No Milestone
No project
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: cal/paper-dynasty-discord#144
No description provided.