From 1d9a1e14ca74a472a46d187f6884d161d3addb23 Mon Sep 17 00:00:00 2001 From: "seer-by-sentry[bot]" <157164994+seer-by-sentry[bot]@users.noreply.github.com> Date: Fri, 21 Nov 2025 18:52:23 +0000 Subject: [PATCH] feat: Optimize potato calculations and notifications --- src/Event/MessageEvent.php | 4 ++++ src/Model/Entity/User.php | 34 +++++++++++++++-------------- src/Service/NotificationService.php | 7 ++++-- 3 files changed, 27 insertions(+), 18 deletions(-) diff --git a/src/Event/MessageEvent.php b/src/Event/MessageEvent.php index 25e0122d..cf58db8e 100644 --- a/src/Event/MessageEvent.php +++ b/src/Event/MessageEvent.php @@ -78,6 +78,9 @@ public function process(): void return; } + // Capture potato left after validation to avoid re-querying in notification + $potatoLeftAfterValidation = $fromUser->potatoLeftToday(); + $toUsers = []; foreach ($this->receivers as $receiver) { $toUser = $userService->getOrCreateUser($receiver); @@ -94,6 +97,7 @@ public function process(): void fromUser: $fromUser, toUsers: $toUsers, event: $this, + potatoLeftToday: $potatoLeftAfterValidation, ); $stored = $quickWinService->store( diff --git a/src/Model/Entity/User.php b/src/Model/Entity/User.php index e996e99b..4af9fc1d 100644 --- a/src/Model/Entity/User.php +++ b/src/Model/Entity/User.php @@ -40,6 +40,13 @@ class User extends Entity '*' => false, ]; + /** + * Cache for potatoSentToday() to avoid duplicate queries + * + * @var int|null + */ + protected ?int $_potatoSentTodayCache = null; + public const STATUS_ACTIVE = 'active'; public const STATUS_DELETED = 'deleted'; @@ -121,6 +128,11 @@ public function potatoReceived(): int */ public function potatoSentToday(): int { + // Return cached value if already computed + if ($this->_potatoSentTodayCache !== null) { + return $this->_potatoSentTodayCache; + } + $messagesTable = $this->fetchTable('Messages'); $query = $messagesTable->find(); @@ -135,7 +147,10 @@ public function potatoSentToday(): int ]) ->first(); - return (int)$result->sent; + // Cache the result for subsequent calls + $this->_potatoSentTodayCache = (int)$result->sent; + + return $this->_potatoSentTodayCache; } /** @@ -165,21 +180,8 @@ public function potatoReceivedToday(): int */ public function potatoLeftToday(): int { - $messagesTable = $this->fetchTable('Messages'); - - $query = $messagesTable->find(); - $result = $query - ->select([ - 'sent' => $query->func()->sum('amount'), - ]) - ->where([ - 'sender_user_id' => $this->id, - 'type' => Message::TYPE_POTATO, - 'created >=' => $this->getStartOfDay(), - ]) - ->first(); - - return Message::MAX_AMOUNT - (int)$result->sent; + // Reuse the cached result from potatoSentToday() to avoid duplicate query + return Message::MAX_AMOUNT - $this->potatoSentToday(); } /** diff --git a/src/Service/NotificationService.php b/src/Service/NotificationService.php index 38663943..919dbb4f 100644 --- a/src/Service/NotificationService.php +++ b/src/Service/NotificationService.php @@ -29,12 +29,14 @@ public function __construct() * @param \App\Model\Entity\User $fromUser User who did gib the potato * @param array<\App\Model\Entity\User> $toUsers Users who will receive the potato * @param \App\Event\MessageEvent|\App\Event\ReactionAddedEvent $event The event. + * @param int|null $potatoLeftToday Optional pre-computed potato left today to avoid re-querying * @return void */ public function notifyUsers( User $fromUser, array $toUsers, MessageEvent|ReactionAddedEvent $event, + ?int $potatoLeftToday = null, ): void { $toUserNames = []; foreach ($toUsers as $toUser) { @@ -58,7 +60,8 @@ public function notifyUsers( } if ($fromUser->notifications['sent'] === true) { - $potatoLeftToday = $fromUser->potatoLeftToday(); + // Use pre-computed value if provided, otherwise query + $potatoLeft = $potatoLeftToday ?? $fromUser->potatoLeftToday(); $gibMessage = sprintf( 'You did gib *%s* %s to %s.', @@ -69,7 +72,7 @@ public function notifyUsers( $gibMessage .= PHP_EOL; $gibMessage .= sprintf( 'You have *%s* :potato: left. Your potato do reset in *%s hours* and *%s minutes*.', - $potatoLeftToday, + $potatoLeft, $fromUser->potatoResetInHours(), $fromUser->potatoResetInMinutes(), );