prepare(" INSERT INTO driver_streaks (driver_id, current_streak, zero_commission_until) VALUES (?, 0, NULL) ON DUPLICATE KEY UPDATE current_streak = 0 "); $stmt->execute([$driver_id]); } elseif ($action === 'increment') { $stmt = $con->prepare("SELECT current_streak FROM driver_streaks WHERE driver_id = ?"); $stmt->execute([$driver_id]); $row = $stmt->fetch(PDO::FETCH_ASSOC); $current = $row ? intval($row['current_streak']) + 1 : 1; $zero_until = NULL; if ($current >= 5) { // Reward unlocked! 0% commission until end of today $zero_until = date('Y-m-d 23:59:59'); $current = 0; // reset for next streak } $stmt2 = $con->prepare(" INSERT INTO driver_streaks (driver_id, current_streak, best_streak, zero_commission_until) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE current_streak = ?, best_streak = GREATEST(best_streak, ?), zero_commission_until = COALESCE(?, zero_commission_until) "); $stmt2->execute([ $driver_id, $current, $current, $zero_until, $current, $current, $zero_until ]); } // 🆕 Invalidate Redis Cache (Cache-Aside pattern) global $redis; if (isset($redis)) { try { $redis->del("driver_streak:{$driver_id}"); $redis->del("gamification_dashboard:{$driver_id}"); } catch (Exception $e) { error_log("[streak_helper] Redis Cache Invalidation Error: " . $e->getMessage()); } } } catch (Exception $e) { error_log("[streak_helper] Error: " . $e->getMessage()); } } function hasZeroCommission($con, $driver_id) { try { $stmt = $con->prepare("SELECT zero_commission_until FROM driver_streaks WHERE driver_id = ?"); $stmt->execute([$driver_id]); $row = $stmt->fetch(PDO::FETCH_ASSOC); if ($row && !empty($row['zero_commission_until'])) { return (strtotime($row['zero_commission_until']) > time()); } } catch (Exception $e) { error_log("[streak_helper] Error checking commission: " . $e->getMessage()); } return false; } ?>