perf: double API calls in trade views (validate_trade and _get_user_team) #94

Closed
opened 2026-03-20 13:17:50 +00:00 by cal · 1 comment
Owner

Problem

Two methods in views/trade_embed.py make redundant API calls per user interaction.

create_trade_embedvalidate_trade() called twice (lines 714, 769)

First call at line 714 determines embed color, second call at line 769 gets status text. Each validate_trade() hits roster API + transactions API per participant. On every button interaction (Remove Move, Cancel, navigation), this doubles the API cost.

TradeAcceptanceView_get_user_team() called twice per button click

  • interaction_check (line 341) calls it to verify the user is a participant — discards the team object
  • Button callbacks (accept_button line 369, reject_button line 404) call it again to get the team for processing

Fix

validate_trade

Call once, store the result:

validation_result = await builder.validate_trade()
# Use validation_result for both color and status text

_get_user_team

Store the team on the view instance after interaction_check succeeds:

async def interaction_check(self, interaction):
    team = await self._get_user_team(interaction)
    if team is None:
        return False
    self._checked_team = team
    return True

Impact

MEDIUM — Trade builder is interactive with multiple button clicks. Each click currently makes 2x the necessary API calls.

## Problem Two methods in `views/trade_embed.py` make redundant API calls per user interaction. ### `create_trade_embed` — `validate_trade()` called twice (lines 714, 769) First call at line 714 determines embed color, second call at line 769 gets status text. Each `validate_trade()` hits roster API + transactions API per participant. On every button interaction (Remove Move, Cancel, navigation), this doubles the API cost. ### `TradeAcceptanceView` — `_get_user_team()` called twice per button click - `interaction_check` (line 341) calls it to verify the user is a participant — discards the team object - Button callbacks (`accept_button` line 369, `reject_button` line 404) call it again to get the team for processing ## Fix ### validate_trade Call once, store the result: ```python validation_result = await builder.validate_trade() # Use validation_result for both color and status text ``` ### _get_user_team Store the team on the view instance after `interaction_check` succeeds: ```python async def interaction_check(self, interaction): team = await self._get_user_team(interaction) if team is None: return False self._checked_team = team return True ``` ## Impact **MEDIUM** — Trade builder is interactive with multiple button clicks. Each click currently makes 2x the necessary API calls.
cal added the
ai-working
label 2026-03-20 13:18:39 +00:00
cal removed the
ai-working
label 2026-03-20 13:21:33 +00:00
Claude added the
ai-working
label 2026-03-20 18:31:10 +00:00
Claude added the
status/pr-open
label 2026-03-20 18:33:40 +00:00
Collaborator

PR opened: #116

Fix 1create_trade_embed: moved the single validate_trade() call before the if builder.is_empty block; both color selection and status text now share the result, eliminating the second call.

Fix 2TradeAcceptanceView: interaction_check stores the resolved team in self._checked_team after validating the user is a participant; accept_button and reject_button read from self._checked_team instead of calling _get_user_team() again.

PR opened: https://git.manticorum.com/cal/major-domo-v2/pulls/116 **Fix 1** — `create_trade_embed`: moved the single `validate_trade()` call before the `if builder.is_empty` block; both color selection and status text now share the result, eliminating the second call. **Fix 2** — `TradeAcceptanceView`: `interaction_check` stores the resolved team in `self._checked_team` after validating the user is a participant; `accept_button` and `reject_button` read from `self._checked_team` instead of calling `_get_user_team()` again.
Claude added
ai-pr-opened
and removed
ai-working
labels 2026-03-20 18:33:47 +00:00
cal closed this issue 2026-03-31 19:54:19 +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/major-domo-v2#94
No description provided.